一文搞懂Flex彈性布局空間分配規則
前情
早期css布局使用最多的就是浮動,后面出了Flex后,就基本拋棄了浮動的使用,基本每個項目起手就是FLex,特別是小程序端,官方就是主推的Flex布局,所以Flex布局在我平時開發中有的非常多,也是非常好用的布局方式,相比以前你得費一些周折的布局方式,現在都能輕輕松松實現,用的多但是有一些計算細節其實也是理解不是特別深的,flex布局中有一個flex復合屬性,用于控制彈性盒子子元素尺寸的,分開就是flex-basis+flex-grow+flex-shrink,最近在B站看到一個介紹Flex的視頻其中說詳細講到 了計算邏輯的內容,感覺干貨挺多,特此記錄
各屬性功能描述
flex-basis
定義了在分配多余空間之前,項目占據的主軸空間(main size)。瀏覽器根據這個屬性,計算主軸是否有多余空間。它的默認值為auto,即項目的本來大小,它可以設為跟width或height屬性一樣的值(比如200px),則項目將占據固定空間
.item {
flex-basis: <length> | auto; /* 默認值為auto */
}
flex-grow
定義項目的放大比例,默認為0,即如果存在剩余空間,也不放大;如果所有項目的flex-grow屬性都為1,則它們將等分剩余空間(如果有的話)。如果一個項目的flex-grow屬性為2,其他項目都為1,則前者占據的剩余空間將比其他項多一倍
.item {
flex-grow: <number>; /* 默認值為 0 */
}
flex-shrink
定義了項目的縮小比例,默認為1,即如果空間不足,該項目將縮小;如果所有項目的flex-shrink屬性都為1,當空間不足時,都將等比例縮小。如果一個項目的flex-shrink屬性為0,其他項目都為1,則空間不足時,前者不縮小,負值對該屬性無效
.item {
flex-shrink: <number>; /* 默認值為 1 */
}
Flex空間分配邏輯
Flex空間分配的三步法:
第一步計算所有子元素basis的總和
第二步比較容器寬度和總的basis寬度的
第三步計算容器寬度
總的basis小于容器寬度,應用flex-grow
總的basis大于容器寬度,應用flex-shrink
總的basis等于容器寬度,無需伸縮
整個流程圖如下:

計算公式如下圖:

計算實戰
當空間充足時,flex-grow生效,元素尺寸變大一起加大多余的空間
當前項的最終寬度 = basis + (容器寬度-總的basis) * 當前項的grow/總的grow,下面來看一個示例
關鍵代碼如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<div class="container">
<div class="a">a</div>
<div class="b">b</div>
<div class="c">c</div>
</div>
</body>
</html>
.container{
width:600px;
height: 168px;
display: flex;
flex-direction: row;
}
.a{
flex:1 1 0;
background-color: red;
}
.b{
flex:2 1 auto;
width: 200px;
background-color: green;
}
.c{
flex:3 1 100px;
background-color: blue;
}
演示地址:https://jsbin.com/fibecijohi/edit?html,css,output
計算解析:
Flex容器container下有三個子項分別為a,b,c
容器的寬度為600
總的basis = 0(a)+200(b)+100(s) = 300
總的grow = 1(a)+2(b)+3(c) = 6
a項的寬度= 0 + (600 - 300) * 1/6 = 50
b項的寬度= 200 + (600 - 300) * 2/6 = 300
c項的寬度= 100 + (600 - 300) *3/6 = 250

當空間不足時,flex-shrink生效,元素尺寸變小一起減小不足的空間
當前項的最終寬度 = basis - (總的basis - 容器寬度) * (當前項的basis * 當前項的sthrink)/(各元素的basic * 各元素的shrink之和),下面來看一個示例
代碼如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<div class="container">
<div class="a">a</div>
<div class="b">b</div>
<div class="c">c</div>
</div>
</body>
</html>
.container{
width:600px;
height: 168px;
display: flex;
flex-direction: row;
}
.a{
flex:1 1 200px;
background-color: red;
}
.b{
flex:1 3 auto;
width: 400px;
background-color: green;
}
.c{
flex:1 2 100px;
background-color: blue;
}
演示地址:https://jsbin.com/barihazasi/edit?html,css,js,output
計算解析:
Flex容器container下有三個子項分別為a,b,c
容器的寬度為600
總的basis = 200(a)+400(b)+100(s) = 700
a項的寬度= 200 - (700 - 600) * 1200/(1200 + 3400 + 2100) = 200 - 100 *200/1600 = 187.5
b項的寬度= 400 - (700 - 600) * 3400/(1200 + 3400 + 2100) = 400 - 100 * 1200/1600 = 325
c項的寬度= 100 - (700 - 600) * 2100/(1200 + 3400 + 2100) = 100 - 100 * 200/1600 = 87.5

總結
一直有在用Flex,也大概知道是按比例計算余下多的或少的空間,但并沒有深入研究,今天在B站看到詳細介紹計算邏輯的視頻真的茅塞頓開,計算邏輯總結如下:
- 一切始于flex-basis:它決定了是進入擴張模式還是收縮模式
- 空間充足時,分配空間:系統根據flex-grow的比例分配余下空間
- 空間不足時,壓縮空間:系統根據flex-basis和flex-shrink共同決定的權重分梭壓縮量
個人知識有限,如果你有更好的解析方法,希望不吝分享,一起學習一起進步

浙公網安備 33010602011771號