iT邦幫忙

2021 iThome 鐵人賽

DAY 4
1
Modern Web

CSS Flex/Grid Layout Modules系列 第 4

[CSS] Flex/Grid Layout Modules, part 4

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 元件直接換行。

https://ithelp.ithome.com.tw/upload/images/20210907/2000143374WV4bUz7G.png

當你在設計 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-contentjustify-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;
    }
}

https://ithelp.ithome.com.tw/upload/images/20210907/200014330qxo5t2lPl.png

對於 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 被這樣一搞炸鍋了,

https://ithelp.ithome.com.tw/upload/images/20210907/20001433LeyZBvp4Ya.png

迫於無奈只能繼續調整 .main 的設定,

.main {
    flex-shrink: 1;
    width: calc(100% - 200px);
    max-width: 80%;
}

https://ithelp.ithome.com.tw/upload/images/20210907/20001433JZpu6lF3l1.png

到最後發現內文流向也出了問題,

https://ithelp.ithome.com.tw/upload/images/20210907/20001433nbtPHGnJYe.png

然後我們就得將文字中斷,大概可以這樣設定,

.main {
    flex-shrink: 1;
    width: calc(100% - 200px);
    max-width: 80%;
    work-break: break-all;
}

關於文字斷行的部分有很多種方式,這裡的例子或許不是最好,但僅提供大家做一個參考。

對於 Flexbox 的排版(Grid 也一樣)來說,尺寸是一個比較麻煩,且很容易造成跟最初視覺設計不符合的地方。所以在決定切版斷點時,必須仔細跟設計師協調畫面呈現的方式才行。


關於 column 方向

通常這件事情被討論的機會比較低,加上對於行動裝置來說,由上往下排列也是一種既定的作法,所以對於 column 這個方向,多數不會特別去著墨,就僅僅是換一個方向而已。這邊我們暫時不討論直書系統的呈現方式,以比較普及的由左到右、由上到下的方向來看。

請記得主要軸、交叉軸會交換,然後所應用的樣式方向會跟著主要軸交換這件事情。

對於普遍的裝置來說,今天無論是行動裝置還是電腦(泛指桌機、筆電爾等),由於垂直方向變為主要軸,所以你的 主要軸 方向並沒有「主要軸尺寸」,你的裝置尺寸這個時候變成了「交叉軸尺寸」了。

所以這個地方你就必須留意一些狀況,

  1. 主要軸沒有尺寸,所以並不會產生斷行。
  2. 主要軸方向對齊也由於無高度,並不會有預期效果。
  3. 如果有使用填充(stretch),則交叉軸會出現填充樣式。
  4. 在 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 1


部落格同步放送:
[CSS] Flex/Grid Layout Modules, part 4


上一篇
[CSS] Flex/Grid Layout Modules, part 3
下一篇
[CSS] Flex/Grid Layout Modules, part 5
系列文
CSS Flex/Grid Layout Modules16
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言