這週是 六角鼠年鐵人賽 第三週,不知道要寫啥,就重新整理了一下 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-flow
flex-direction
:決定主軸線的方向flex-wrap
:決定是否換行
justify-content
:主軸線的對齊align-items
:交錯軸的對齊align-content
:整體的對齊
內層元素屬性:
align-self
:單一個物件的交錯軸對齊order
:排序flex
flex-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
。
|
|