配了八年瀑布流,每次高度都要靠 JS 算——今天 grid-template-rows: masonry 把这件事彻底原生化了
瀑布流这个问题,困扰了前端工程师太多年——图片高度不一,Grid 会留空白,column-count 会打乱阅读顺序,JS 库又贵性能又差。现在 CSS Grid Lanes 正式把这件事原生化了,三行 CSS,浏览器自己算最短列。
为什么这么多年搞不定
做瀑布流,有三个常用方案,每个都有坑。
Grid 布局会留空白。 CSS Grid 天然按行排列,卡片高度不一就会出现大缝隙,这在图片画廊里完全不可接受。
column-count 会打乱阅读顺序。 多列布局的内容从上往下填,第一列填满才进第二列,读出来的顺序和 DOM 顺序对不上,语音朗读和键盘导航全乱。
JS 库要付出真实代价。 Masonry.js、Isotope 这类库需要在主线程跑布局计算,每次窗口resize都要重算,图片加载完还要再算一次,累积布局偏移(CLS)直接飙红。
grid-template-rows: masonry 原生化了
这是 CSS Grid Level 3 引入的新布局模式,语法极简:
.gallery {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
grid-template-rows: masonry;
gap: 1rem;
}
就这一行 grid-template-rows: masonry,浏览器自动把每个卡片塞进最短的那一列,没有空白,不打乱 DOM 顺序,主线程零额外计算。
和 JS 库的核心差异:
| JS 库 | CSS masonry | |
|---|---|---|
| 布局计算 | 主线程 JS | 浏览器布局引擎 |
| 窗口 resize | 全量重算 | 自动重排 |
| 图片加载完 | 重新计算 | 自动调整 |
| 依赖 | 需引入 npm 包 | 零依赖 |
| CLS 风险 | 高(延迟计算) | 低(原生) |
完整降级方案:三行 CSS 搞定
Safari 26 首发支持,Firefox 154(2026-08-18)也跟上了,Chrome 和 Edge 在 Interop 2026 推进中。用 @supports 做渐进增强:
/* 降级:普通 Grid */
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 1rem;
align-items: start;
}
/* 增强:Masonry */
@supports (grid-template-rows: masonry) {
.card-grid {
grid-template-rows: masonry;
}
}
不支持的浏览器走普通 Grid,配合 align-items: start 防止卡片被拉高,比 JS 库优雅得多。
还有几个细粒度控制
masonry-slack:控制排列紧凑度,默认 0,可以设 1rem 让浏览器在美观和紧凑之间做平衡。
.gallery {
grid-template-rows: masonry;
masonry-slack: 1rem;
}
跨列卡片:和普通 Grid 完全一样,grid-column: span 2 直接生效。
.featured-item {
grid-column: span 2;
}
对齐控制:align-tracks 和 justify-tracks 控制非 masonry 轴的对齐方式。
三个真实场景直接用
- 图片画廊:Pinterest 风格,零 JS,图片加载自动重排
- 产品卡片列表:电商店铺,商品高度不一,
span 2特色商品直接跨列 - 博客文章卡片:标题长短不一,瀑布流告别参差不齐的下边距
现在能用在生产吗
Safari 26 + Firefox 154 + Chrome(实验)三家状态,主流用户覆盖率有限但可以渐进增强上线。Interop 2026 把 masonry 列为核心关注项,三大引擎全部在推进。
策略:现在用 @supports 渐进增强上线,降级走普通 Grid,完全不破坏现有功能。等 Chrome 稳定支持后再切主路径,JS 库可以开始计划下线了。
八年了,终于可以删掉那个 masonry 的 npm 依赖了。
评论区
登录后可评论。