深入理解Flex屬性

Yeaseon_Zhang發表於2017-10-12

作者: Yeaseon
Blog:yeaseonzhang.github.io
原文連結

Flex 是 Flexible Box的縮寫,意為“彈性佈局”,可以簡便、完整、響應式地實現各種頁面佈局。

Flex的出現就是為了解決傳統佈局的display屬性 + position屬性 + float屬性的複雜性。

瀏覽器對於Flex的支援性

可以看到瀏覽器對於Flex佈局的支援性已經很好了,所以我們可以放心大膽的用在我們專案中。

flex 屬性

flex: flex-grow | flex-shrink | flex-basis

flex屬性包含三個值:flex-growflex-shrinkflex-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-growflex-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_3child_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屬性的瞭解已經不再是單單的比例計算了,希望本文對你有所幫助。

相關文章