基础方案
说明文字较短。
查看详情来源:17golang原创
时间:2026-09-15 04:26:38 465浏览 收藏
多张卡片的标题、说明文字长度不一样时,最常见的结果是按钮上下错位。原因通常不是卡片高度没写够,而是每张卡片内部又创建了一套独立的 Grid 轨道。解决这类问题可以让卡片成为父网格的子项,再用 grid-template-rows: subgrid 继承父级行轨道。
grid-row: span 3 跨过标题、正文、操作三行。普通 Grid 只约束直接子元素。外层网格知道三张卡片放在哪些列,却不知道卡片内部的标题和按钮;如果每张卡片都写一遍 grid-template-rows: auto 1fr auto,它们的行高仍由各自内容决定。标题多一行,正文和按钮就会一起下移。
这里的目标是“跨卡片对齐”,不是让所有卡片强行同高。父网格应明确共享哪些轨道,卡片内部不要再复制一套互不相干的行定义。

先把卡片看成父网格的三个垂直区域:标题、可伸缩内容、操作区。下面的结构刻意让每张卡片只有三个直接子元素,便于观察轨道是否真的被继承。
基础方案
说明文字较短。
查看详情
/* 父网格统一声明三条可共享的行轨道。 */
.card-grid {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
grid-template-rows: auto 1fr auto;
gap: 24px;
align-items: stretch;
}
/* 每张卡片跨过标题、正文、操作三行,才能继承完整轨道。 */
.card {
display: grid;
grid-row: span 3;
grid-template-rows: subgrid;
min-width: 0;
padding: 20px;
border: 1px solid #d9e2ec;
border-radius: 12px;
}
/* 内容区允许伸展,操作区自然落在同一条父级行上。 */
.card__body {
min-width: 0;
}
/* 不支持 subgrid 的环境仍保留可用的纵向卡片。 */
@supports not (grid-template-rows: subgrid) {
.card {
display: flex;
flex-direction: column;
}
.card__body {
flex: 1;
}
}
关键不在 subgrid 这个词本身,而在卡片实际跨过了父级的三行。若卡片只占一行,继承到的轨道范围就不完整;若卡片内部多套了一层包装,真正需要对齐的元素也可能不再是卡片的直接子元素。
把三张卡片放入相同的父网格后,给其中一张加上两行标题或更长的说明,观察三张卡片的操作区是否仍处于同一水平线。验证时看三个点:标题区域是否共享高度、正文区域是否吸收剩余空间、操作链接是否落在共同的底部轨道。
subgrid 也可以用于列:例如卡片内部的图标、标题和数值需要沿用父级列线时写 grid-template-columns: subgrid。列和行可以分别启用,也可以同时启用。父级的 gap 默认会传入 subgrid,但卡片确实需要不同间距时可以在卡片上覆盖 row-gap 或 column-gap。

固定三段内容的卡片很适合行 subgrid;如果卡片里要自动放入数量未知的标签、列表项或评论,使用 subgrid 的那个维度不会像普通 Grid 那样继续创建隐式轨道。此时应只对确定需要对齐的维度使用 subgrid,另一维保留普通网格和 grid-auto-rows。
兼容性上,现代浏览器已经普遍支持 subgrid,但嵌入式 WebView、旧企业环境仍可能缺失。上面的 @supports 降级把卡片切换为纵向 flex:它不保证跨卡片的精确行线一致,却能避免内容重叠和操作入口消失。生产页面应在目标浏览器矩阵中确认视觉要求,再决定是否把精确对齐作为必要能力。
| 现象 | 优先检查 | 处理方式 |
|---|---|---|
| 按钮仍然错位 | 卡片是否跨过全部父级行 | 补上 grid-row: span 3 |
| 子项没有对齐 | 是否为卡片直接子元素 | 减少中间包装或把 subgrid 下移到正确容器 |
| 多出的项目挤在末行 | subgrid 维度是否需要隐式行 | 取消该维度的 subgrid,改用普通隐式轨道 |
它共享的是父网格轨道,不是无条件设置固定高度。父级使用 auto 或可受内容影响的轨道时,内容仍可能参与轨道尺寸计算。
先检查卡片是否为父网格直接子项、是否跨过对应行,以及标题是否被额外包装层隔开。subgrid 只影响它的直接子网格项。
可以。grid-template-columns: subgrid 与 grid-template-rows: subgrid 是独立的,按需要继承一个维度即可。