Media Query 已經快被講爛了。
我不確定現在是否還流行 RWD 這件事情,如果以 Core Web Vitals 來看,你可能會被建議減少未使用的 CSS,但是誰在乎誰痛苦。
我最近就挺痛苦的(倒)。
Flexbox 與 Media Query
前面講到了不少關於斷行、多行的問題,當我們準備面臨多裝置、多解析度的時候,這個問題又會浮上台面。畢竟以常用的 flex-direction: row
來說,你的裝置尺寸就直接與你的 Media Query 的斷點,與你的 viewport
有所關連。
這邊就先不講
viewport
了(誰在乎誰痛苦)。
我們直接來看幾個比較常用的斷點設計,以 Bootstrap(5.0.x) 為例,
Media Query | 最大尺寸(max-width ) |
---|---|
@media (min-width: 576px) |
540px |
@media (min-width: 768px) |
720px |
@media (min-width: 992px) |
960px |
@media (min-width: 1200px) |
1140px |
@media (min-width: 1400px) |
1320px |
也許你會覺得,斷點就這樣而已,跟我的 Flexbox 有什麼關係?有的,斷點設計最直接的影響就是容器的 剩餘空間 的計算。先前有提過剩餘空間的計算方式,現在在每一種 Media Query 的斷點限制下,每一個 階段 所呈現出來的剩餘空間都不同。
再者,如果 Flex 元件空間不足時,元件內的內容在沒有設定 overflow: hidden;
的情況下,就會超出你的 Flex 元件,同樣的道理,在 Flex 容器空間不足的情況下,就會發生兩種狀況,
- 在
flex-wrap: nowrap
的狀況下,Flex 元件(或其內容)超出容器。 - 在
flex-wrap: wrap
的狀況下,Flex 元件直接換行。
當你在設計 Media Query 斷點(這年頭還會有人手刻斷點嗎?)的時候,請留意你的容器與元件的尺寸設定,同時,你也必須留意內容是否會打破元件的尺寸。
依照 Bootstrap 那樣常見的斷點來說,我們在設計 Flex 容器,或者,我們在操作 Bootstrap Grid Layout 的時候,排版本身並不會特別去思考樣式的使用性。舉個例子來說,通常在 Bootsrtap 的起手式大概都是,
<div class="container">
<aside class="col col-sm-4 col-xl-2 my-aside">
<!-- 我是側邊欄位 -->
</aside>
<main class="col col-sm-8 col-xl-10 my-main">
<!-- 我是主要區塊 -->
</main>
</div>
.my-aside {
order: 2;
}
.my-aside {
order: 1;
}
@media (min-width: 576px) {
.my-aside {
order: 1;
}
.my-aside {
order: 2;
}
}
然後就沒有然後了。在一般情況下,不會再針對你的排版區塊做上其他的樣式設定,一方面為了確保在 RWD 的情況下不會 跑版,另外也能避開 Media Query 覆寫地獄。
所謂的 覆寫地獄 就是,Bootstrap 用了 N 個 Media Query 斷點,你就要覆寫最多 N - 1 次的樣式。
再者,我們通常在製作行動裝置(俗稱手機版)的時候,多數以 flex-direction: column;
來編排,而切換到比較大尺寸的裝置(俗稱電腦版)的時候,則會視情況改以 flex-direction: row;
的方式來編排。
請留意,這兩個方向的主要軸、交叉軸是會交換方向的。
所以,請留意你的 align-items
, align-content
及 justify-content
的適用軸方向的狀況。當主要軸轉換的時候,請注意你的排版樣式也要適性調整才不會出意外。
舉例來說,
.flex-container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: flex-start;
}
@media screen and (min-width: 576px) {
.flex-container {
flex-flow: row wrap;
align-items: flex-start;
justify-content: center;
}
}
對於 Media Query 來說,其實不管對象是不是 Flexbox,你弄壞的地方他一樣會壞掉。所以之前所提到的尺寸、留白等議題,在這邊還是必須留意。當你有一些固定尺寸的內容(如圖片),在規劃排版的 RWD 時就需要計算空間是否夠用,是否產生斷點等狀況。
<div class="flex-container">
<aside class="flex-item sidebar">
<h2>Profile</h2>
<img class="logo" src="./logo.jpg" alt="Avatar">
</aside>
<main class="flex-item main">
</main>
</div>
.flex-container {
display: row;
flex-flow: column nowrap;
align-items: flex-start;
justify-content: flex-start;
}
.flex-item {
flex: 0 0 auto;
}
.sidebar {
width: 100%;
}
.main {
width: 100%;
}
.logo {
display: block;
width: 200px;
height: 200px;
}
@media screen and (min-width: 768px) {
.flex-container {
flex-flow: row nowrap;
}
.sidebar {
width: 20%;
}
.main {
width: 80%;
}
}
當遇到破版的時候,通常第一件事情會做的大概是這樣,
.logo {
display: block;
width: 100%;
max-width: 200px;
}
接下來客戶就來問說為何把他的視覺縮小了,然後就只能改回第一版,
.logo {
display: block;
width: 200px;
height: 200px;
}
接著開始面對整體排版的空間配置問題,只好針對 .sidebar
調整,
@media screen and (min-width: 768px) {
.sidebar {
width: 20%;
min-width: 200px;
}
}
果不其然隔壁棚的 .main
被這樣一搞炸鍋了,
迫於無奈只能繼續調整 .main
的設定,
.main {
flex-shrink: 1;
width: calc(100% - 200px);
max-width: 80%;
}
到最後發現內文流向也出了問題,
然後我們就得將文字中斷,大概可以這樣設定,
.main {
flex-shrink: 1;
width: calc(100% - 200px);
max-width: 80%;
work-break: break-all;
}
關於文字斷行的部分有很多種方式,這裡的例子或許不是最好,但僅提供大家做一個參考。
對於 Flexbox 的排版(Grid 也一樣)來說,尺寸是一個比較麻煩,且很容易造成跟最初視覺設計不符合的地方。所以在決定切版斷點時,必須仔細跟設計師協調畫面呈現的方式才行。
關於 column
方向
通常這件事情被討論的機會比較低,加上對於行動裝置來說,由上往下排列也是一種既定的作法,所以對於 column
這個方向,多數不會特別去著墨,就僅僅是換一個方向而已。這邊我們暫時不討論直書系統的呈現方式,以比較普及的由左到右、由上到下的方向來看。
請記得主要軸、交叉軸會交換,然後所應用的樣式方向會跟著主要軸交換這件事情。
對於普遍的裝置來說,今天無論是行動裝置還是電腦(泛指桌機、筆電爾等),由於垂直方向變為主要軸,所以你的 主要軸 方向並沒有「主要軸尺寸」,你的裝置尺寸這個時候變成了「交叉軸尺寸」了。
所以這個地方你就必須留意一些狀況,
- 主要軸沒有尺寸,所以並不會產生斷行。
- 主要軸方向對齊也由於無高度,並不會有預期效果。
- 如果有使用填充(stretch),則交叉軸會出現填充樣式。
- 在 Firefox 下,
break-*
系列樣式可操作斷行。
具體會產生什麼情況我就不贅述,特別是第 4 點,牽扯到的範圍有點超出本系列文章要討論的東西。有興趣的人可以參考我之前寫過的 瀑布流難題。
不過我還是發牢騷一下,關於 Regions Module Level 1 到現在就感覺是躺在那,說是說跟 Flexbox 有關,但實際上從 Flexbox 那裡也找不太到相關的資訊。至於說 CSS Multi-column Layout Module Level 1 就不提了,基本上跟 Flexbox 用的 Column 是兩回事。
對於行動裝置,或比較小尺寸的裝置(更甚是你的元件區塊中想要使用 column
)來說,你可以單純的把他想成 由上而下 的排列工具就好。
小記
無論你是要使用 RWD, AWD 還是什麼 WD,請多留意你的內容所造成的尺寸差異。無論用什麼方向來排列你的介面樣式,重點還是以內容呈現為主,說穿了 Flexbox 充其量就是工具而已,適切的使用才是上策。
目錄與小節:
[CSS] Flex/Grid Layout Modules, part 0