CSS Flexible Box Layout

目錄

引子

最近接觸 flex 佈局的時候,碰到一些問題,因而藉着這個機會,對 flex 相關的知識點進行整理。css

簡介

CSS 2.1 定義了 4 種佈局模式,這些算法是根據盒子與它們的兄弟和祖先盒子的關係,來肯定盒子自身大小和位置。分別有:html

  • block 佈局,爲文檔佈局設計
  • inline 佈局,爲文本佈局設計
  • table 佈局,爲表格形式的 2D 數據佈局設置
  • positioned 佈局,設計用於很是明確的定位,不用考慮文檔中的其餘元素

新引入的 flex 佈局,跟 block 佈局很相似,它缺乏不少在 block 佈局中,有關文本和文檔相關的特性,例如浮動。相應的,它擁有了簡單且強大的工具,用於來分配空間,並能夠按照 web 應用程序和複雜網頁常常須要的方式對齊內容。git

目前處於候選推薦階段,主流瀏覽器支持的狀況很不錯,詳細見 Can I use flexgithub

相關概念和術語

一個元素設置 display 屬性值爲 flexinline-flex,就會變成一個 flex 容器(flex container),其直接子元素被稱爲 flex 項(flex items),它們佈局使用 flex 佈局模式。web

在 CSS 中定義了一些跟物理方向和空間相對應的一些概念,這些概念爲將來定義新的佈局提供理論支持,在 flex 佈局模式中對應物理方向和空間的概念以下圖。算法

32-css-flex

  • main axis:主軸,flex 項的排列是按照主軸進行排列,主軸的方向取決於 flex-direction 屬性,不必定是水平方向。
  • main-start/main-end:flex 容器主軸上的開始/結束位置,flex 項的排列是從 main-start 開始,到 main-end 結束。
  • main-size:在主軸方向 flex 容器或者 flex 項的高度或寬度,它多是元素的 widthheight 屬性。相似的,它的 min/max main size 屬性取決於它的 min-width/max-width 或者 min-height/max-height 屬性。
  • cross axis:側軸,跟主軸方向垂直的軸。
  • cross-start/cross-end:flex 容器側軸上的開始/結束位置,flex 項的排列是從 cross-start 開始,到 cross-end 結束。
  • cross-size:在側軸方向 flex 容器或者 flex 項的高度或寬度,它多是元素的 widthheight 屬性。相似的,它的 min/max cross size 屬性取決於它的 min-width/max-width 或者 min-height/max-height 屬性。

flex container

成爲 flex 容器的方式是,設置 display 屬性值爲 flex | inline-flex瀏覽器

  • flex:當一個塊級元素放在流佈局中,這個值會讓這個元素生成一個 flex 容器盒子。
  • inline-flex:當一個內聯元素放在流佈局中,這個值會讓這個元素生成一個 flex 容器盒子。

flex 容器會爲它的內容創建一個 flex 格式化上下文,它造成的包含塊就像塊級容器作的那樣。flex 容器的外邊距(margin)不會跟它內容的邊距重合。overflow 屬性適用於 flex 容器。flex 容器不是塊級容器,而且有些適用於 block 佈局的屬性在 flex 佈局中並不適用,特別是:ide

  • floatclear 不會產生浮動或者清空 flex 項,而且不會讓元素脫離文檔流。
  • vertical-align 對 flex 項沒有做用。
  • ::first-linefirst-letter 僞元素不適用於 flex 容器,flex 容器不會爲它們的祖先提供第一行格式化或第一個字母。

這是測試示例,移動端查看以下。工具

32-qrcode-flex-test

若是一個元素的 display 屬性設置爲 inline-flex,在特定的環境下,它的的 display 屬性會被計算爲 flex佈局

用於 flex 容器的相關屬性有:

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

flex-direction

屬性名:flex-direction

可取值:row | row-reverse | column | column-reverse

默認值:row

適用於:flex 容器

可繼承:否

flex-direction 屬性經過設置 flex 容器主軸的方向,來指定 flex 項在 flex 容器中的放置方式。

這是測試示例,移動端查看以下。

32-qrcode-flex-direction

flex-wrap

屬性名:flex-wrap

可取值:nowrap | wrap | wrap-reverse

默認值:nowrap

適用於:flex 容器

可繼承:否

flex-wrap 屬性決定 flex 容器是單行仍是多行,側軸的方向決定了新行的插入方向。

  • nowrap:flex 容器的子元素單行顯示。
  • wrap:flex 項在當前行顯示不了時,會換行顯示。
  • wrap-reverse:flex 項在當前行顯示不了時,會換行顯示。

當值爲非 wrap-reverse 時,cross-start 的方向與 當前 writing modeinline-startblock-start 方向一致,當值爲 wrap-reverse 時,cross-startcross-end 方向相反。

這是測試示例,移動端查看以下。

32-qrcode-flex-wrap

flex-flow

flow-flowflex-directionflex-wrap 的縮寫。
屬性名:flex-flow

可取值:flex-direction || flex-wrap

適用於:flex 容器

可繼承:否

justify-content

屬性名:justify-content

可取值:flex-start | flex-end | center | space-between | space-around

默認值:flex-start

適用於:flex 容器

可繼承:否

justify-content 屬性沿着 flex 容器當前行的主軸對齊 flex 項。

  • flex-start:flex 項向行的開始位置放置。行內第一個 flex 項的 main-start 外邊距邊界與行的 main-start 的外邊距邊界齊平,每一個後續的 flex 項與前一項齊平放置。
  • flex-end:flex 項向行的結束位置放置。行內最後一個 flex 項的 main-end 外邊距邊界與行的 main-end 的外邊距邊界齊平,每一個前面的 flex 項與後續的項齊平放置。
  • center:flex 項向行的中間位置放置。行內每一個 flex 項齊平放置並與行的中心對齊,行的 main-start 邊界與第一個 flex 項之間的空間,和行的main-end 邊界與最後一個 flex 項之間的空間等量。
  • space-between:flex 項在行內均勻分佈。若是剩下的自由空間是負的,或者只有一個 flex 項在行內,這個值的做用與 flex-start 等同。除此以外,行內第一個 flex 項的 main-start 外邊距邊界與行的 main-start 的外邊距邊界對齊,行內最後一個 flex 項的 main-end 外邊距邊界與行的 main-end 的外邊距邊界對齊,剩下的 flex 項在行上均勻分佈,任意兩個相鄰 flex 項的間距相同。
  • space-around:flex 項在行內均勻分佈,兩端各有一半的空間。若是剩下的自由空間是負的,或者只有一個 flex 項在行內,這個值會被識別爲 center。除此以外,在行內任意兩個相鄰的 flex 項的間距相同,第一個和最後一個 flex 項與 flex 容器邊界的間距是相鄰 flex 項之間間距的一半。

32-justify-content

這是測試示例,移動端查看以下。

32-qrcode-justify-content

align-items

屬性名:align-items

可取值:flex-start | flex-end | center | baseline | stretch

默認值:stretch

適用於:flex 容器

可繼承:否

align-items 設置全部 flex 容器的項的默認對齊方式,包括匿名的 flex 項。

  • flex-start:flex 項的 cross-start 外邊距邊界與行的 cross-start 邊界對齊。
  • flex-end:flex 項的 cross-end 外邊距邊界與行的 cross-end 邊界對齊。
  • center:flex 項的外邊距盒子在行的側軸上中心。
  • baseline:flex 項基於基線對齊,行內全部參與的 flex 項目都基於基線對齊,而且擁有基線與其自身的 cross-start 外邊距邊界最大距離的 flex 項,與行的 cross-start 邊界齊平。若是項目在必要的軸中沒有基線,則從 flex 項的邊框盒子合成基線。
  • stretch:若是 flex 項的 cross size 屬性計算爲 auto,而且側軸的的外邊距都不是 auto,那麼 flex 項會被拉伸。它使用的值是儘量的讓 項的外邊距盒子的 cross size 與行的大小一致的長度,仍然受到 min-height/min-width/max-height/max-width 的約束。

32-align-items

這是測試示例,移動端查看以下。

32-qrcode-align-items

align-content

屬性名:align-content

可取值:flex-start | flex-end | center | space-between | space-around | stretch

默認值:stretch

適用於:多行 flex 容器

可繼承:否

當在側軸上有多餘的空間時,align-content 屬性讓 flex 容器內的行對齊。注意,該屬性對單行 flex 容器沒有做用。

  • flex-start:行向 flex 容器的開始位置放置。flex 容器內第一行的 cross-start 邊界與flex 容器的 cross-start 邊界齊平,後續的每行與前一行齊平。
  • flex-end:行向 flex 容器的結束位置放置。flex 容器內最後一行的 cross-end 邊界與flex 容器的 cross-end 邊界齊平,每一個前面的行與後續的行齊平放置。
  • center:行向 flex 容器的中間位置放置。flex 容器內每一行都齊平放置並與 flex 容器的中心對齊,flex 容器內第一行與 flex 容器的 cross-start 內容邊界的空間,和 flex 容器內最後一行與 flex 容器的 cross-end 內容邊界的空間等量。
  • space-between:行在 flex 容器內均勻分佈。若是剩下的自由空間是負的,或者只有一行在 flex 容器內,這個值的做用與 flex-start 等同。除此以外,flex 容器內第一行的 cross-start 邊界與 flex 容器的 cross-start 內容邊界對齊,flex 容器內最後一行的 main-end 邊界與 flex 容器的 main-end 的內容邊界對齊,剩下的行在 flex 容器內均勻分佈,任意相鄰行的間距相同。
  • space-round:行在 flex 容器內均勻分佈,兩端各有一半的空間。若是剩下的自由空間是負的,這個值的做用與 center 等同。除此以外,flex 容器內任意相鄰的行的間距相同,第一行和最後一行與 flex 容器邊界的間距是相鄰行間距的一半。
  • stretch:行會伸展佔據剩餘的空間。若是剩下的自由空間是負的,這個值的做用與 flex-start 等同。除此以外,剩餘的空間會被全部的行平分。

32-align-content

這是測試示例,移動端查看以下。

32-qrcode-align-content

flex item

flex 容器下每一個在文檔流裏的後代都會成爲一個 flex 項。每一個連續的子文本都包含在匿名塊容器 flex 項中。若是隻包含空白符,就不會渲染,就好像文本節點擁有屬性 display: none 。flex 項爲它的內容創建一個獨立的格式化上下文。然而,flex 項是 flex 級別盒子,不是 block 級別盒子,它們參與本身的 flex 格式化上下文,不是在 block 格式化上下文。

若是在 flex 容器內,在文檔流的後代設置 display 爲內聯的值,其計算值與塊級別值等效。也就是說這種狀況下 flex 項的 display 屬性值被鎖定。詳細見 CSS Display

flex 容器內絕對定位,脫離文檔流的後代不會參與 flex 佈局。這樣的 flex 容器的靜態位置矩形(static-position rectangle )是它的內容盒子,這個靜態位置矩形是用來決定絕對定位盒子偏移位置的容器。

相鄰 flex 項的邊距(margin)不會合並。flex 項的 marginpadding 爲百分比時,跟塊級盒子同樣,會根據包含快的邏輯寬度計算。margin 的值爲 auto 時,會在相應的維度,吸取額外的空間。它們能夠用來對齊或者分開 flex 項。

用於 flex 項的相關屬性有:

  • flex
  • order
  • align-self

flex

屬性名:flex

可取值:none | [ <‘flex-grow’> <‘flex-shrink’>? || <‘flex-basis’> ]

默認值:0 1 auto

適用於:flex 項

可繼承:否

影響 flex 項長度有 flex 因子(增加和收縮)和 flex 基礎。當一個盒子是 flex 項時,flex 屬性決定了盒子的主要大小。若是一個盒子不是 flex 項,flex 屬性將不會有做用。

flex 設置值爲 none 時,至關於 0 0 auto

flex-grow

值爲數字。當空間剩餘時,這個屬性決定了 flex 項相對於 flex 容器下其它 flex 項,會增加多少空間。當在 flex 簡寫中省略時,設置爲 1 。

flex-shrink

值爲數字。當空間不足時,這個屬性決定了 flex 項相對於 flex 容器下其它 flex 項,會收縮多少空間。當在 flex 簡寫中省略時,設置爲 1 。

flex-basis

flex-basis 定義了在分配多餘空間前,flex 項的初始 main size。

  • auto:使用該值時,將會取 main size 屬性的值,若是 main size 屬性的值也是 auto,則使用值 content
  • content:基於 flex 項的內容大小自動生成。
  • <‘width’>:除了上面兩個值,flex-basis 使用方式與 widthheight 相同。

在 flex 簡寫中省略時,設置的值是 0 。

flex 常見值

  1. flex: initial:至關於 flex: 0 1 auto 。flex 項的大小基於 width/height 屬性。當有剩餘空間時,不會分配剩餘空間,但容許空間不足時縮小到最小尺寸。對齊的屬性或者 auto 外邊距能夠用來讓 flex 項沿主軸對齊。
  2. flex: auto:至關於 flex: 1 1 auto 。flex 項的大小基於 width/height 屬性。當有剩餘空間時,會沿着主軸,儘量的吸取剩餘空間。若是全部項目都是 flex: autoflex: initialflex: none ,則在項目大小調整後,任何剩餘空間將均勻分配到具備屬性 flex: auto 的項。
  3. flex: none:至關於 flex: 0 0 auto 。flex 項的大小根據 width/height 屬性。盒子不會變得有彈性,跟取值 initial 有點相似,但不容許 flex 項收縮,即便在溢出的狀況下。
  4. flex: <positive-number>:至關於 flex: <positive-number> 1 0 。flex 項接收 flex 容器中指定比例的可用空間。若是 flex 容器下全部 flex 項都使用這種模式,它們的大小將與指定的彈性係數成比例。

這是測試示例,移動端查看以下。

32-qrcode-flex

order

屬性名:order

可取值:<integer>

默認值:0

適用於:flex 項

可繼承:否

order 屬性控制了 flex 項在 flex 容器裏面顯示的順序。flex 容器放置內容,從最低編號開始按順序向上。序號相同的組,會按照它們在源文檔中出現的順序放置。flex 容器內絕對定位的後代,會被當作擁有 order: 0 ,這樣作是爲了決定它們相對於 flex 項的繪製順序。

這是測試示例,移動端查看以下。

32-qrcode-order

align-self

屬性名:align-self

可取值:auto | flex-start | flex-end | center | baseline | stretch

默認值:auto

適用於:flex 項

可繼承:否

align-self 做用跟 align-items 同樣,但它適用於 flex 項,能夠爲單獨的 flex 項設置對齊的方式,會覆蓋 align-items 的效果。

若是 flex 項的側軸任一外邊距爲 auto ,那麼 align-self 無效。

align-selfalign-items 多了一個可取值 auto ,使用該值時,對齊方式的控制權交給了父級盒子。

這是測試示例,移動端查看以下。

32-qrcode-align-self

參考資料

相關文章
相關標籤/搜索