傳統的 CSS 佈局方式是基於盒模型(它是根據盒子與父盒子以及兄弟盒子的關係肯定大小和位置的算法),實現時依賴於 block, inline, table, position, float 這些屬性,但對於一些特殊佈局不易實現,好比垂直居中。css
Flexbox Layout 是一種新的佈局方式,被稱爲彈性佈局,它使得子元素(items)能夠靈活的、響應式的適應父容器(flex container)的空間,即便子元素的大小未知或是動態,而且能夠很容易實現元素的水平和垂直對齊。算法
盒模型是基於 block 和 inline 的流動方向進行佈局,而 flex 佈局則是基於彈性流方向(flex-flow directions),基本思想以下圖所示。瀏覽器
flex 容器內的子元素會沿着 main axis(從 main-start 到 main-end )或 cross axis(從 cross-start 到 cross-end)進行佈局,其中:ide
使用如下代碼就能夠將一個 HTML 元素指定爲 flex 佈局:svg
.container {
display: flex; /* or inline-flex */
}
複製代碼
這個元素稱爲 Flex Container,內部其餘 HTML 元素被稱爲 Flex Items。flex 容器 有 6 個屬性:源碼分析
肯定主軸的方向,也就是內部元素的彈性排列方向。若是不考慮換行,Flexbox 是單向佈局的概念,始終將元素放置在水平行或垂直列中。佈局
.container {
flex-direction: row | row-reverse | column | column-reverse;
}
複製代碼
默認狀況下,子元素不會換行,只會在同一行(或列)中放置,可使用此屬性設置換行。flex
.container{
flex-wrap: nowrap | wrap | wrap-reverse;
}
複製代碼
它是 flex-direction 和 flex-wrap 屬性的縮寫.ui
flex-flow: <'flex-direction'> || <'flex-wrap'>
複製代碼
默認是: flex-flow: row nowrap
flexbox
定義子元素在主軸上的對齊方式。
.container {
justify-content: flex-start | flex-end | center | space-between | space-around | space-evenly;
}
複製代碼
定義子元素在交叉軸上如何對齊。
.container {
align-items: stretch | flex-start | flex-end | center | baseline;
}
複製代碼
定義容器內部多行元素的行對齊方式,相似於 justify-content 定義主軸內元素的對齊方式。
**注意: **當只有一行元素時,此屬性不生效
.container {
align-content: flex-start | flex-end | center | space-between | space-around | stretch;
}
複製代碼
Flex 容器內部的子元素也有 6 個屬性,分別是:
默認狀況下,元素按原始順序排列,可是該屬性能夠控制元素在 Flex 容器中的顯示順序,數值越小,越靠前,默認爲 0。
.item {
order: <integer>; /* default is 0 */
}
複製代碼
定義元素在必要時擴大的能力s,好比容器還有剩餘空間。默認爲 0,有空間也不擴大。
若是全部元素都設置爲 1,那麼會均攤容器剩餘的空間;若是其中一個元素值爲 2,那麼它佔的剩餘空間是其餘元素的兩倍(至少儘可能會這樣作)。
**注意: **負值無效。
.item {
flex-grow: <number>; /* default 0 */
}
複製代碼
定義元素在必要時縮小的能力,默認爲 1,即若是空間不足,該元素將會縮小。
相對的,若是全部元素此屬性值都爲 1,空間不足時會等比例縮小;若是有一個元素值爲 0,其餘爲 1,空間不足時,前者不縮小。
**注意: **負值無效。
.item {
flex-shrink: <number>; /* default 1 */
}
複製代碼
定義在分配容器剩餘空間以前,如何判斷子元素的大小,瀏覽器根據此屬性計算主軸剩餘空間的大小。
值可設爲指定長度(如 20%, 5rem)或關鍵字(auto)。默認爲 auto,元素的大小依據 main size(主尺寸),若是 main size 爲 auto,則使用元素內容的最大長度。
.item {
flex-basis: <length> | auto; /* default auto */
}
複製代碼
子元素在彈性擴大時, flex-basis 的不一樣可能會形成不同的結果,下圖分別是**"絕對"(從0開始算起)彈性和"相對"(從元素內容長度開始算起)**彈性的差別結果。
其中三個子元素 flex-grow 的值爲 1:1:2:
因爲瀏覽器計算主軸剩餘空間的大小不一樣,因此致使元素彈性結果的不一樣。
該屬性是 flex-grow, flex-shrink 和 flex-basis 的簡寫,其中第二個和第三個參數( flex-shrink 和 flex-basis )是可選的.
.item {
flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]
}
複製代碼
默認是 flex: 0 1 auto
, 建議優先使用此屬性,它有兩個簡便使用的關鍵字: auto(1 1 auto) 和 none(0 0 auto).
容許元素覆蓋默認的或是使用 align-items 指定的對齊方式。
.item {
align-self: auto | flex-start | flex-end | center | baseline | stretch;
}
複製代碼
除了 auto, 其餘屬性值都與 align-items 一致。
**注意: **float, clear 和 vertical-align 對 flex 容器內的元素不生效。
其中:
最後回到題目的問題,經常使用的垂直居中,只需將 flex 容器的 align-items 和 justify-content 屬性值設爲 center 便可。
參考: A Complete Guide to Flexbox
搜索公衆號「頓悟源碼」獲取更多源碼分析和造的輪子。