flexbox(彈性盒佈局模型),以及適用場景

喆星高照發表於2021-04-09

一、是什麼

Flexible Box 簡稱 flex,意為”彈性佈局”,可以簡便、完整、響應式地實現各種頁面佈局

採用Flex佈局的元素,稱為flex容器container

它的所有子元素自動成為容器成員,稱為flex專案item

 

 

容器中預設存在兩條軸,主軸和交叉軸,呈90度關係。專案預設沿主軸排列,通過flex-direction來決定主軸的方向

每根軸都有起點和終點,這對於元素的對齊非常重要

二、屬性

關於flex常用的屬性,我們可以劃分為容器屬性和容器成員屬性

容器屬性有:

  • flex-direction
  • flex-wrap
  • flex-flow
  • justify-content
  • align-items
  • align-content

flex-direction

決定主軸的方向(即專案的排列方向)

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

屬性對應如下:

  • row(預設值):主軸為水平方向,起點在左端
  • row-reverse:主軸為水平方向,起點在右端
  • column:主軸為垂直方向,起點在上沿。
  • column-reverse:主軸為垂直方向,起點在下沿

如下圖所示:

 

 

flex-wrap

彈性元素永遠沿主軸排列,那麼如果主軸排不下,通過flex-wrap決定容器內專案是否可換行

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

屬性對應如下:

  • nowrap(預設值):不換行
  • wrap:換行,第一行在上方
  • wrap-reverse:換行,第一行在上方

預設情況是不換行,但這裡也不會任由元素直接溢位容器,會涉及到元素的彈性伸縮

flex-flow

flex-direction屬性和flex-wrap屬性的簡寫形式,預設值為row nowrap

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

justify-content

定義了專案在主軸上的對齊方式

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

屬性對應如下:

  • flex-start(預設值):左對齊
  • flex-end:右對齊
  • center:居中
  • space-between:兩端對齊,專案之間的間隔都相等
  • space-around:兩個專案兩側間隔相等

效果圖如下:

 

 

align-items

定義專案在交叉軸上如何對齊

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

屬性對應如下:

  • flex-start:交叉軸的起點對齊
  • flex-end:交叉軸的終點對齊
  • center:交叉軸的中點對齊
  • baseline: 專案的第一行文字的基線對齊
  • stretch(預設值):如果專案未設定高度或設為auto,將佔滿整個容器的高度

align-content

定義了多根軸線的對齊方式。如果專案只有一根軸線,該屬性不起作用

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

屬性對應如嚇:

  • flex-start:與交叉軸的起點對齊
  • flex-end:與交叉軸的終點對齊
  • center:與交叉軸的中點對齊
  • space-between:與交叉軸兩端對齊,軸線之間的間隔平均分佈
  • space-around:每根軸線兩側的間隔都相等。所以,軸線之間的間隔比軸線與邊框的間隔大一倍
  • stretch(預設值):軸線佔滿整個交叉軸

效果圖如下:

 

 

容器成員屬性如下:

  • order
  • flex-grow
  • flex-shrink
  • flex-basis
  • flex
  • align-self

order

定義專案的排列順序。數值越小,排列越靠前,預設為0

.item {
    order: <integer>;
}

flex-grow

上面講到當容器設為flex-wrap: nowrap;不換行的時候,容器寬度有不夠分的情況,彈性元素會根據flex-grow來決定

定義專案的放大比例(容器寬度>元素總寬度時如何伸展)

預設為0,即如果存在剩餘空間,也不放大

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

如果所有專案的flex-grow屬性都為1,則它們將等分剩餘空間(如果有的話)

 

 

如果一個專案的flex-grow屬性為2,其他專案都為1,則前者佔據的剩餘空間將比其他項多一倍

 

 

彈性容器的寬度正好等於元素寬度總和,無多餘寬度,此時無論flex-grow是什麼值都不會生效

flex-shrink

定義了專案的縮小比例(容器寬度<元素總寬度時如何收縮),預設為1,即如果空間不足,該專案將縮小

.item {
    flex-shrink: <number>; /* default 1 */
}

如果所有專案的flex-shrink屬性都為1,當空間不足時,都將等比例縮小

如果一個專案的flex-shrink屬性為0,其他專案都為1,則空間不足時,前者不縮小

 

 

在容器寬度有剩餘時,flex-shrink也是不會生效的

flex-basis

設定的是元素在主軸上的初始尺寸,所謂的初始尺寸就是元素在flex-growflex-shrink生效前的尺寸

瀏覽器根據這個屬性,計算主軸是否有多餘空間,預設值為auto,即專案的本來大小,如設定了width則元素尺寸由width/height決定(主軸方向),沒有設定則由內容決定

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

當設定為0的是,會根據內容撐開

它可以設為跟widthheight屬性一樣的值(比如350px),則專案將佔據固定空間

flex

flex屬性是flex-growflex-shrink 和 flex-basis的簡寫,預設值為0 1 auto,也是比較難懂的一個複合屬性

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

一些屬性有:

  • flex: 1 = flex: 1 1 0%
  • flex: 2 = flex: 2 1 0%
  • flex: auto = flex: 1 1 auto
  • flex: none = flex: 0 0 auto,常用於固定尺寸不伸縮

flex:1 和 flex:auto 的區別,可以歸結於flex-basis:0flex-basis:auto的區別

當設定為0時(絕對彈性元素),此時相當於告訴flex-growflex-shrink在伸縮的時候不需要考慮我的尺寸

當設定為auto時(相對彈性元素),此時則需要在伸縮時將元素尺寸納入考慮

注意:建議優先使用這個屬性,而不是單獨寫三個分離的屬性,因為瀏覽器會推算相關值

align-self

允許單個專案有與其他專案不一樣的對齊方式,可覆蓋align-items屬性

預設值為auto,表示繼承父元素的align-items屬性,如果沒有父元素,則等同於stretch

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

效果圖如下:

 

 

三、應用場景

在以前的文章中,我們能夠通過flex簡單粗暴的實現元素水平垂直方向的居中,以及在兩欄三欄自適應佈局中通過flex完成,這裡就不再展開程式碼的演示

包括現在在移動端、小程式這邊的開發,都建議使用flex進行佈局

參考文獻

  • https://developer.mozilla.org/zh-CN/docs/Web/CSS/flex
  • http://www.ruanyifeng.com/blog/2015/07/flex-grammar.html

相關文章