CSS - Flex
Flex 可以自由地達成多欄式排版,多欄中可以各自設定自己的位置布局,或是依據某種模式平均分配位置,每一欄的空間可擴張也可縮減,會隨著畫面大小響應式的自動調整,以往比較難處理的"區塊垂直置中"都可以輕鬆做到喔!
主容器 (Flex Container) 與子層元素 (Flex Item)
開始使用 Flex 之前,要先了解它的組成結構,由一個外層的主容器及其內一個以上的子元素所組成,才能形成一個 Flex 物件。 主容器的掌控性會比較強,可以想成是對整體的操縱布局,子層元素的話當然就是針對自身做調整囉!
Flex 定位的標準會依據**主軸(main axis)及交錯軸(cross axis)**而定,首先來看看 MDN 提供的圖解:
黃底的區塊是 flex container,其內部的三個藍色區塊就是它的 flex item,預設情況下,橫向軸會是主軸,縱向軸是交錯軸,但兩者之間是可以互換的,互換的依據在於排版呈現要以橫式 (row) 還是直式 (column) 顯示。軸線本身有分起始處 (axis start) 及結尾處 (axis end) ,這兩處也是可以互相調換的,這也是 Flex 可以這麼彈性調整位置的關鍵之一。
For 主容器使用的屬性:
顯示屬性
display: flex;
表示該區塊的 display 方式要使用 Flex,因此其內部的元素就會被當作是 Flex item 囉!
axis 相關屬性
flex-direction: row | row-reverse | column | column-reverse;
設定主要的排版呈現方式- row: 預設值,子層元素由左到右排列(橫式)
- row-reverse: 子層元素由右到左排列(起始與結尾處互換了)
- column: 子層元素由上而下排列(直式)
- column-reverse: 子層元素由下而上排列
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: flex-start | flex-end | center | strecth | baseline;
設定交錯軸方向的對齊- flex-start: 對齊交錯軸起始處
- flex-end: 對齊交錯軸結尾處
- center: 對齊交錯軸中間
- strecth: 預設值,子層元素在交錯軸的方向延伸與主容器同高度
- baseline: 以子層元素的文字基線為標準對齊
wrap 相關屬性
wrap 設定跟 flex item 排版的行數有關,預設模式是 nowrap 的情況下,如果子層元素寬度設死或是內容超過容器的寬度,就會出現破版的狀況。如果有設定要 wrap,則原本超出容器的範圍會自動往下一行擺放,變成多行的排列。於是乎就會有 wrap 的屬性設定以及多行排列的方式設定囉!
flex-wrap: nowrap | wrap | wrap-reverse;
設定子層元素超過容器大小是否要換行排列- nowrap: 預設值,不換行
- wrap: 子層元素超過容器寬度會換行
- wrap-reverse: 會換行,且上下行及對齊位置都顛倒
align-content: flex-start | flex-end | center | space-between | space-around | stretch;
每一行 flex line 與交錯軸的對齊設定- flex-start: 對齊交錯軸起始處
- flex-end: 對齊交錯軸結尾處
- center: 對齊交錯軸中間
- space-between: 兩邊的 flex line 會貼齊起始處及結尾處,中間剩餘的 flex line 會平均分配空間
- space-around: flex line 周圍留下的距離平均分配空間
- strecth: 預設值,flex line 的 item 在交錯軸的方向延伸與主容器同高度
flex-direction 與 flex-wrap 的 shorthand
flex-flow
就是一個方便一次設定 direction 及 wrap 的屬性,寫法會像這樣:flex-flow: row wrap;
For 子層元素使用的屬性:
子層元素在父容器空間中的彈性調整相關屬性
flex-grow: 0 | 正整數 ;
設定 flex item 可以分配到剩餘空間的比例,預設值為 0,表示不會因為父容器中還有剩餘空間就變大,如果有設定 0 之外的正整數數值,就會依照該值的比例去分配空間。 比例計算方式: 自身設定的比例/全部元素設定的比例總數*剩餘空間大小
上圖第三個例子分別設定 flex item 有不同的 flex-grow 比例,可看出 item 3 因為設定 0 所以大小不會變,而 item 1 與 item 2 則將剩餘的空間依照 2:1 的比例分別加到自己身上。
flex-shrink: 0 | 正整數 ;
設定 flex item 超出父容器時要不要自行瘦身,預設值為 1,表示有超出父容器空間的話,自己的大小會依照比例縮減。如果設定為 0 就不會自行縮減喔!也可設定其他正整數,原理同 flex-grow 一樣,會將原本超出的空間大小,依據子層元素全部的比例總數以及自身的比例決定各自縮減的量。
上圖第三個例子分別設定 flex item 有不同的 flex-shrink 比例,可看出 item 3 因為設定 0 所以大小不會變,而 item 1 與 item 2 則依照超出空間的 2:1 比例分別縮減自己。
flex-basic: auto | 一般寬高設定單位 ;
設定 flex item 的"基本大小",預設值為 auto,大小針對寬或高會根據父容器的主軸方向為何, 主軸為 row 的話是寬度, column 則是高度。該屬性可以當成是針對 flex 物件的寬高設定,因為當父容器是 display: flex 時,子層元素的 flex-basic 權重就會比原本的 width / height 屬性還高!建議元素為 flex-item 時都使用 flex-basic 這個屬性來設定寬高,可以省略額外修改 width / height 的功夫。
flex: 0 | 1 | auto ;
flex-grow、flex-shrink 及 flex-basic 的 shorthand,設定有先後順序之差喔!
子層元素自身的對齊方式
可以改變各個子層元素在容器中的排列方式。
align-self: auto | flex-start | flex-end | center | strecth | baseline;
設定子層各自針對交錯軸方向的對齊- auto: 預設值,會跟隨父層設定
- flex-start: 對齊交錯軸起始處
- flex-end: 對齊交錯軸結尾處
- center: 對齊交錯軸中間
- baseline: 以文字基線為標準對齊
- strecth: 在交錯軸的方向延伸與主容器同高度
子層元素的排序
非常方便的功能,尤其版面要因應 RWD 調整時靠它很輕鬆就可以改變元素的排序位置!
order: 0 | Number ;
預設值是 0,都沒有特地設值或 item 之間數值相同的話會依據 html 正常的流動順序排列,如果每個 item 的 order 值都不同時就會改變元素之間的順序位置喔! order 可以設定負值,總之數值越小排列越前面,數值越大就反之。
與 flex 的神搭配 - margin
雖然 flex 提供很多對齊方式,不過這些對齊通常是在某種"定律"之下,可能彼此距離相等或者周圍的邊距相等之類的,如果想排出其中一欄離大家很遠,或是彼此之間距離不一的版型,其實可以依靠margin這個屬性來幫忙。雖然元素變成 flex 性質的物件,但依然保有 box-model 的特性喔!所以一般 margin 使用方式用在它身上也是可以通的。其中特別的是,如果元素設定成 margin-[left/right]:auto;
的話,該元素就會往反方向推擠直到父容器邊距。