[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


<<:  Day 04:专案01 - 超简单个人履历03 | CSS简介

>>:  Day.1 前言

Day01-CRUD API 实作(一)事前规划、Laravel Sanctum 安装与设定

大家好~ 第一天先来规划我们的主题和预计会有哪些功能吧! 主题的话, 我决定做个留言板, 会有留言的...

[从0到1] C#小乳牛 练成基础程序逻辑 Day 3 - Hello World

打Code打Call | 主控台App | Hello World 🐄点此填写今日份随堂测验 ...

裁切,调整大小,旋转

提取ROI 在影像处理中是一个重要技能 像是在行人中要做人脸辨识 就必须找出人脸的位置座标 roi ...

JS 物件与纯值 DAY 58

物件与纯值 var family = {}; family.name = '皮杰先生'; conso...

Kotlin Android 第29天,从 0 到 ML - TensorFlow Lite - 艺术风格转换(Style Transfer)

前言: (维基)神经风格迁移( NST ) 是指一类软件算法,它们操纵数字图像或视频,以采用另一幅图...