CSS 中的 Flex(彈性佈局)
能夠很靈活的控制網頁的佈局,其中決定 Flex
佈局內項目寬度/高度的是三個屬性:
flex-basis
, flex-grow
, flex-shrink
.html
flex-basis 決定了項目佔據主軸的空間,除非使用 box-sizing
進行設置,不然它將設置內容框的大小,所以當你指定一個flex項的大小時須要額外當心,由於它很肯能包含內邊距與邊框。git
你能夠爲其指定一個具體的CSS尺寸值,也能夠指定其佔據父元素的百分比,它的默認值爲 auto
(根據內容自動調整大小)github
<!-- demo-1 --> <div class="parent"> <div class="child1">100px</div> <div class="child2">200px</div> </div> <div class="parent"> <div class="child1">10%</div> <div class="child2">20%</div> </div> <div class="parent"> <div class="child1">30%</div> <div class="child2">auto</div> </div> <style> .parent { width: 500px; display: flex; margin-bottom: 15px; text-align: center; background-color: #eeeeee; } /** 像素值*/ .parent:nth-child(1) .child1 { flex-basis: 100px; background-color: #356969 } .parent:nth-child(1) .child2 { flex-basis: 200px; background-color: #369925; } /** 百分比 */ .parent:nth-child(2) .child1 { flex-basis: 10%; background-color: #356969 } .parent:nth-child(2) .child2 { flex-basis: 20%; background-color: #369925; } /** 自動 */ .parent:nth-child(3) .child1 { flex-basis: 30%; background-color: #356969 } .parent:nth-child(3) .child2 { flex-basis: auto; background-color: #369925; } </style>
flex-grow 設置當 flex 容器存在剩餘空間(flex容器的大小減去全部flex項的大小之和)時項目的放大比例,它的默認值爲 0 (即便存在剩餘空間也不放大)。若是全部項目的 flex-grow 屬性值都是相同的,則它們將等分剩餘空間,不然,將根據不一樣的屬性值所定義的比率進行分配。佈局
例如,主軸長度爲600px, 項目1佔據50px, 項目2佔據100px, 項目3佔據150px, 則剩餘空間爲:600px - (50px + 100px + 150px) = 300pxflex
假如每一個項目的 flex-grow
屬性值都相同(例如都爲1),則全部項目分配到相同的剩餘空間:
- 項目1: 300px * (1 / (1 + 1 + 1)) = 100px;
- 項目2: 300px * (1 / (1 + 1 + 1)) = 100px;
- 項目3: 300px * (1 / (1 + 1 + 1)) = 100px;code
<!-- demo-2 --> <div class="parent"> <div class="child1">50px + 100px</div> <div class="child2">100px + 100px</div> <div class="child3">150px + 100px</div> </div> <style> .parent { width: 600px; display: flex; text-align: center; color: #eee; } .child1 { flex-basis: 50px; flex-grow: 1; background-color: #0066CC; } .child2 { flex-basis: 100px; flex-grow: 1; background-color: #009900; } .child3 { flex-basis: 150px; flex-grow: 1; background-color: #CC3300; } </style>
假設每一個項目的 flex-grow 屬性的值並不都是相同的,例如項目1爲 1, 項目2爲 2, 項目3爲 3, 則它們分配到的剩餘空間分別爲:
- 項目1: 300px * (1 / (1 + 2 + 3)) = 50px;
- 項目2: 300px * (2 / (1 + 2 + 3)) = 100px;
- 項目3: 300px * (3 / (1 + 2 + 3)) = 150px;htm
<!-- demo-3 --> <div class="parent"> <div class="child1">50px + 50px</div> <div class="child2">100px + 100px</div> <div class="child3">150px + 150px</div> </div> <style> .parent { width: 600px; display: flex; text-align: center; color: #eee; } .child1 { flex-basis: 50px; flex-grow: 1; background-color: #0066CC; } .child2 { flex-basis: 100px; flex-grow: 2; background-color: #009900; } .child3 { flex-basis: 150px; flex-grow: 3; background-color: #CC3300; } </style>
要是屬性值爲小數怎麼辦呢?這裏分兩種狀況:
1. 全部flex項的 flex-gorw 屬性值之和大於1,仍然按照上述方式進行計算;
2. 全部flex項的 flex-gorw 屬性值之和小於1,基值按照1來進行計算,例如項目1爲 0.2, 項目2爲 0.3, 項目3爲 0.4, 則它們分配到的剩餘空間分別爲:
- 項目1: 300px * (0.2 / 1) = 60px;
- 項目2: 300px * (0.3 / 1) = 90px;
- 項目3: 300px * (0.4 / 1) = 120px;blog
<!-- demo-4 --> <div class="parent"> <div class="child1">50px + 60px</div> <div class="child2">100px + 90px</div> <div class="child3">150px + 120px</div> </div> <style> .parent { width: 600px; display: flex; text-align: center; color: #eee; } .child1 { flex-basis: 50px; flex-grow: 0.2; background-color: #0066CC; } .child2 { flex-basis: 100px; flex-grow: 0.3; background-color: #009900; } .child3 { flex-basis: 150px; flex-grow: 0.4; background-color: #CC3300; }
flex-shrink 設置當 flex 容器空間不足時項目的放大比例,它的默認值爲 1 (空間不足時該項目將縮小)。文檔
flex-shrink 的計算方式與 flex-grow 略有不一樣,有兩個因素影響 flex 項該縮小多少,一個是 flex-shrink 的屬性值,另外一個是 flex 項自己的大小,它們按各自的權重進行縮小,舉例來講:get
主軸長度爲600px, 項目1佔據100px, 項目2佔據300px, 項目3佔據500px, 每一個項目的 flex-shrink
屬性值分別爲1,3,2, 則總權重爲 100px * 1 + 300px * 3 + 500px 2 = 2000px, 每一個項目的權重分別爲爲:
- 項目1: (100px 1) / 2000px = 0.05;
- 項目2: (300px * 3) / 2000px = 0.45;
- 項目3: (500px * 2) / 2000px = 0.50;
溢出的空間長度爲:100px + 300px + 500px - 600px = 300px;
那麼每一個項目分別縮小:
- 項目1: 300px * 0.05 = 15px;
- 項目2: 300px * 0.45 = 135px;
- 項目3: 300px * 0.50 = 150px;
<!-- demo-5 --> <div class="parent"> <div class="child1">100px - 15px</div> <div class="child2">300px - 135px</div> <div class="child3">500px - 150px</div> </div> <style> .parent { width: 600px; display: flex; text-align: center; color: #eee; } .child1 { flex-basis: 100px; flex-shrink: 1; background-color: #0066CC; } .child2 { flex-basis: 300px; flex-shrink: 3; background-color: #009900; } .child3 { flex-basis: 500px; flex-shrink: 2; background-color: #CC3300; } </style>
一樣的,當 flex-shrink 的值爲小數時,也分兩種狀況:
1. 全部flex項的 flex-shrink 屬性值之和大於1,仍然按照上述方式進行計算;
2. 全部flex項的 flex-shrink 屬性值之和小於1,只收縮溢出空間的一部分,例如項目1爲 0.1, 項目2爲 0.3, 項目3爲 0.2, 則總的收縮空間爲:
300px * (0.1 + 0.3 + 0.2) = 180px
每一個項的權重計算方式是不變的,每一個項目分別縮小:
- 項目1: 180px * 0.05 = 9px;
- 項目2: 180px * 0.45 = 81px;
- 項目3: 180px * 0.50 = 90px;
<!-- demo-6 --> <div class="parent"> <div class="child1">100px - 9px</div> <div class="child2">300px - 135px</div> <div class="child3">500px - 90px</div> </div> <style> .parent { width: 600px; display: flex; text-align: center; color: #eee; } .child1 { flex-basis: 100px; flex-shrink: 0.1; background-color: #0066CC; } .child2 { flex-basis: 300px; flex-shrink: 0.3; background-color: #009900; } .child3 { flex-basis: 500px; flex-shrink: 0.2; background-color: #CC3300; } </style>
因爲只收縮了溢出空間的一部分,div 內的元素總寬度其實是超出 div 的寬度的。
以上就是關於使用flex佈局中 flex-grow 與 flex-shrink 計算方式的簡單介紹。
該篇博客內的代碼已同步到Github
參考資料:
[1]. MDN文檔 https://developer.mozilla.org/zh-CN/docs/Web/CSS/flex-basis
[2]. MDN文檔 https://developer.mozilla.org/zh-CN/docs/Web/CSS/flex-grow
[3]. MDN文檔 https://developer.mozilla.org/zh-CN/docs/Web/CSS/flex-shrink