作者: Yeaseon
Blog:yeaseonzhang.github.io
原文連結
Flex 是 Flexible Box的縮寫,意為“彈性佈局”,可以簡便、完整、響應式地實現各種頁面佈局。
Flex的出現就是為了解決傳統佈局的display
屬性 + position
屬性 + float
屬性的複雜性。
瀏覽器對於Flex的支援性
可以看到瀏覽器對於Flex佈局的支援性已經很好了,所以我們可以放心大膽的用在我們專案中。
flex 屬性
flex: flex-grow | flex-shrink | flex-basis
flex屬性包含三個值:flex-grow
、flex-shrink
和flex-basis
flex-grow
: 擴充套件比例flex-shrink
: 收縮比例flex-basis
: 伸縮基準值
首先我們簡單寫一個flex佈局的Demo
HTML
<div class="parent">
<div class="child_1"></div>
<div class="child_2"></div>
<div class="child_3"></div>
</div>複製程式碼
CSS
.child_1,
.child_2,
.child_3 {
flex: 1;
height: 200px;
}
.child_1 {
background-color: rgba(255, 0, 0, .5);
}
.child_2 {
background-color: rgba(0, 255, 0, .5);
}
.child_3 {
background-color: rgba(0, 0, 255, .5);
}複製程式碼
See the Pen Flex-1 by YeaseonZhang (@YeaseonZhang) on CodePen.
設定父元素display: flex
,其子元素就能使用flex佈局,我們只是簡單的為子元素使用了flex: 1
就實現了三等分,而且會隨著父元素的寬度變化而變化。這就是我們平時flex佈局的簡單用法,即各個子元素按照比例佈局。
flex: 1
其實是flex: 1 1 0%
的簡寫屬性,即伸縮比例都是1。下面我們就分別理解下三個屬性值對於佈局的影響。
flex-basis 屬性
flex-basis
屬性是伸縮的基準值,這個屬性也是我們計算最終寬度的決定性因素。
通過子元素flex-basis
屬性和與父元素(容器)寬度值進行比較,會出現兩種情況(忽略相等的情況):
- 子元素
flex-basis
屬性和 < 父元素寬度 - 子元素
flex-basis
屬性和 > 父元素寬度
上面的兩種情況就分別對應了flex-grow
和flex-shrink
屬性生效的情況,也就是說當子元素的flex-basis
屬性寬度和小於父元素的寬度值時flex-grow
生效,反之flex-shrink
生效。
flex-grow 屬性
flex-grow
屬性是擴充套件比例,上面我們也談到了當子元素的flex-basis
總和小於父元素的寬度值時flex-grow
生效。
現在我們就來改變CSS,滿足這個前提條件。
CSS
.parent {
display: flex;
width: 600px;
}
.child_1,
.child_2,
.child_3 {
height: 200px;
}
.child_1 {
flex: 1 0 150px;
background-color: rgba(255, 0, 0, .5);
}
.child_2 {
flex: 0 0 100px;
background-color: rgba(0, 255, 0, .5);
}
.child_3 {
flex: 1 0 150px;
background-color: rgba(0, 0, 255, .5);
}複製程式碼
See the Pen Flex-2 by YeaseonZhang (@YeaseonZhang) on CodePen.
此時,各個元素的flex-basis
和為(150 + 100 + 150) = 400px
, 小於父元素的600px
,我們就來分別計算每個子元素的寬度值。
可用空間 = 父元素width - 子元素flex-basis總和 => 600 - (150 + 100 + 150) = 200
單位擴充套件空間 = 可用空間/子元素flex-grow總和 => 200/(1 + 0 + 1) = 100複製程式碼
子元素的計算公式為width = flex-basis + flex-grow * 單位擴充套件空間
所以child_1
寬度為(150 + 1 * 100) = 250px
, child_2
寬度為(100 + 0 * 100) = 100px
, child_3
同 child_1
。
flex-shrink 屬性
flex-shrink
屬性是收縮比例,當子元素的flex-basis
總和大於父元素的寬度值時flex-grow
生效。
現在我們就修改CSS滿足這個前提。
CSS
.parent {
display: flex;
width: 600px;
}
.child_1,
.child_2,
.child_3 {
/*flex: 1;*/
height: 200px;
}
.child_1 {
flex: 0 1 400px;
background-color: rgba(255, 0, 0, .5);
}
.child_2 {
flex: 0 1 200px;
background-color: rgba(0, 255, 0, .5);
}
.child_3 {
flex: 0 2 400px;
background-color: rgba(0, 0, 255, .5);
}複製程式碼
See the Pen Flex-3 by YeaseonZhang (@YeaseonZhang) on CodePen.
當然啦,我們可以按照flex-grow
的計算方法套用。
溢位空間 = 父元素width - 子元素flex-basis總和 => 600 - (400 + 200 + 400) = -400
單位收縮空間 = 溢位空間/子元素flex-shrink總和 => -400/(1 + 2 + 2) = -100複製程式碼
子元素的計算公式為width = flex-basis + flex-shrink * 單位收縮空間
所以child_1
寬度為(400 + 1 * (-100)) = 300px
, child_2
寬度為(200 + 1 * (-100)) = 100px
, child_3
同 (400 + 2 * (-100)) = 200px
。
大功告成了?其實並沒有例項情況並不是我們計算的那樣300px 100px 200px
,而是285.72px 142.86px 171.42px
。
通過Google,發現了一種收縮因數的計算方法:
理想空間 = 子元素(flex-basis * flex-shrink)之和 => 400 * 1 + 200 * 1 + 400 * 2 = 1400
溢位空間 = 父元素width - 子元素flex-basis總和 => 600 - (400 + 200 + 400) = -400
收縮因數 = (flex-basis * flex-shrink) / 理想空間 => 400 / 1400 = 0.286; 200 / 1400 = 0.143; 800 / 1400 = 0.571複製程式碼
分別為每個子元素計算了收縮因數就能計算我們子元素的實際寬度,子元素的計算公式width = flex-basis + 收縮因數 * 溢位空間
所以child_1
寬度為400 + 0.286 * (-400) = 285.6
, child_2
寬度為200 + 0.143 * (-400) = 142.8
, child_3
寬度為400 + 0.571 * (-400) = 171.6
現在我們計算出的值與瀏覽器渲染出的值基本上是相同的,我們對於flex
屬性的瞭解已經不再是單單的比例計算了,希望本文對你有所幫助。