這週是 六角鼠年鐵人賽 第三週,不知道要寫啥,就重新整理了一下 Flexbox 的筆記。
Flexbox 概述
Flexbox 全稱為 CSS Flexible Box Layout,也就是 CSS 彈性盒子佈局。是一種新的 CSS3 佈局模式,在彈性盒子佈局中,彈性容器的子項目們可以伸展到任何方向、並讓他們的尺寸更加「彈性」、或者持續增大,以填補未使用的空間,抑或縮小,以避免父元素溢出。子元素的橫向或縱向對齊都很容易操作。
1. 為何流行?
為何開始流行了呢?最主要也是因為 CSS3 的規範終於普及,加上行動裝置的發展促成了響應式佈局興起,自適應長寬彈性相當大的 Flexbox 就趁勢而起了。
- 非常適合單向排版,例如導覽列、Gird-Layout
- 許多 CSS 框架也使用(Bootstrap、Foundation 等)
跟毒品一樣,用過就回不去了。
2. 瀏覽器的支援
瀏覽器支援高達 97%。

3. Flexbox 規格歷史
- 2009 年的版本:
display: box現在已經不再跟 Flexbox 有任何關係。 - 2011 過渡期版本:
display: flexbox只是草稿,只被 IE10 實作, 如果可能的話應該避免使用。 - 2012 最終版:
display: flex
模型概念
容器與項目:
- 彈性容器(Flex container)
將元素的display屬性設為flex或inline-flex,就會變彈性容器。 - 彈性項目(Flex item)
所有彈性容器的子元素都會變成彈性項目,包含文字。
彈性容器具有主軸與交錯軸:
- 主軸(main axis)
- 交錯軸(cross axis)
方向:
- 主軸起點與終點(main start/main end)
- 交錯軸點與終點(cross start/cross end)
彈性項目具有:
- 水平尺寸與垂直尺寸(main size、cross size)
屬性介紹
Flexbox 可分成外層元素(彈性容器)與內層元素(彈性項目)。
外容器屬性:
display:flex、inline-flex,啟用 Flexbox 的必備屬性flex-flowflex-direction:決定主軸線的方向flex-wrap:決定是否換行
justify-content:主軸線的對齊align-items:交錯軸的對齊align-content:整體的對齊
內層元素屬性:
align-self:單一個物件的交錯軸對齊order:排序flexflex-grow:伸展比,其數值與其它物件可分配伸展比有關flex-shrink:收縮比flex-basis:絕對值
1. Emmet 速寫格式
Flexbox 相關屬性的 Emmet 速寫格式:
display
d:f:display:flex;d:if:display:inline-flex;
flex-direction
fxd:flex-direction:;fxd:c:flex-direction:column;fxd:cr:flex-direction:column-reverse;fxd:r:flex-direction:row;fxd:rr:flex-direction:row-reverse;
justify-content
jc:justify-content:;jc:c:justify-content:center;jc:fe:justify-content:flex-end;jc:fs:justify-content:flex-start;jc:sa:justify-content:space-around;jc:sb:justify-content:space-between;
flex-wrap
fxw:flex-wrap: ;fxw:n:flex-wrap:nowrap;fxw:w:flex-wrap:wrap;fxw:wr:flex-wrap:wrap-reverse;
align-items
ai:align-items:;ai:b:align-items:baseline;ai:c:align-items:center;ai:fe:align-items:flex-end;ai:fs:align-items:flex-start;ai:s:align-items:stretch;
align-content
ac:align-content:;ac:c:align-content:center;ac:fe:align-content:flex-end;ac:fs:align-content:flex-start;ac:s:align-content:stretch;ac:sa:align-content:space-around;ac:sb:align-content:space-between;
align-self
as:align-self:;as:a:align-self:auto;as:b:align-self:baseline;as:c:align-self:center;as:fe:align-self:flex-end;as:fs:align-self:flex-start;as:s:align-self:stretch;
order
ord:order:;
flex
fx:flex:;fxb:flex-basis:;fxd:flex-direction:;fxd:c:flex-direction:column;fxd:cr:flex-direction:column-reverse;fxd:r:flex-direction:row;fxd:rr:flex-direction:row-reverse;fxf:flex-flow:;fxg:flex-grow:;fxsh:flex-shrink:;fxw:flex-wrap: ;fxw:n:flex-wrap:nowrap;fxw:w:flex-wrap:wrap;fxw:wr:flex-wrap:wrap-reverse;
外容器屬性
1. 必備屬性
使用 Flexbox 就是要將 display 設為 flex 或 inline-block。
display: flex其布局方式與block一樣,都會強迫換行;- 而
inline-flex和inline-block也 一樣,在後方的元素不會換行。
唯一不同的是,flex 與 inline-flex 的子元素具備了更多彈性的設定。
|
|
|
|
2. 主軸方向
flex-direction 可以決定主軸的方向,主軸的方向將會影響容器內的元素排序順序、方向。
flex-direction 設定值共有以下四種:
row:預設值,由左到右,從上到下row-reverse:與row相反column:從上到下,再由左到右column-reverse:與column相反
|
|
|
|
3. 主軸對齊
justify-content 決定了內容元素與整個 Flexbox 的「主軸對齊」位置,設定值共有以下五種:
flex-start:預設值,對齊主軸線最前端flex-end:對齊主軸線最終端center:對齊主軸線中央space-between:平均分配寬度,第一項和最後一項貼齊邊緣space-around:平均分配寬度、間距
|
|
|
|
4. 交錯軸對齊
align-items 剛好和 justify-content 相反,align-items 決定了內容元素與整個 Flexbox 的「交錯軸對齊」位置,設定值總共有下列五個:
stretch:預設值,如果子元素height: auto,會將撐開至父元素的高度flex-start:對齊交錯軸線最前端flex-end:對齊交錯軸線最末端center:對齊交錯軸線中央baseline:對齊子元素的基線
|
|
|
|
5. 換行
當我們把父容器的 display 設定為 flex 或 inline-flex 的時候,子元素就是以單行的方式排列,因為預設不會行,因此當遇到邊界會彈性調整元素。
flex-wrap 可以調整元素是否換行,共有三個設定值:
nowrap:預設值,不斷行wrap:多行wrap-reverse:多行,但主軸線起點與終點相反
|
|
|
|
6. 多行交錯軸對齊
align-items 是針對內容為單行的子元素進行處理,如果遇到多行的子元素(flex-wrap: wrap),就要使用 align-content 這個屬性,這個屬性總共有六個設定值:
stretch:預設值,會平均分配行距,height: auto會撐開填滿整行。flex-start:對齊交錯軸線最前端flex-end:對齊交錯軸線最末端center:對齊交錯軸線中央space-between:第一行與最後一行分別對齊交錯軸線最上方與最下方space-around:平均分配行距,兩端會有行距一半的間距
|
|
|
|
內層元素屬性
1. 交錯軸位置
align-self 作用於內層容器,也就是子元素本身,會覆蓋外層容器的 align-items。
設定值與 align-items 相同:
stretch:預設值,如果子元素height: auto,會將撐開至父元素的高度flex-start:對齊交錯軸線最前端flex-end:對齊交錯軸線最末端center:對齊交錯軸線中央baseline:對齊子元素的基線
|
|
|
|
2. 排序
order 屬性可以直接指定一個數字,就可以由小到大的排列順序。
- 預設值為
0,只給一個元素設置會跑到最後面 - 要設置到最前頭,可以設值負值
- 相同的數字,看元素排序
注意,order 僅僅對元素的視覺順序 (visual order) 產生作用,並不會影響元素的邏輯或順序。
|
|
|
|
3. 伸縮比
FlexBox 最重要的屬性「flex」,個別調整子元素長度「伸展」、「壓縮」的比例以及基本大小。
flex 是簡寫,裡面依序包含三個屬性:
flex-grow:預設值為0,負值無效flex-shrink:預設值為1,負值無效flex-basis:預設值為auto,若值為0,則必須加上單位,以免被視作伸縮性
|
|
三個屬性可以分開設定,也可以合在一起用一個 flex 統一設定。
3.1 伸展比 flex-grow
元素的伸展性,是一個數值,當子元素的寬度「小」於它自己在父元素分配到的寬度,按照數字做相對應的「伸展」比例分配(剩餘空間)。
預設值為 0,不會進行彈性變化,不可為負值,設為 1 則會進行彈性變化。
3.2 壓縮比 flex-shrink
元素收縮性,是一個數值,當子元素的寬度「大」於它自己在父元素分配到的寬度時,會進行壓縮。
預設值為 1,設為 0 的話不會進行彈性變化(全部都 0 可能超出邊界),不可為負值。
3.3 基本大小 flex-basis
flex-basis 為子元素的基本大小,作為父容器的大小比較基準,預設值為 auto。
在分配空間之前,子元素會依 flex-basis 或者 width/height,預約空間,剩餘空間會依 flex-grow 分配。
主軸方向 flex-direction:
- 水平
row:flex-basis為width的替代 - 垂直
column:flex-basis為height的替代
優先級:
- 如果同時設置,那麼
width/height會被覆蓋(flex-basis的優先級較高); - 其中有一個是
auto,那麼另外一個非auto的屬性優先級會更高。
一些常見問題
一些新手使用 FlexBox,沒注意到的問題。
1. 子元素高度被強制拉伸對齊
常見的情況是,當子元素 col 內,放置不同高度的元素 box,每個子元素 col 都會被強制拉伸對齊。
|
|
|
|
這是因為 align-items 預設 stretch。因此可以透過改變 align-items 的值解決,或是使用 align-self 個別調整。
2. 元素被壓縮
我們都知道 FlexBox 預設不換行,因此當容器大小不足時,各個子元素會被壓縮。會被壓縮的原因是 flex-shrink 預設為 1。
所以如果不希望元素被壓縮,可以將 flex-shrink 設為 0。
|
|
