這篇將介紹 flex 屬性,並且深入探討 flex 究竟是如何計算伸縮的比例。
名詞介紹
若要理解 flex 是如何計算伸縮比例,首先需要了解一下 positive free space 與 negative free space 這兩個名詞。
positive free space
若 flex items
在主軸(main axis)
方向上的尺寸總和小於
flex container
的尺寸,此時會出現 flex container 的空間沒有被填滿,這些剩餘空間就稱為 positive free space
。
例如,在主軸(main axis)為 row 下,若 flex container 的寬度為 500px,而 a、b、c 三個 flex items 寬度各為 100px,此時 flex container 還有 200px 的 positive free space。
negative free space
若 flex items
在主軸(main axis)
方向上的尺寸總和大於
flex container
的尺寸,此時 flex container 的空間不夠用,而 flex items 的尺寸總和與 flex container 尺寸的差額
就稱為 negative free space
。
例如,在主軸(main axis)為 row 下,若 flex container 的寬度為 500px,而 a、b、c 三個 flex items 寬度各為 200px,此時 flex container 的寬度 500px 小於 flex items 的寬度總和 600px,negative free space 為 600px 減 500px,等於 100px。
flex 屬性
圖片來源:W3C
1 | flex: flex-grow | flex-shrink | flex-basis; |
-
為三個屬性
flex-grow
、flex-shrink
與flex-basis
的縮寫。- flex-grow: 決定
flex item
將得到
多少比例
的positive free space
。 - flex-shrink: 決定
flex item
將得到
多少比例
的negative free space
。 - flex-basis: 決定
flex item
在尚未 grow 與 shrink 前的原始尺寸
。
- flex-grow: 決定
-
預設值為
flex: 0 1 auto
flex-grow
- 以
flex-basis
為基礎,決定positive free space
的分配比例
,所以有 positive free space 才有作用。- 必須為
≥ 0
的值。 - 若為
0
(預設值
),則不會延伸
。
- 必須為
計算方式
在 flex-direction: row 下,有一個寬度為 500px 的 flex container,與三個寬度各為 100px、80px、70px 的 flex items,則在預設下會有 500px - 250px = 250px 的 positive free space 。
1 |
|
1 | .container { |
現在將三個 flex items 的 flex-grow
分別設定為 1
、2
、2
。
- item1 將分配到 1/(1+2+2) =
1/5
的 positive free space。最終寬度為 150px。 - item2 將分配到 2/(1+2+2) =
2/5
的 positive free space。最終寬度為 180px。 - item3 將分配到 2/(1+2+2) =
2/5
的 positive free space。最終寬度為 170px。
1 | .item1 { |
flex-shrink
-
以
flex-basis
為基礎,決定negative free space
的分配比例
,所以有 negative free space 才有作用。- 必須為
≥ 0
的值。 - 若為
0
,則不會
收縮,此時若 container 空間不夠,會發生overflow
。 預設值
為1
。
- 必須為
-
flex items
不會
縮短至小於
min-content
的尺寸,除非設定 min-width 或 min-height 屬性。
計算方式
flex container 寬度為 500px,其三個 flex items 寬度各為 200px,故此時有 100px 的 negative free space,若將所有 flex items 的 flex-shrink 皆設定為 0,則將發生 overflow。
1 | <div class="container"> |
1 | .container { |
現在將第一個與第二個 flex item 的 flex-shrink
分別設定為 1
與 4
,第三個 flex item 的 flex-shrink 依然為 0
。
注意,shrink 與 grow 的計算方法並不相同,公式可參考 前端新手村 flex grow & shrink 演算法。
negative free space = 500px - 200 *3 = -100px
-
item 1 將分配到
1/5
的 negative free space,所以最後寬度為 180px。算法: 1 * 200/(1 * 200 + 4 * 200 + 0 * 200)= 1/5
-
item 2 將分配到
4/5
的 negative free space,所以最後寬度為 120px。算法: 4 * 200/(1 * 200 + 4 * 200 + 0 * 200)= 4/5
-
item 3 將分配到
0/5
的 negative free space,所以最後寬度為 200px。算法: 0 * 200/(1 * 200 + 4 * 200 + 0 * 200)= 0
1 | .item1 { |
flex-basis
-
決定 flex item 在尚未 grow 或 shrink 前的
原始尺寸
。 -
預設值
為auto
。- 若
有
指定尺寸 width、height (視主軸 main axis 而定),則依照所指定的尺寸
。 - 若
無
指定尺寸 width、height (視主軸 main axis 而定),則由其內容大小
決定。
- 若
-
若為
0
,則 flex item不被納入空間計算
。例如有一個 container 寬度 400px,裡面有 item1 與 item2,寬度各為 200px,此時 flex-basis 為預設的 auto,故沒有剩餘空間。但若將 item2 的 flex-basis 設為 0,則會有 200px 的剩餘空間,原因是 flex-basis 優先級高於 width 與 height。 -
除了 auto 之外,尚有 content、max-content、min-content 等屬性值,不過多數瀏覽器不支援。
-
可給定
有單位
的數值
,例如 100px 或 10%,若同時
設定flex-basis (非 auto)
和尺寸
(width 或 height,視主軸 main axis 而定),則以flex-basis
為優先
。
例如:
有三個 flex items,指定第一個 flex item 的 width 為 200px,
在 flex-direction: row 且 flex-grow 與 flex-shrink 皆為 0 的前提下,設定 flex-basis 值為 auto,此時
- 第一個 flex item 的寬度為 200px。
- 第二與第三個 flex item 的寬度為其內容尺寸。
1 | <div class="container"> |
1 | div { |
flex 屬性另類寫法
flex 屬性除了直接給定 flex-grow、flex-shrink、flex-basis 三個值之外,還有以下幾種寫法。
- flex:
initial
- flex:
auto
- flex:
none
- flex:
<正數>
註:<正數> 可不必為整數,例如可為 0.5。
以下分別說明這四種屬性值的意義。
flex: initial
1 | flex: initial; |
等同於
1 | flex: 0 1 auto; |
flex item 會依照 width 或 height (視主軸 main axis 而定)屬性決定其尺寸,即使 container 中有剩餘空間
,flex item 仍無法延伸
,但當空間不足
時,元素可收縮
。
flex: auto
1 | flex: auto; |
等同於
1 | flex: 1 1 auto; |
flex item 可延伸
與收縮
,會依照 width 或 height (視主軸 main axis 而定)屬性決定其尺寸。若所有 flex items 均設定 flex: auto 或 flex: none,則在 flex items 尺寸決定後,剩餘空間會被平分給 flex: auto 的 flex items。
flex: none
1 | flex: none; |
等同於
1 | flex: 0 0 auto; |
flex item 不可延伸
與收縮
,會依照 width 或 height (視主軸 main axis 而定)屬性決定其尺寸。
flex: positive-number
1 | flex: <正數>; |
等同於
1 | flex: <正數> 1 0; |
flex item 可延伸
與收縮
,flex-basis 為 0
,故 flex item 會依據所設定的比例佔用 container 中的剩餘空間。
例如
1 | flex: 2; |
等同於
1 | flex: 2 1 0; |
可利用此種屬性值的指定方式,輕易地決定 flex items
在 flex container
中所佔的尺寸比例
(width 或 height,視主軸 main axis 而定)。
例如,一個 flex container 裡面有三個 flex items,希望不管 container 如何變化,這三個 items 的尺寸皆一樣大
,則可設定每個 items 的 flex 屬性有相同的正數(positive-number)。
1 | <div class="container"> |
1 | .container { |
註:只要是相同正數
即可,其僅代表比例
關係。
且不論容器如何變動(例如縮放視窗時),比例皆為 1 : 1 : 1
。
同理,若希望這三個 flex items 的尺寸比例分別為 3 : 2 : 1
,則可設定:
1 | .item1 { |
且不論容器如何變動(例如縮放視窗時),比例皆為 3 : 2 : 1
。
有關於 flex 屬性以及伸縮的計算方式就介紹到此,下一篇將繼續介紹 flex 的各種對齊方式。
參考資源