CSS | 所以我說那個版能不能好切一點? - Flex 基本用法
前言
Flex 在 CSS 中算是一個劃時代的排版方式,和它同期的還有另外一個 Grid ,兩個都可以用非常簡單的設定就能做到 Float 能做的,甚至比 Float 更多,也不會有類似 Float 造成父元素高度塌陷的問題,不過這篇文章並不是要來比較的,而是讓大家更了解在考慮排版時,工具箱內有多少武器 😃 !
Flex
Flex 是 display
中新增的配置之一,能夠對被設定為 Flex 區塊內的內容做排版,在 Flex 之中,不論是垂直或水平的對齊、排列、順序甚至是大小都可以簡單完成,下方先簡單介紹一些關於 Flex 屬性:
flex-direction
這裡筆者很喜歡 Amos 的影片提到的解說方式:
與其把
flex-direction
當作是資料的排列方式,更不如說是資料的流向。
針對不同的設定 flex-direction
能讓資料從左往右放,也能由右往左,或是在直向排列下也能控制是要從上到下或從下到上:
flex-direction: row | row-reverse | column | column-reverse
而不論是那種配置,只要是放完資料結束的那一邊,就是資料流向的終點。例如下方為 flex-direction
設定為 row-reverse
,那資料流就是從右至左,右邊為起點,左邊為終點,而因為資料流從右邊開始放資料,所以看起來會像靠右對齊:
這時候也可以發現,使用 row
橫向資料流的話,那在沒有為 item
設定高度的情況下 flex
內的 item
都會將高度填滿。
換個情況說,將 flex-direction
設置為 column
,資料流就會由上至下,若是 column-reverse
則是由下至上,且將 item
的寬度設定刪去,那 item
就會將寬度填滿:
從 flex-direction
可以得到一個使用 Flex 很重要的觀念:
在 Flex 中資料的流向稱之為主軸,而交叉軸為次軸
也就是說如果 flex-direction
為 row
那次軸就是直向的 column
,這個觀念下方會一直用到,要記得!
justify-content
justify-content
預設為 flex-start
,這個屬性可以用來配至主軸的對齊方式,包含對齊資料流的起點、終點、置中等等:
justify-content: flex-start | flex-end | center
例如上方第一個例子被設定為 row-reverse
,資料從右流到左,因此當設定 flex-end
時, Flex 內的 item
會靠向資料流結束的那邊:
除了基本的 flex-start
、 flex-end
和 center
置中外,也還有平均分配空白區域的:
justify-content: space-around | space-between
兩者的分別是將空白區域給平分到每個 item
之間,或是在每個 item
的左右加上均分後的空隙,兩者的差別可以看下方:
flex-wrap
flex-wrap
在 Flex 可以用來控制是否換行,預設的值為 nowrap
不換行,這裡可以試著將上方的 item
寬度從 90px
改為 120px
,就會發現 Flex 會自動將 item
縮放至與父元素相等的寬度 300px
,並擠在同一行中,但如果在這個狀況下,另外指定 flex-wrap
為 wrap
換行,那超過寬度的區塊就會自動被擠到下一行了:
除了換行外,也能夠另外發現 item
的次軸尺寸也被自動縮放了一半,但有時候並不需要 Flex 自動依父元素調整次軸尺寸去對齊,而是根據內文自動縮放次軸尺寸,這時候就能考慮使用 align-items
。
align-items
align-items
可以用來調整次軸的對齊方式,配置的值和 justify-content
相似:
align-items: flex-start | center | flex-end
能夠替次軸對齊設定 center
的 Flex ,讓垂直置中不再是一件擾人的事情:
接下來要介紹的是 align-items
的另外兩個屬性:
align-items: stretch | baseline
首先將外層 Flex Box 的 height
給刪去,並在 item
中添加 margin: 5px
,讓 Flex Box 能夠直接被 item
的內容撐開:
設定為 stretch
會靠上對齊並讓每一個區塊的次軸尺寸都相同,而另一個 baseline
的對齊方式則是以基準線為準,因此將紅色區塊的字體調大,可以發現它和藍色區塊的第一行底線是對齊的,而區塊的次軸尺寸則是以內容為主。
align-content
align-content
實際運用起來也像是次軸的對齊,但它更像是對 Flex Box 中空白空間的應用,而 align-items
較接近是以區塊內容做對齊,例如在 align-content
中也擁有靠上、置中、靠下:
align-content: flex-start | center | flex-end
除此之外還多了對 space
空間的分配運用:
align-content: space-around | space-between
既然要展示對空白空間的運用,那得先將 Flex Box 的 Height
給調大才看得出差別,如果以 margin: 5px
將 Flex Box 撐開,就不會有空白空間了,以下調整 height
後使用 align-content
:
上方的屬性都是設定在 Flex Box 上,調整所有內容區塊,但除此之外, Flex 也有針對單一內容設定他的對齊方式和順序,下方會為各位介紹。
align-self
align-self
可以為單一內容物做次軸的排序,它能夠配置的值和 align-items
相同:
align-self: flex-start | center | flex-end | stretch | baseline
下方例子將 align-self
設定在 A 身上,可以發現只有 A 的對齊方式與其餘的不同:
上方第二個區塊將 align-items
設定為 flex-start
這樣才看得出 A 被置中了。
order
接著從對齊再講回資料的流向, order
能夠為指定的區塊設定資料的順序, order
的原理是所有區塊在 Flex Box 中都是預設 0 ,而當 order
的數字越小,代表順序會更接近在開始的那一端,而數字越大則是排在越靠近結束的那端,下方使用 order
將第一個例子的順序打亂:
如同上述所說 order
越小,順序就會越接近資料流的開始那端,因此在第一個例子中, order
最小的 B 在 flex-direction:row-reverse
的狀態下順序為第一個,接著是 order
為 1 的 A 和 0 的 C 。
flex-grow & flex-shrink
在上方的例子中有稍微提到, Flex Box 內的區塊寬度超過的部分會自動被縮成與 Flex Box 的容器等大,這是 Flex 中的「縮」,也是 flex-shrink
,除了縮以外還有「伸」,當在 Flex Box 內還有剩餘空間時,內部的區塊能夠依照比例將空白的部分填滿,這個「伸」為 flex-grow
。
下方先展示 flex-shrink
的部分:
flex-shrink
縮的算法是,如上方整個 Flex Box 的寬度是 300 ,但每個 item
的寬度卻有 150 ,整整比 Flex Box 多了 (150*3)–300=150 ,而 Flex Box 內的三個區塊 flex-shrink
分別是 1 、 3 、 6 ,總和為 10 , 也就是說 A 的 flex-shrink
佔比例中的 1/10 因此被扣除的寬度為 150 * 1/10 也就是 15,因此 A 的尺寸就變成 150–30=135 , C 的尺寸就是 150-((6/1+3+6)*150) =60。
緊接著 flex-grow
是填滿的比例,一樣可以先看一下下方的例子:
在例子中每個區塊的寬度都是 50 ,但 Flex Box 的區塊為 300 ,也就是還有 300–(50*3)=150 的補份需要被填滿,而上方三個區塊的 flex-grow
分別為 1 、 3 、 6 ,因此 A 的長度就是原有寬度 50 加上被伸尺寸150*(1/1+3+6) 結果為 65, C 的話則是 50+150*(6/1+3+6) 為 90。
本文介紹了關於 Flex 的所有配置及呈現效果,話說終於把 jsfiddle 的嵌入搞定,能夠直接看到程式碼及結果,這樣就不必再另外搭配 Gist 演示程式碼,文章看起來也更方便,或是有其他建議也可以指教一下!
最後,如果上方的例子或講解有任何問題,再麻煩留言告訴我!我會盡快修改或回覆的!謝謝大家!
參考文章