Flexbox 意為彈性布局,是一種新的CSS 3 布局方式,與傳統布局方式(基於盒模型,依賴display屬性 +position屬性 +float屬性)相比,flex布局更加靈活,具有響應式,可以解決在布局上的很多麻煩。

廢話就不多說了,下面我將儘可能地用簡潔明了的言語來描述 Flex 布局。

基本概念

使用了flex布局,則有flex容器(flex container),子元素為項目(flex item)。

在 flex 容器中默認存在兩條軸,水平主軸(main axis) 和垂直的交叉軸(cross axis),start和end表示對應軸的起始位置,這是默認的設置,當然你可以通過修改使垂直方向變為主軸,水平方向變為交叉軸。比如將Flexbox的方向設置為row,則主軸就是橫軸,而交叉軸就是縱軸;反之設置成column,則主軸就是縱軸,而交叉軸就是橫軸,這個下面會具體講。

每個項目(flex item)佔據的主軸空間為 (main size), 佔據的交叉軸的空間為 (cross size)。

這裡還需要注意的是,不能直截了當地認為寬度就是 main size,高度就是 cross size,這個還要取決於你主軸的方向,如果你垂直方向是主軸,那麼項目的高度就是 main size。

實際上,要實現 flex 布局需要先指定一個容器,任何一個容器都可以被指定為 flex 布局,這樣容器內部的元素就可以使用 flex 來進行布局。語法如下:

.container {
display: flex | inline-flex; //可以有兩種取值
}

給div這類塊元素設置display: flex或者給span這類行內元素設display: inline-flex,flex布局即創建!

而Flex布局相關屬性正好分為兩撥,一撥作用在flex容器上,還有一撥作用在flex子項上。

需要注意的是:當時設置 flex 布局之後,子元素的 float、clear、vertical-align 的屬性將會失效。

Flex容器上的屬性

有下面六種屬性可以設置在容器上,它們分別是:

  1. flex-direction
  2. flex-wrap
  3. flex-flow
  4. justify-content
  5. align-items
  6. align-content

1. flex-direction: 決定主軸的方向(即項目的排列方向)

.container {
flex-direction: row | row-reverse | column | column-reverse;
}

  • row(默認):主軸為水平方向,起點在左端
  • row-reverse:主軸為水平方向,起點在右端

  • column:主軸為垂直方向,起點在上沿
  • column-reverse:主軸為垂直方向,起點在下沿

2. flex-wrap: 決定容器內項目是否可換行

默認情況下,項目都排在主軸線上,使用 flex-wrap 可實現項目的換行。

.container {
flex-wrap: nowrap | wrap | wrap-reverse;
}

  • nowrap(默認):不換行,即當主軸尺寸固定時,當空間不足時,項目尺寸會隨之調整而並不會擠到下一行
  • wrap:項目主軸總尺寸超出容器時換行,第一行在上方
  • wrap-reverse:換行並反向,第一行在下方

3. flex-flow: flex-direction 和 flex-wrap 的複合簡寫形式

.container {
flex-flow: <flex-direction> || <flex-wrap>;
}

默認值為: row nowrap,這個屬性其實沒多大卵用,不就是兩個屬性的縮寫嘛。

4. justify-content:定義項目在主軸的對齊方式

.container {
justify-content: flex-start | flex-end | center | space-between | space-around;
}

建立在主軸為水平方向時的測試,即 flex-direction: row

  • flex-start(默認):左對齊
  • flex-end:右對齊
  • center:居中
  • space-between:兩端對齊,項目之間的間隔相等,即剩餘空間等分成間隙
  • space-around:每個項目兩側的間隔相等,所以項目之間的間隔是項目與邊緣的間隔的兩倍

5. align-items: 定義項目在交叉軸上的對齊方式

.container {
align-items: stretch | flex-start | flex-end | center | baseline;
}

建立在主軸為水平方向時的測試,即 flex-direction: row

  • stretch(默認):如果項目未設置高度或設為auto,將佔滿整個容器的高度

假設容器高度設置為 50px,而項目都沒有設置高度或設為auto的情況下,則項目的高度也為 50px

  • flex-start:交叉軸的起點對齊
  • flex-end:交叉軸的終點對齊
  • center:交叉軸的中點對齊
  • baseline: 項目的第一行文字的基線對齊

以文字的底部為主

6. align-content: 定義多根軸線的對齊方式,如果項目只有一根軸線,那麼該屬性將不起作用

.container {
align-content: stretch | flex-start | flex-end | center | space-between | space-around;
}

什麼叫項目只有一根軸線呢?其實可以這麼理解:

當你 flex-wrap 設置為 nowrap 的時候,容器僅存在一根軸線,因為項目不會換行,就不會產生多條軸線。

當你 flex-wrap 設置為 wrap 的時候,容器可能會出現多條軸線,這時候你就需要去設置多條軸線之間的對齊方式了。

建立在主軸為水平方向時測試,即 flex-direction: row, flex-wrap: wrap

  • stretch(默認):軸線佔滿整個交叉軸
  • flex-start:軸線全部與交叉軸上的起點對齊
  • flex-end:軸線全部與交叉軸上的終點對齊
  • center:軸線全部在交叉軸上的中間對齊
  • space-between:軸線與交叉軸兩端對齊,軸線之間的間隔平均分布
  • space-around:每個軸線兩側的間隔都相等,所以軸線之間的間隔是軸線與邊緣的間隔的兩倍

到這裡關於容器上的所有屬性都講完了,接下來就來講講關於在 flex item(項目) 上的屬性。

Flex 項目上的屬性

item 項目上有六種屬性可運用,它們分別是:

  1. order
  2. flex-grow
  3. flex-shrink
  4. flex-basis
  5. flex
  6. align-self

1. order: 定義項目在容器中的排列順序,數值越小,排列越靠前,默認值為 0

.item {
order: <integer>;
}

2. flex-grow: 定義項目的放大比例

.item {
flex-grow: <number>;
}

默認值為 0,即如果存在剩餘空間,也不放大。

如果所有項目的 flex-grow 屬性都為1,則它們將等分剩餘空間(如果有的話)。如果一個項目的 flex-grow 屬性為2,其他項目都為1,則前者佔據的剩餘空間將比其他項多一倍。

3. flex-shrink: 定義項目的縮小比例

.item {
flex-shrink: <number>;
}

flex-shrink屬性定義了項目的縮小比例,默認為1,即如果空間不足,該項目將縮小。

如果所有項目的 flex-shrink 屬性都為1,當空間不足時,都將等比例縮小。如果一個項目的flex-shrink 屬性為0,其他項目都為1,則空間不足時,前者不縮小。

負值對該屬性無效。

4. flex-basis: 定義了在分配容器剩餘空間之前項目的默認大小。相當於對瀏覽器提前告知:瀏覽器兄弟,我要佔據這麼大的空間,提前幫我預留好

.item {
flex-basis: <length> | auto;
}

默認值:auto,即項目本來的大小, 這時候 item 項目的寬高取決於 width 或 height 的值。

當主軸為水平方向的時候,同時設置 width 和 flex-basis,會忽略 width。flex顧名思義就是彈性的意思,因此,實際上不建議對flex項目使用 width 屬性,因為不夠彈性。

當容器剩餘空間不足的時候,flex子項目的實際寬度通常不是設置的 flex-basis 尺寸,因為flex布局剩餘空間不足的時候默認會收縮,如果有3個子項目,則默認按1:1:1收縮。

5. flex: flex-grow, flex-shrink 和 flex-basis的複合縮寫

.item{
flex: none | [ <flex-grow> <flex-shrink>? || <flex-basis> ]
}

flex 的默認值是以上三個屬性值的組合。假設以上三個屬性同樣取默認值,則 flex 的默認值為0 1 auto。

有關快捷值:

flex: auto //等同於flex:1 1 auto
flex: none //等同於flex:0 0 auto

6. align-self: 控制單獨某一個項目的垂直對齊方式,與align-items屬性語法區別不大

.item {
align-self: auto | flex-start | flex-end | center | baseline | stretch;
}

唯一區別就是align-self多了個auto(默認值),表示繼承自flex容器的align-items屬性值,如果沒有父元素,則等同於 stretch。

跟 align-items 其他屬性值含義一樣,只不過 align-self 是對單個項目生效的,而 align-items 則是對容器下的所有項目生效的。

從垂直居中看出flex的強大

以往讓元素垂直居中並不容易,直到CSS3的出現,使用絕對定位配合translate屬性才讓垂直居中變得簡單,不過還有一個更爽的辦法,那就是使用flex,讓垂直居中變得異常簡單

<div class=「wrapper」>
<div class=「div」>
flexbox 對你說愛不完
</div>
</div>

幾行簡單代碼,即可讓div垂直居中

.wrapper {
display: flex;
align-items: center;
justify-content: center;
}

這裡最重要的就是包裹元素的三個關鍵屬性

  • display: flex 將容器指定為flex布局,任何一個元素都可以指定
  • align-items: center 沿交叉軸對齊項目,這裡指的是垂直方向
  • justify-content: center 設置主軸內容對齊方式

其他Flex知識點

  • 在Flex布局中,再強調一遍flex子元素中設置floatclear以及vertical-align屬性都是沒有用的。
  • Flexbox布局最適合應用程序的組件和小規模布局(一維布局),而Grid布局則適用於更大規模的布局(二維布局),有關Grid布局的文章後面會補充。
  • 已經9102年了,Flex老語法不用在管了,果斷放棄,然後私有前綴也不用再加了,看到就煩。
  • 如果想更好地理解Flex的工作原理,可以在此頁面上嘗試flex 布局編輯器。

如果覺得文章對你有些許幫助,歡迎在我的GitHub博客點贊和關注,感激不盡!

推薦閱讀:

相关文章