先记住这个答案
subgrid 是 grid-template-rows 或 grid-template-columns 的取值,不会把普通元素变成网格容器。要让卡片里的标题、正文、按钮沿父级行轨道排,卡片需要先是父 Grid 的项目,再设置 display: grid,并在对应轴写 grid-template-rows: subgrid。align-self 是项目在分配区域内怎样对齐,与是否创建子网格是两回事。
- 子网格元素本身也是 Grid 容器
subgrid只作用于指定轴- 子网格继承父级对应轨道
align-self控制项目在区域内的对齐
卡片内部对齐的前提
一排商品卡的标题长短不同,按钮却要齐底。父级 Grid 可规划共同的行轨道;每张卡跨越这些行,并把内部行设置成子网格。这样各卡不再自己测量标题行高度。
.list { display: grid; grid-template-columns: repeat(3, 1fr); grid-template-rows: auto 1fr auto; }
.card { display: grid; grid-row: span 3; grid-template-rows: subgrid; }
.card .button { align-self: end; }.card 的 display: grid 决定内部子节点是否变成网格项目;grid-template-rows: subgrid 决定这三行使用父级轨道。按钮的 align-self: end 只改变按钮在所占区域里的位置,不负责继承轨道。
实际卡片布局还要确保卡片在父网格中跨越预期的行。若父容器没有共享的行轨道设计,仅写 subgrid 不会凭空制造跨卡片的对齐线。
行与列可以分别选择
有时只需要让标题、描述、按钮在纵向对齐,卡片内部横向布局仍想独立控制。这时只把行设为 subgrid,列继续由卡片自己的 grid-template-columns 定义。反过来,也可以只继承列。
检查元素样式时分两层看:它是不是 Grid 容器;它在父 Grid 中占哪几条轨道。第一层缺失时 grid-template-rows 不产生网格容器效果,第二层范围不对时即便子网格生效,内部项目也找不到期望的对齐位置。
容易答错的地方
- 以为
subgrid等同于display: grid subgrid只指定轨道来源。没有display: grid,子元素不会因为这个值自动成为网格项目。- 把
align-self: stretch当成共享轨道 - 拉伸改变的是单个项目在网格区域内的尺寸。跨卡片共享标题行高度需要公共轨道或子网格,不能只靠项目自身拉伸。
面试官还会怎么问?
可以只在列方向使用子网格吗?
可以。写 grid-template-columns: subgrid,行方向仍可定义独立轨道;两个轴并不必须一起继承。
子网格能重新设置父级轨道宽度吗?
它使用父级在所占范围内的轨道,不能像独立 Grid 那样重新定义那组轨道尺寸。内部内容可能参与轨道尺寸计算,但轨道属于父级布局。
卡片不是父 Grid 的直接项目能用吗?
子网格继承的是其父网格对应的轨道。若中间多了一层普通包装元素,先检查实际的网格项目是谁,以及要在哪一层建立子网格。
参考资料
示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。