[CSS] Flex/Grid Layout Modules, part 13

单元对齐跟留白的部分今天会继续,定位的问题基本上不出乱子的话就如同昨天说明的。当然,如果再加上对齐跟留白,如果不小心也是会爆炸的。

对於留白问题,我一律设定为 0欸不是。


填满(stretch)与留白(margin

我们现在已经会操作单元轨道来 框住 我们的 Grid 单元了,那麽,那些基本的单元对齐的部分应该使用上就不会有太大的问题。

如果忘记的请自行复习

但是呢,由於轨道边界设定的关系,所以 Grid 容器指定的对齐、Grid 单元自行指定的对齐,跟 marginstretch 之间就会有不少互相影响的部分。之前有说过,当你使用 stretch 的时候,因为会预设 填满 所以对齐这件事情基本上会觉得他 没有任何效果

在完全没有任何设定的 Grid 单元,他们所有的设定预设都会是 auto,也就是说,基本上所有的 Grid 单元会填满每一个轨道空间,

.grid-container {
    display: grid;
    
    grid-template-columns: repeat(7, [foo] 1fr [qoo]);
    grid-template-rows: repeat(3, 1fr);
    
    grid-auto-rows: 100px;
}
<div class="grid-container">
    <div class="grid-item">1</div>
    <div class="grid-item">2</div>
    <div class="grid-item">3</div>
    <div class="grid-item">4</div>
    <div class="grid-item">5</div>
    <div class="grid-item">6</div>
    <div class="grid-item">7</div>    
</div>

https://ithelp.ithome.com.tw/upload/images/20210918/20001433P7XHemzX34.png

所以在这种预设行为下,基本上你想要定义的对齐都 看不出什麽效果,换句话说,除非你明订了 Grid 容器、Grid 单元所使用的轨道空间,与 Grid 单元本身的尺寸,你的对齐才会有效果。

所以,这种 stretch 的预设行为,在明确定义使用空间的情况下,会有什麽反应呢?

.grid-item:first-child {
    grid-column: 1 / 4;
    grid-row: 1 / 3;
    
    align-self: stretch;
    justify-self: stretch;
}

图片我就不做了,上面就是把栏方向轴轨道 1 ~ 4,列方向轴轨道 1 ~ 3 这个区域填满。

但是,

如果你使用了 margin 的话,他的填满就会受到 margin 的影响,且,如同之前所说的,这个填满设定一样会受到 min-width, min-height, max-width, max-height 所影响。我们单纯来看 margin 的例子,

.grid-item:first-child {
    grid-column: 1 / 4;
    grid-row: 1 / 3;
    
    align-self: stretch;
    justify-self: stretch;
    
    margin-left: 100px;
}

https://ithelp.ithome.com.tw/upload/images/20210918/20001433O7W1DwItUy.png

你会看到这个 Grid 单元被压缩了,我们之前有说过,在无指定尺寸的 Grid 单元,他所使用的尺寸演算方式会使用 fit-content 的计算方式来决定这个 Grid 单元的大小。所以,在一个合理的 margin 留白数值的设定下,Grid 单元的尺寸就会被压缩,用以符合留白(margin)的设定。

如果在无指定尺寸下使用 auto 的关键字呢?这个时候就必须取决於 fit-content 所计算出来的结果,来决定这个 auto 的最终呈现结果。换句话说,会有以下两种状况,

  • fit-content 计算尺寸可填满轨道,则 auto 数值为 0
  • fit-content 计算尺寸无法填满轨道,则 auto 数值为 <轨道剩余空间>

https://ithelp.ithome.com.tw/upload/images/20210918/200014336QcrGJTQFB.png

换句话说,margin 使用 auto 的效果就是将非指定尺寸的 Grid 单元做尺寸计算,而早先我们有提过,单元的非指定尺寸运算就是使用 fit-content,所以,在 auto 的情况下就会把整个 Grid 单元压缩到 fit-content

所以,你会有一种错觉,底下的设定为何没对齐左边?

.grid-item:first-child {
    grid-column: 1 / 4;
    grid-row: 1 / 3;
    
    align-self: stretch;
    justify-self: start;
    
    margin-left: auto;
}

不是你的错觉
对於整个 Grid 轨道来说,他就是水平方向使用 start 对齐左边,之所以内容被推到右边,那是因为从 Grid 轨道的 start 开始,被放入了 margin-left: auto,而使无指定尺寸内容被压缩到 fit-content 的关系。

我们如果跳离开 Grid 格线系统,单纯的使用区块元件来看,

https://ithelp.ithome.com.tw/upload/images/20210918/20001433r0lLs69jy5.png

这个状况在一般的 Box Module 对齐就是这个方式(以一般 LTR 的文本状况),所以,现在只是把这个 100px 换成 auto 而已,其实并没有 对齐点不同 的情况。这也是一种很常见的 在逻辑与样式设定上是有对齐的,但是在 视觉上 却看起来没有对齐 的情况。

举例来说,

.grid-item:nth-of-type(1),
.grid-item:nth-of-type(2) {
    grid-column: 1 / 4;
    grid-row: auto;
    
    align-self: stretch;
    justify-self: start;
    
    margin-left: auto;
}
<div class="grid-container">
    <div class="grid-item">对齐点其实在左边</div>
    <div class="grid-item">看起来却向对齐了右边</div>
</div>

https://ithelp.ithome.com.tw/upload/images/20210918/20001433HdeHiykErV.png

有监於绝大部分的人还是视觉动物,所以如果要精确对齐的话,基本上要太随意使用 autostretch 这两个设定,不然大多都是 你的对齐不是我的对齐 的这种鸟事。


列方向轨道定位问题

我们一直都在讲栏方向的对齐、定位,虽然说绝大部分的情况,大多都可以转个方向就能通用,但是,有些情况还是会让你产生 为什麽会这样? 的疑惑。

举一个最常见的例子,

.grid-item:nth-of-type(1),
.grid-item:nth-of-type(2) {
    grid-column: 1 / 3;

    grid-row: auto;
}

我们把两个单元定位在 栏方向的范围,且大小完全相同 ,在这个情况下,你觉得他会发生覆盖吗?

不会!

我知道了,一定是我设定了 grid-row: auto 的关系!

不是!

那会发生什麽事情?

https://ithelp.ithome.com.tw/upload/images/20210918/20001433f3Ik4PGpcX.png

其实你把这个行为转 90 度,把栏、列交换来看,你就知道为什麽了。由於我们太习惯了由左至右排列,而忽略了由上至下的这一层关系。所以会天真的以为,既然栏重叠了那就 往後放 就好啦?

不!
栏重叠了要往下放!
栏重叠了要往下放!
栏重叠了要往下放!

同样的道理,

.grid-item:nth-of-type(1),
.grid-item:nth-of-type(2) {
    grid-row: 2 / 3;
}

我这次连 grid-column 都不设定了,请问会发生什麽事情呢?我已经指定了 重复的列 的轨道位置,那麽他会怎麽摆放这两个 Grid 单元呢?

https://ithelp.ithome.com.tw/upload/images/20210918/20001433zY5pEKgtTN.png

如果你有设定 grid-column 但使用的是 span 关键字,那麽也会造成雷同的效果。但是请不要同时指定开始与结束的位置,请使用 span <数字> 就好。请不要问我为什麽?

你同时指定开始、结束位置,就 等於完全重叠 了好吗!

请不要这样设定後还来问我为何没有自动排!

我保证会敲死你!

.grid-item:nth-of-type(1),
.grid-item:nth-of-type(2) {
    grid-column: span 3;
    grid-row: 2 / 3;
}

https://ithelp.ithome.com.tw/upload/images/20210918/20001433ZknRws244r.png

span 这个关键字在一开始我们的 grid-column 重叠的例子上也是通用的,这边我就不再附上图片了。那麽,这样会有什麽意外吗?

有,而且不小心就会发生。

当你算错轨道的时候,例如,我们的跨度写成了 span 5

.grid-item:nth-of-type(1),
.grid-item:nth-of-type(2) {
    grid-column: span 5;
    grid-row: 2 / 3;
}

/* 或是 */

.grid-item:nth-of-type(1),
.grid-item:nth-of-type(2) {
    grid-column: 1 / 4;
    grid-row: span 5;
}

两个方向如果跨度都超过 Grid 容器,隐性格线就会出现,此时,隐性轨道的宽度会依照你所设定的数值去走(grid-auto-columns, grid-auto-rows),如果没有设定,那麽隐性轨道的宽度就会是 0。所以,当你不小心跨度跨过头的时候,你就会瞬间多出好几条网格格线出来。

这种时候,如果你有设定间隔(gap)的话,你就会发现在有限尺寸的方向,就是一般显示装置的宽度,最右边多出了很多 gap 的宽度出来,我之前有提过了间隔尺寸会依照格线轨道而 永久存在不会被压缩

row 方向就比较幸运一点,如果你的容器没有指定列方向尺寸的话,基本上他就视为 无限长度 的方式将所需要的 Grid 轨道填满正个容器。

但是,如果 row 方向有设定尺寸,也就是容器的高度(height)时,就没那麽好运了。这种情况就很类似於把 row 方向转去 column 一样(把高度变成宽度)。

这种设定错误的情况会因为隐性轨道尺寸的设置而造成两种不同的影响,

  • 不指定隐性轨道尺寸优先计算 span <数字> 的可用轨道,将整个轨道区域依照指定尺寸,或弹性系数 fr 依照 fit-content 来均分,并将不足的部分分配 0 的尺寸,绝大部分隐性轨道会分配到 0 尺寸。
  • 指定隐性轨道尺寸优先分配且保证 隐性轨道尺寸 的轨道空间,不足空间的部分会压缩弹性系数 fr 的轨道空间,并使得符合 fit-content 尺寸,有部分轨道会分配到 0 的尺寸。

具体来说会如何呢?如果不设定隐性格线尺寸,那麽隐性格线就会被压缩,

https://ithelp.ithome.com.tw/upload/images/20210918/20001433P6nW38LjFS.png

如果设定隐性格线尺寸,那麽隐性格线尺寸会优先占用容器,

https://ithelp.ithome.com.tw/upload/images/20210918/200014336cL3K5kS20.png

如果是列方向的话,比较不会有奇怪的问题,但如果你限制了 Grid 容器的高度(height),那麽列方向如果在空间不足,出现隐性轨道的时候,就会有比较奇怪的状况发生。

https://ithelp.ithome.com.tw/upload/images/20210918/20001433KPxCdeXCy9.png

由於间隔(gap)本身会占据空间,所以在不设定隐性格线尺寸的情况下,会尽可能压缩没用到空间的列,但是,由於列方向的 fit-content 最小值是 0(除非你是直书模式),所以你从上图会发现,我们原本的第二列内容,被压缩到仅出现在间隔(gap)所占据的空间内。

这就是所谓的 夹缝中求生存!

如果你有设定隐性格线尺寸,那麽状况就刚好颠倒,如同栏方向(column)一样,被压缩的就会是原本设置弹性空间的部分,

https://ithelp.ithome.com.tw/upload/images/20210918/200014338lZalWTEZL.png

其实,如果你限制了容器的宽度(width),那麽一样会发生类似的状况。只是因为这边的范例都以 width: 100% 为主,所以并没有像是高度那麽明显的情形发生。


小记

有没有发现我压根都没讲到对齐?因为那些关键字好像太容易,讲起来颇无趣。我明天找个时间充版面贴一下好了,总得有个交代才行(笑)。


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


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


<<:  予焦啦!BSS 初始化

>>:  Day 06 : 资料处理 Pandas (2)

Day 17 - Error Handling 错误处理

前言 错误处理往往是最容易被忽略的一块,因为 程序运行顺利,那当然不用考虑 error case 程...

我的 QA 道路之你怎麽又被炒了

嗨各位~ 今天是今年的最後一天, 这篇想来分享一下我自身QA的经历, 我知道你们想看的是到底为甚麽会...

[Day 11] 多对多关联的变形:Parent-Child reference

之前我们看过了透过 DAO 方式,来处理资料之间呈现一对多关联,或者多对多关联的做法。 今天我们来看...

33岁转职者的前端笔记-DAY 7 常见的卷轴 scollbar 做法

第七篇一样来写写公司专案用到的排版技能 在注册页面还没填资料时很多网站都会先跳出「个人资料使用声明同...

躲开Windows地雷使用AWS的Docker让你上天堂

Container会飞 在AWS ECS上目前有提供EC2 mode, Fargate, ECS A...