[CSS] Flex/Grid Layout Modules, part 10

来到了 30 天的三分之一,然後我才刚讲完网格容器而已,但是,剩下的东西也不多了,好像要写满 30 篇难度有点高。

只好多写一点废话了。


间隔、间隔、间隔

当兵有呼过拐拐的应该知道我在讲什麽。

这边的 gap 其实跟 Flexbox 其实是同一套,而且特性也一样。

Gaps Between Boxes
CSS Box Alignment Module Level 3

不要问我为什麽大家都跟 Box Alignment Module 有关。如果大家有耐心去看官方文件的话,会发现 Box Alignment Module 超级无敌霹雳长,几乎是囊括了所有跟对齐有关,跟对齐没有那麽相关,跟对齐几乎无关的东西(疑)。

例如 gap 我就不懂跟对齐有什麽关系?

基本上在 Grid 容器里面,间隔的写法跟 Flexbox 如出一辙,

.grid-container {
    display: grid;
    
    grid-template-columns: repeat(3, 1fr);
    grid-template-rows: repeat(3, 1fr);
    
    column-gap: 10px;
    row-gap: 10px;
}

https://ithelp.ithome.com.tw/upload/images/20210913/20001433sdL8dqgEBu.png

与 Flexbox 相同的地方是,间隔的尺寸并不会被压缩,且也是算在整个容器尺寸里面。所以,当你设定了容器尺寸的时候,请留意 gap 的尺寸是否会压缩到你的 Grid 单元,尔或是,你的 Grid 单元与 gap 的尺寸总和,是否能容纳在 Grid 容器内。

同样的状况,当你使用 repeat()auto-fillauto-fit 的时候,也会因为 gap 的尺寸设定,而导致你的每个栏或列能放入的数量不同。

我们快速的举几个例子给大家看看,

.grid-container {
    display: grid;
    
    grid-template-columns: repeat(3, 200px);
    grid-template-rows: repeat(3, 200px);
    
    column-gap: 10px;
    row-gap: 10px;
    
    width: 600px;
    height: 600px;
}

在这种时候,其实你的 Grid 容器真实尺寸是,

200px x 3 + 10px x 2 = 620px

而你将容器设定为 600px 时,基本上他还是会依照 Grid 的规范画出容器,但是容器本身会限制在 600px 的尺寸内,

https://ithelp.ithome.com.tw/upload/images/20210913/20001433E5essJH4La.png

当然,你也可以使用弹性尺寸设计来避开这件事情,但是,由於 gap 的绝对优势,所以你的 Grid 单元会被 压缩。压缩的方式跟分配 fr 的方式是雷同的,但这里的弹性尺寸总和需要扣除固定尺寸的限制,

Grid 单元尺寸 = <剩余空间> * <弹性尺寸> / <弹性尺寸总和(扣除固定尺寸的情况)>

剩余空间 = 容器总空间 - (若存在则扣除固定尺寸单元) - gap 尺寸

举例来说,

.grid-container {
    display: grid;
    
    grid-template-columns: minmax(200px, 1fr) 2fr 1fr;
    
    column-gap: 10px;
    
    width: 600px;
}

最终我们得到的後面两个尺寸就分别是,

  • 2fr 最终尺寸 (600 - 20) * 2 / 3 = 253.33px
  • 1fr 最终尺寸 (600 - 20) * 1 / 3 = 126.66px

为什麽?

因为上述的设定一定会触发 minmax() 并且将最小值锁定在 200px

另外针对 auto-fill, auto-fit 的例子,

.grid-container {
    display: grid;
    
    grid-template-columns: repeat(auto-fill, 100px);
    
    column-gap: 10px;
    
    width: 600px;
}

https://ithelp.ithome.com.tw/upload/images/20210913/20001433tbjOtUavq4.png

剩余空间不足 的情况下,就会少了一个间隔,根据 w3c 官方 Grid gutters 的定义,在 Grid 容器尺寸无法放入更多的 Grid 单元,所以对於隐性轨道来说,他是一个空轨道,等同於 上一个 轨道是这个容器的最後一个轨道,所以在这边的间隔并不会出现。

举体来说 auto-fill, auto-fit 间隔的出现,可以用以下的方式解释,

  • 剩余空间不足,不出现最後一个间隔
  • 剩余空间足够,出现最後一个间隔

同理 auto-fit 也是一样的状况,以下的例子是当 剩余空间足够 时,你的间隔就会出现,

https://ithelp.ithome.com.tw/upload/images/20210913/20001433KodKPqo3bG.png

另外,官方虽然是这样讲,但实际上浏览器(除了 Firefox)并没有这麽做,

When a collapsed track’s gutters collapse, they coincide exactly—the two gutters overlap so that their start and end edges coincide. If one side of a collapsed track does not have a gutter (e.g. if it is the first or last track of the implicit grid), then collapsing its gutters results in no gutter on either “side” of the collapsed track.

以下是 Webkit 渲染收合轨道时的情况,

https://ithelp.ithome.com.tw/upload/images/20210913/200014336EA7o1CBaN.png

以下是 Grcko 渲染收合轨道的情况,

https://ithelp.ithome.com.tw/upload/images/20210913/20001433jggjqLJ8wT.png

个人觉得这是一种 Grid Layout 的 Bug,截至目前为止(2021/09/15),只有 Firefox 渲染引擎 Gecko 是比较正常的结果,有兴趣的可以看这个小讨论,

[css-grid] Collapsed grid tracks and content distribution #1140

最後稍微介绍一下 gap 的相关设定方式,

样式 可用值 预设值
column-gap, row-gap normal 或长度单位或比例(%),不可为负值 normal
gap <'row-gap'> <'column-gap'>? 上述两者缩写,没有预设值

最後的对齐

这件事情其实也是属於 CSS Box Alignment Module 的部分,在 Flexbox 也通用,至於为何留到 Grid 才讲?因为我觉得这个东西在 Grid 雷的程度比 Flexbox 要精彩许多。

在我们定义对齐的时候,有一组关键字可以使用,叫做 safeunsafe,他是用来定义你的对齐是否在 安全的范围 内操作。

什麽叫做 安全的范围

我们先举个简单的例子,当我这样做的时候,你就会发现奇怪的现象,

.grid-container {
    display: grid;
    
    grid-auto-rows: 100px;
    
    align-items: center;
}

.grid-item:first-child {
    height: 200px;
}

https://ithelp.ithome.com.tw/upload/images/20210913/20001433JNVyCdu8Mz.png

这个现象在 逻辑上 是合理的,由於 align-items 的本意是对齐每个 Grid 单元,然後使用了 center垂直置中 这个 Grid 单元。所以,他出现了 超出 Grid 容器 的状况,根据逻辑定义上来说,他没有问题。

但是,视觉上来看就是所谓的 跑版

所以,就有了所谓的 溢位定位(overflow position 的设定,就是刚刚提到的关键字,

  • safe 倘若对齐元件超过(产生溢位)对齐容器,则该元件会采用 start 方式对齐
  • unsafe 不采取任何动作,使用原有设定做呈现,由渲染端自己决定

预设是 unsafe 啦。所以不要太崩溃,如果发生溢位状况的话,可能得先重新检视一下网格设计是否合理,你硬要用 safe 也不是不行,只要达成你的效果即可。


小记

今天一个小段落就大家轻松一点,目前来说大抵上把 Grid 容器的部分都交代的差不多了,接下来可以开始讲 Grid 单元,Grid 单元内巢状 Grid 容器之类的事情,然後又是无限对齐、留白、定位等问题(灿笑)。


目录与小节:
[CSS] Flex/Grid Layout Modules, part 1


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


<<:  Day 15 - LocalStorage and Event Delegation

>>:  Day 2 [Python ML] 基础资料处理

威胁建模-DREAD

-Stride、VAST、Trike 等:哪种威胁建模方法适合您的组织? 风险敞口是根据可能性、後...

Day22 - [丰收款] 以Django Web框架实作永丰API线上支付模拟情境(3) - 两种付款方式实作

昨天使用了Bootstrap5、Vue,打造了我们的付款流程入口页面後,今天要将之前的ATM虚拟帐户...

[Q&A] 06 风险评监报告生出来前的修修改改

资讯安全管理制度运行过程中,会对即有的企业或机构文化带来一定的冲击。 顾问有教过、学员有学过都是真的...

Day 20 : 笔记篇 07 — 在笔记的 Metadata 使用 [[内部连结]] ,在无形之中累积对某一主题的认识

前言 在上一篇文章中,我介绍了在 Obsidian 中实作 学习笔记整理流程 的方法。我将资讯来源分...

Azure AutoML02及结语

AutoML得到的结果,说明如下。见图<AZ-exp4MNIST.png> 当看到 [S...