先记住这个答案
先把子网格元素放进父 Grid,并用 grid-row 或 grid-column 指定它跨越的轨道;然后在该轴写 subgrid。它的孩子会对齐父网格对应的轨道线,但定位时从子网格自己的起点编号。比如卡片跨父网格第 2 到第 5 条行线,它内部只有三行、四条本地线;孩子无法用一个线号直接跳到父网格范围外。
- 先确定子网格在父级跨越的范围
- 子项用局部线号定位
span决定项目跨过几条轨道- 子项不能越界占用父级其他轨道
先圈定父级轨道范围
把卡片看作从父网格裁下来的一块区域更容易理解。它跨过三条父级行轨道,内部子网格就获得三条对应的行轨道;父级其他行不属于这张卡。
.board { display: grid; grid-template-rows: 60px 1fr 48px; }
.card { display: grid; grid-row: 1 / span 3; grid-template-rows: subgrid; }
.card__title { grid-row: 1; }
.card__action { grid-row: 3; }标题占子网格第一行,操作区占第三行,两者沿用父级对应行的尺寸。span 3 说的是跨三条轨道,不是跨三条网格线;三条轨道的两端一共有四条线。
如果卡片在父网格中从第二行开始,内部标题仍可用本地第一行定位。把父级绝对行号直接写给子项,往往会落到意料之外的位置。
双轴定位要分别看范围
行方向可以设成子网格,列方向继续让卡片独立布局。这时内部的 grid-row 对着父级行轨道,grid-column 对着卡片自有列轨道。两个坐标系可以同时存在,不要因为行已经共享就以为列也共享。
调试嵌套布局时,先标出父级的行列线,再写出子网格项目实际占的范围,最后才判断子项的线号。父级缩小或卡片换位置时,局部线号仍相对卡片起点,适合复用组件。
还有一个容易忽略的场景:子网格内部某项内容很长,把共享的 auto 轨道撑高,父网格那条轨道也会跟着变高。子网格并非把父级尺寸“复制一份”后各自计算;它把内部内容的尺寸需求带回同一组轨道。因此跨卡片对齐通常会成功,但整行卡片也可能因为一张长标题而变高。要控制高度,就要先处理文本换行或轨道上限。
容易答错的地方
- 把
span 3理解为跨三条线 span 3指三条轨道。若从第 1 条线开始,结束线是第 4 条。- 让子项直接定位到父级范围外
- 子项仍是子网格的网格项目,定位发生在子网格提供的轨道范围内;需要更大范围先调整父级对子网格的分配。
面试官还会怎么问?
子网格只跨一行有用吗?
可以生效,但在该轴只有一条轨道,可供内部项目对齐的线很有限。跨多条轨道时共享效果更明显。
父网格的命名线能在子网格里使用吗?
继承轨道时相关线名可以传入子网格范围,但仍应核对局部范围和命名冲突,不能借名字越过所占区域。
能同时继承行和列吗?
可以两个轴都设 subgrid,前提是父网格在两个轴上都给子网格分配了相应轨道范围。
参考资料
示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。