你以为瀑布流只能用 JS 撑着排版?今天 Safari 26.4 用四行 CSS 把这件事彻底原生化了

每次打开一个有瀑布流的页面,加载时都会看到一次明显的抖动——卡片从上方挤下来,重新排列。这个瞬间的跳动叫布局抖动(layout shift),是 JavaScript 算完坐标再重排 DOM 时产生的视觉垃圾。

这背后是一个持续了十几年的工程妥协:CSS 没有办法让元素自己「找最短的那列落下去」。

于是 Masonry.js、Isotope 这类库统治了这个场景:JS 先量每张卡片的高度,再用 bin-packing 算法从短到长排列,每次窗口缩放重新跑一遍,每次插入新卡片重新跑一遍。16KB 的库,加载时主线程被卡一次,缩放时又被卡一次,首次渲染的布局抖动直接拉低你的 CLS 分数。

CSS 曾经用 column-count 模拟过瀑布流,但元素是按列纵向排的,阅读顺序会乱掉,不适合内容保序的场景。

Safari 26.4 的 CSS Grid Lanes 把这件事彻底原生化了。

Grid Lanes 是 CSS Grid Layout Level 3 的一部分,通过 display: grid-lanes 激活。本质上复用了 Grid 的 track 定义语法,让浏览器在布局阶段自动把每个元素放进「当前最短的那一列」,不需要 JS 介入,不需要绝对定位,也就不会产生任何布局抖动。

三行核心代码:

.gallery {
  display: grid-lanes;
  grid-template-columns: repeat(3, 1fr);
  gap: 1rem;
}

grid-template-columns 复用 Grid 语法,支持 auto-fill + minmax() 做响应式,一行媒体查询都不用:

.gallery {
  display: grid-lanes;
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
  gap: 1rem;
}

想让某张卡片跨两列?一行:

.hero {
  grid-column: span 2;
}

还有一个新属性 flow-tolerance,控制「保序」与「紧凑」的取舍——默认 1em 的容差意味着:当最短列和次短列的高度差在 1em 以内时,浏览器优先保持 DOM 顺序而非极致紧凑。这个参数是无障碍阅读顺序的关键杠杆。

.gallery {
  display: grid-lanes;
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
  gap: 1rem;
  flow-tolerance: 4lh;
}

浏览器支持现状(2026 年 9 月):

Safari 26.4 是目前唯一默认开启的引擎,覆盖所有 iOS Safari 用户。Chrome(140-150)和 Firefox(77-153)需要手动在 chrome://flagsabout:config 开启实验性 Web Platform 特性才能用。渐进增强写法:

.gallery {
  /* 默认降级:CSS Grid 正常排列 */
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1rem;
}

@supports (display: grid-lanes) {
  .gallery {
    display: grid-lanes;
    grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
  }
}

如果你的用户主要在 iOS 上,Safari 26.4 的覆盖率已经可以直接上了。如果面向全平台,现在开始加上 @supports 降级,写一次,未来浏览器默认开启时自动切换到原生实现。

三步开始:

  1. 跑通 demo:在 Safari 26.4 打开一个 display: grid-lanes 的本地页面,确认效果符合预期
  2. 加渐进增强:套 @supports 包裹 grid-lanes 规则,未支持浏览器回退到 column-count 或普通 Grid
  3. 监控覆盖:等 Chrome/Firefox 稳定版默认开启后,删掉降级代码,享受零 JS 的完整性能收益

十几年了,瀑布流终于不需要 JS 撑着排版了。

评论区

0 条评论

登录后可评论。