CSS | 所以我說那個版能不能好切一點? - Flex 基本用法

神Q超人
Enjoy life enjoy coding
8 min readApr 16, 2019
Photo by Zbynek Burival on Unsplash

前言

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-directionrow 那次軸就是直向的 column ,這個觀念下方會一直用到,要記得!

justify-content

justify-content 預設為 flex-start ,這個屬性可以用來配至主軸的對齊方式,包含對齊資料流的起點、終點、置中等等:

justify-content: flex-start | flex-end | center

例如上方第一個例子被設定為 row-reverse ,資料從右流到左,因此當設定 flex-end 時, Flex 內的 item 會靠向資料流結束的那邊:

除了基本的 flex-startflex-endcenter 置中外,也還有平均分配空白區域的:

justify-content: space-around | space-between

兩者的分別是將空白區域給平分到每個 item 之間,或是在每個 item 的左右加上均分後的空隙,兩者的差別可以看下方:

flex-wrap

flex-wrap 在 Flex 可以用來控制是否換行,預設的值為 nowrap 不換行,這裡可以試著將上方的 item 寬度從 90px 改為 120px ,就會發現 Flex 會自動將 item 縮放至與父元素相等的寬度 300px ,並擠在同一行中,但如果在這個狀況下,另外指定 flex-wrapwrap 換行,那超過寬度的區塊就會自動被擠到下一行了:

除了換行外,也能夠另外發現 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 演示程式碼,文章看起來也更方便,或是有其他建議也可以指教一下!

最後,如果上方的例子或講解有任何問題,再麻煩留言告訴我!我會盡快修改或回覆的!謝謝大家!

參考文章

  1. https://www.youtube.com/watch?v=_nCBQ6AIzDU

--

--