1. 程式人生 > >還在為垂直居中苦惱?CSS 佈局利器 flexbox 輕輕鬆鬆幫你搞定

還在為垂直居中苦惱?CSS 佈局利器 flexbox 輕輕鬆鬆幫你搞定

傳統的 CSS 佈局方式是基於**盒模型**(它是根據盒子與父盒子以及兄弟盒子的關係確定**大小**和**位置**的演算法),實現時依賴於 *block*, *inline*, *table*, *position*, *float* 這些屬性,但對於一些特殊佈局不易實現,比如**垂直居中**。 **Flexbox Layout** 是一種新的佈局方式,被稱為**彈性佈局**,它使得子元素(*items*)可以靈活的、響應式的適應父容器(*flex container*)的空間,即使子元素的大小未知或是動態,並且可以很容易實現元素的水平和垂直對齊。 盒模型是基於 **block** 和 **inline** 的流動方向進行佈局,而 **flex 佈局**則是基於彈性流方向(**flex-flow directions**),基本思想如下圖所示。 ![flex-direction-terms.svg](https://img2018.cnblogs.com/blog/1424165/201908/1424165-20190810220816710-1302494784.png) flex 容器內的子元素會沿著 **main axis**(從 **main-start** 到 **main-end** )或 **cross axis**(從 **cross-start** 到 **cross-end**)進行佈局,其中: - **main axis** - **主軸**,子元素排列的基本軸,要**注意**,它不一定是水平的,這取決於 **flex-direction** 屬性的配置 - **main-start | main-end** - 子元素從 main-start 開始到 main-end 彈性的放置在容器中,預設都在一行排列,**不換行**, 除非設定 **flex-wrap** 屬性 - **main size** - 子元素的**主尺寸**,如果主軸是水平的,那 *width* 是主尺寸;垂直的,那 *height* 是主尺寸 - **cross axis** - 垂直於主軸的軸,稱之為**交叉軸**,方向取決於主軸的方向 - **cross-start | cross-end** - 當子元素**換行時**,每行則從 cross-start 開始到 cross-end 排列 - **cross size** - 與 main size 同理,只不過剛好相反 # Flex Container 使用以下程式碼就可以將一個 HTML 元素指定為 **flex 佈局**: ```css .container { display: flex; /* or inline-flex */ } ``` 這個元素稱為 **Flex Container**,內部其他 HTML 元素被稱為 **Flex Items**。**flex 容器** 有 6 個屬性: - flex-direction - flex-wrap - flex-flow - justify-content - align-items - align-content ## flex-direction ![flex-direction.svg](https://img2018.cnblogs.com/blog/1424165/201908/1424165-20190810220843363-1765397213.png) **確定主軸的方向**,也就是內部元素的彈性排列方向。如果不考慮換行,Flexbox 是**單向佈局**的概念,始終將元素放置在**水平行**或**垂直列**中。 ```css .container { flex-direction: row | row-reverse | column | column-reverse; } ``` - row(預設): 主軸為水平方向,從左到右排列 - row-reverse: 主軸為水平方向,從右到左排列 - column: 主軸為垂直方向,從上到下排列 - column-reverse: 主軸為垂直方向,從下到上排列 ## flex-wrap ![flex-wrap.svg](https://img2018.cnblogs.com/blog/1424165/201908/1424165-20190810220859316-1822917777.png) 預設情況下,子元素不會換行,只會在同一行(或列)中放置,可以使用此屬性**設定換行**。 ```css .container{ flex-wrap: nowrap | wrap | wrap-reverse; } ``` - nowrap (預設): 不換行 - wrap: 換行,第一行在上方 - wrap-reverse: 換行,第一行在下方 ## flex-flow 它是 flex-direction 和 flex-wrap 屬性的縮寫. ```css flex-flow: <'flex-direction'> || <'flex-wrap'> ``` 預設是: `flex-flow: row nowrap` ## justify-content ![justify-content.svg](https://img2018.cnblogs.com/blog/1424165/201908/1424165-20190810220924362-127493445.png) 定義子元素在**主軸上的對齊方式**。 ```css .container { justify-content: flex-start | flex-end | center | space-between | space-around | space-evenly; } ``` - flex-start (**預設**): 左對齊,以主軸的起點對齊 - flex-end: 右對齊,以主軸的終點對齊 - center: 居中,以主軸的中點對齊 - space-between: 兩端對齊,子元素間隔相等 - space-around: 子元素兩側的間隔相等,因此,元素之間的間隔正好是與邊框間隔的兩倍 - space-evenly: 子元素分佈排列,並且兩個元素的間隔與到邊框的間隔相等 ## align-items ![align-items.svg](https://img2018.cnblogs.com/blog/1424165/201908/1424165-20190810220939935-660491201.png) 定義子元素在**交叉軸上如何對齊**。 ```css .container { align-items: stretch | flex-start | flex-end | center | baseline; } ``` - stretch (**預設值**): 如果子元素沒有指定高度或設為 auto,將會拉伸佔滿容器的高度 - flex-start: 以交叉軸的起點對齊 - flex-end: 以交叉軸的終點對齊 - center: 以交叉軸的中點對齊 - baseline: 以子元素的第一行文字的基線對齊 ## align-content ![align-content.png](https://img2018.cnblogs.com/blog/1424165/201908/1424165-20190810220955032-2050560065.png) 定義容器內部多行元素的**行對齊方式**,類似於 **justify-content** 定義主軸內**元素的對齊方式**。 **注意: **當只有一行元素時,此屬性不生效 ```css .container { align-content: flex-start | flex-end | center | space-between | space-around | stretch; } ``` - stretch (**預設值**):每行拉伸佔滿整個交叉軸 - flex-start:以交叉軸的起點對齊 - flex-end:以交叉軸的終點對齊 - center:以交叉軸的中點對齊 - space-between:在交叉軸上兩端對齊,每行間隔相等 - space-around:每行兩側的間隔相等,因此,行間隔正好是與邊框間隔的兩倍 # Flex Items Flex 容器內部的子元素也有 6 個屬性,分別是: - order - flex-grow - flex-shrink - flex-basis - flex - align-self ## order ![order.png](https://img2018.cnblogs.com/blog/1424165/201908/1424165-20190810221020401-462493865.png) 預設情況下,元素按**原始順序**排列,但是該屬性可以控制元素在 Flex 容器中的顯示順序,數值越小,越靠前,預設為 0。 ```css .item { order: