我是路程lucky,6年web前端開發經驗,目前參與的項目技術棧主要是React,歡迎關注~
今天給大家分享一下解決一個遇到的樣式布局問題經歷,「標籤寬度自適應,間距固定,每行指定個數」,看似簡單,但新手朋友如果不注意很容易踩坑,下面我們就來逐步分析解決這個css布局小問題。
場景描述
工作中遇到這樣一個需求場景:由於視覺設計師的視覺審美要求下,h5頁面中,查詢的商品列表每行有多個標籤標籤個數不固定,寬度自適應,左右間距固定。整體左右間距30px,標籤之間間距6px,頁面整體寬度640px(不同機型不同寬度)。
註:當前h5腳手架開發採用的scss,已集成了px2rem也就是像素轉rem,編寫px即可實現不同寬度的自適應。

初步思考
通常,由於移動端布局有一定兼容性等問題,一些特定的布局如display:grid等,我們還是謹慎使用。我們想到的第一想法是flex布局,可以使得寬度自適應,閃現的思路是:
- 父元素設置為display:flex,自動換行
- 子元素設置間距:距離上下左右,然後寬度就自適應,然後就好了?
// scss
// 父元素
.parent {
display:flex;
flex-wrap:wrap;
margin-left: 10px;
margin-right: 30px;
}
// 大致的想法
.child {
flex: 1;
margin: 10px 6px;
width: auto; // ?這個寬度如何處理
}
對於
justify-content:space-between,期初也想使用這種,但需求要間距固定,無法適用。
問題來了
現實是殘酷的,你會發現子元素全部在一排,沒有寬度,也發現這裡的最大難點就是如何確定標籤寬度
- 如何實現一行三個
- 每行的三個標籤第二個標籤和第三個標籤之間有間距,而第一個和左邊相對頁面左右邊是沒有間距的。
嘗試解決
我們知道問題中使用flex布局的核心問題是要有最小寬度,沒有寬度就不會撐開。css3的calc在移動h5中的兼容性還是不錯的,我們可以動態計算寬度。根據每行顯示3個,間距固定,那麼我們可以得出以下計算公式:
子元素標籤寬度 = ( 頁面總寬度100% – 頁面左右寬度30px * 2 – 標籤左右邊框2px * 3 – 邊框左右間距6px * 2 ) / 3;
化簡:
子元素標籤寬度 = 100% / 3 – 30px * 2 / 3 – 2px * 3 / 3 – 6px * 2 / 3
= 100% / 3 – 26px
// 子元素寬度
.child {
width: calc(100% / 3 – 26px);
}
還是有問題,1行只能展示2個
這樣布局,還是發現出現問題,雖然我們按照思路進行布局,但我們忽略了一個重點:標籤的左右間距規律是:第1、4、7等最左側第一個,也就是3n+1距離左側是空的。第一時間,你會想通過偽類 nth-chilld(3n+1)來實現標籤。但如果真這樣做,這裡對於h5頁面來說,
- 誤差大,這種間距稍不留神就會出現溢出換行
- 維護成本高,其他小夥伴維護需要注意這個偽類控制
我們換一種思路來考慮。其實這類場景PC端是很常見的,我們可以聯動父元素來解決。
思路:
- 父元素寬度設置為100%加上一個間距的距離
- 父元素距離左側減少一個間距的距離
優點:
- 間距可以抽出為變數,方便維護
- 誤差小
最終方案
父元素flex布局,距離左側為指定寬度,子元素寬度應該為正常的三個相同寬度和間距元素。
子元素標籤寬度 = ( 頁面總寬度100% – 頁面左右寬度30px * 2 – 標籤左右邊框2px * 3 – 邊框左右間距6px * 3 ) / 3;
化簡:
子元素標籤寬度 = 100% / 3 – 30px * 2 / 3 – 2px * 3 / 3 – 6px * 3 / 3
= 100% / 3 – 28px
// scss
$width: 6px;
// 父元素
.parent {
display:flex;
flex-wrap:wrap;
margin-left: (30px – $width);
margin-right: 30px;
width: calc(100% + $width);
}
// 大致的想法
.child {
flex: 1;
margin: 10px $width;
width: calc(100% / 3 – 30px * 2 / 3 – 2px * 3 / 3 – $width * 3 / 3)
// width: calc(100% / 3 – 28px);
}
總結
看似一個很容易很常見標籤寬度自適應的布局樣式問題,卻引發了坑,各種思考,當然方案遠不止這一種。我們可以通過實踐經驗總結出以下幾點:
- 寬度自適應問題可以通過動態計算(當前主流瀏覽器基本都支持)
- 子節點的寬度問題可以去思考父元素是不是能夠做一些改變實現
- 多思考,大膽實踐,方法總比困難多,這樣你才會摸索出更多的方法。
web前端開發崗位,一定要能夠腦洞靈活,各種角度各種方法思考。我們才能遊刃有餘。謝謝大家。
我是路程lucky,6年web前端開發經驗,目前參與的項目技術棧主要是React,歡迎關注~
原創文章,作者:投稿專員,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/229595.html
微信掃一掃
支付寶掃一掃