先记住这个答案
Grid 的 gap 定义轨道之间的沟槽。三列会有两道列沟槽,不会在容器左右再各加一道;即使某个项目横跨两列,列与列之间的沟槽仍在布局计算中,但这个项目会铺过整个区域。若自动放置让 Grid 新建一行,原有行与新行之间同样会出现行沟槽。
gap只在相邻轨道之间出现- 容器首尾没有额外的
gap - 隐式轨道之间同样有沟槽
- 跨轨道项目不会被沟槽切开
用轨道数计算间距
做三列卡片时,不能拿卡片的左右 margin 模型来算 gap。容器内容盒宽 640px,三列分别固定 200px,column-gap 是 20px,那么两道沟槽占 40px,剩下的宽度是否还能容纳列,要直接按轨道求和。项目换了顺序或某一格为空,沟槽不会跟着项目移动。
.cards {
display: grid;
grid-template-columns: repeat(3, 200px);
column-gap: 20px;
row-gap: 12px;
}
.cards > .wide { grid-column: 1 / 3; }
/* wide 横跨前两列,也覆盖它们之间的沟槽 */这里显式列总宽为 600px,加两道列沟槽是 640px。.wide 横跨前两列时宽度是 420px,不是 400px,因为它覆盖的区域包括中间的 20px 沟槽。沟槽影响区域尺寸,但不会把一个项目的背景切成两半。
隐式网格也有间距
假设模板只声明一行,却放进足够多的自动排列项目。Grid 会继续生成隐式行,行高可由 grid-auto-rows 控制。每相邻两行之间都应用 row-gap;新增两行意味着增加两道行间距。gap 本身并没有创建轨道,创建轨道的是自动放置或项目跨出显式边界。
这一点在计算列表高度时容易漏掉:三行各 100px,row-gap: 16px,网格内容高度是 332px,而非 348px。只有两处相邻关系。若用百分比间距,容器尺寸是否明确又会影响求值,尺寸紧张时优先用清晰的长度值核算。
三列网格不管放了三张还是六张卡片,列沟槽始终是相邻列轨之间的两道,不会因为项目变多就再多出三道。一个项目跨两列时,它覆盖了中间那道沟槽所在的区域,看起来也不像给项目每侧都加了 margin。量尺寸时应先算轨道数,再算轨道之间的 gap,最后才看项目自身内边距。
容易答错的地方
- 把
gap当成每个项目的margin - 项目外边距属于项目本身,首尾项目也可能留白;
gap属于轨道之间。跨格项目会覆盖中间沟槽,二者的几何行为不同。 - 认为空格子就没有沟槽
- 没有项目不等于轨道消失。只要相邻轨道存在,它们之间就有定义好的沟槽。想移除空列,需要改变轨道模板或自动生成策略。
面试官还会怎么问?
gap 会撑大一个跨两列的项目吗?
会。它的网格区域覆盖两条列轨和中间沟槽,因此项目铺满区域时宽度包含那道间距。
新增隐式行会自动继承 row-gap 吗?
会。row-gap 作用于所有相邻行轨,包括显式行与隐式行的交界处。
只有一列时 column-gap 有效果吗?
只有一条列轨就没有相邻列,因而没有列沟槽;但若项目定位迫使网格生成第二列,就会出现一道。
参考资料
示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。