配了八年瀑布流,每次高度都要靠 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-tracksjustify-tracks 控制非 masonry 轴的对齐方式。

三个真实场景直接用

  1. 图片画廊:Pinterest 风格,零 JS,图片加载自动重排
  2. 产品卡片列表:电商店铺,商品高度不一,span 2 特色商品直接跨列
  3. 博客文章卡片:标题长短不一,瀑布流告别参差不齐的下边距

现在能用在生产吗

Safari 26 + Firefox 154 + Chrome(实验)三家状态,主流用户覆盖率有限但可以渐进增强上线。Interop 2026 把 masonry 列为核心关注项,三大引擎全部在推进。

策略:现在用 @supports 渐进增强上线,降级走普通 Grid,完全不破坏现有功能。等 Chrome 稳定支持后再切主路径,JS 库可以开始计划下线了。

八年了,终于可以删掉那个 masonry 的 npm 依赖了。

评论区

0 条评论

登录后可评论。