先记住这个答案
Masonry,也叫瀑布流,主要解决高度不同的卡片按列紧凑堆叠、避免普通 Grid 行高造成大块空白的问题。subgrid 解决另一件事:让嵌套网格的行或列沿用父网格轨道,使卡片内部标题、正文、按钮与兄弟卡片对齐。一个讨论放置算法,一个讨论轨道继承,不能互相替代。原生瀑布流相关规范仍在演进,使用前要看目标浏览器支持。
- Masonry 解决不等高卡片的空洞
subgrid解决嵌套轨道对齐dense只回填网格空格- 原生瀑布流语法需查兼容性
不等高卡片为什么留洞
普通 Grid 中,同一行的行轨高度要能容纳该行较高的项目。左侧卡片特别高、右侧卡片很矮时,右侧下面的空间可能空着。grid-auto-flow: dense 能回填自动放置时由于项目跨度留下的空网格单元,却不会把短卡片下方的行轨空白变成真正的瀑布流通道。
.gallery {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
grid-auto-flow: dense;
gap: 12px;
}
.gallery .wide { grid-column: span 2; }
/* dense 可填跨度留下的格子,不按列堆叠不等高内容 */做生产级瀑布流前,先明确是否必须保持 DOM 阅读顺序、是否要图片加载后重新测量高度、是否需要按列或按行排序。原生 Grid lanes 等实验能力可能提供更接近瀑布流的布局,但语法和浏览器支持不能凭一段旧示例保证;要以当前目标环境的兼容数据验证。
子网格负责对齐嵌套内容
商品卡片外层是 Grid,每张卡片自身也设为 Grid。如果每张卡片独立定义行高,标题长短不同会让价格按钮上下不齐。让卡片跨越父网格轨道,并在对应轴使用 subgrid,子项便能沿父级分配的轨道对齐。它不会把高卡片下面的空洞补上,也不会重排兄弟卡片。
subgrid 用在 grid-template-columns 或 grid-template-rows,可只对一个轴生效。它继承的是父项目跨过的轨道范围,不是复制整张父网格。两种能力可在同一页面分别承担任务,但若产品要求的是照片墙的紧密堆叠,先判断瀑布流方案是否适配浏览器与交互顺序。
一组高度不等的图文卡片,普通 Grid 的每行仍以该行最高卡片确定行轨道;grid-auto-flow: dense 只能填完整空单元,不能把下一张卡片插进某列局部空白。subgrid 则解决另一件事:让卡片内部标题、摘要沿父级轨道对齐。两者目标不同。要选 Masonry 方案时,应先明确目标浏览器和阅读顺序要求,别只根据截图判断可用。
容易答错的地方
- 把
dense说成原生瀑布流 - 它仅尝试填较早空格,普通 Grid 的行轨仍存在,不能按列消除所有高度差。
- 用
subgrid期待卡片自动重排 - 子网格控制嵌套轨道对齐,不决定兄弟卡片堆叠顺序。
面试官还会怎么问?
瀑布流为什么要关注图片加载?
图片加载后高度可能改变,依靠测量定位的方案必须更新位置;否则卡片会重叠或留洞。
subgrid 能只继承列不继承行吗?
能。只在 grid-template-columns 写 subgrid,行轨仍可自行定义。
什么时候可以先用普通 Grid?
卡片高度接近、允许按行对齐且不要求填满每个纵向空洞时,普通 Grid 更简单。
参考资料
示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。