大家好,我是 Immerse,一名独立开发者、内容创作者、AGI 实践者。
关注公众号:沉浸式趣谈,获取最新文章(更多内容只在公众号更新)
个人网站:https://yaolifeng.com 也同步更新。
转载请在文章开头注明出处和版权信息。
我会在这里分享关于编程、独立开发、AI干货、开源、个人思考等内容。
如果本文对您有所帮助,欢迎动动小手指一键三连(点赞、评论、转发),给我一些支持和鼓励,谢谢!

之前做瀑布流布局,要么用 Masonry.js 这种库,要么自己写一堆 JavaScript 计算位置。
现在好了,CSS Grid Lanes 来了,三行代码就搞定。
Safari 技术预览版已经支持了,你现在就能试。
三行代码实现瀑布流
看最简单的用法。
.container {
display: grid-lanes;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
gap: 16px;
}

就这样。
第一行设置 display: grid-lanes,告诉浏览器用 Grid Lanes 布局。
第二行定义列,至少 250px 宽,自动填充所有可用空间。浏览器会根据屏幕宽度决定显示几列。
第三行设置间距,列与列之间、卡片与卡片之间都是 16px。
不用写 JavaScript,不用算高度,不用考虑响应式。浏览器全帮你搞定了。
原理是什么?
把它想象成堵车的高速公路。
每辆车都想往前挤,哪条车道空就往哪条钻。每个新卡片也一样,浏览器会把它放在最靠上的位置。
这样布局出来的效果和 Masonry.js 一模一样,但性能好太多了。
如果你要做无限滚动加载更多内容,也不用 JavaScript 控制布局了。滚到底部加载新数据,浏览器自动把新卡片摆好。
列宽可以不一样
因为底层用的是 CSS Grid,你可以做各种花样。
比如奇数列窄,偶数列宽,最后一列始终是窄的:
.container {
display: grid-lanes;
grid-template-columns: repeat(auto-fill, minmax(8rem, 1fr) minmax(16rem, 2fr)) minmax(8rem, 1fr);
}

这样布局出来就有节奏感了,不会显得太死板。
卡片可以跨列
既然是 Grid,那肯定能跨列。
article {
grid-column: span 1;
}
article:nth-child(1) {
grid-column: span 4;
}
article:nth-child(2),
article:nth-child(3) {
grid-column: span 2;
}

第一张卡片占 4 列做头图,第 2 到第 3 张占 2 列做次要内容,其他的占 1 列。
这种布局以前只能用 JavaScript 计算,现在纯 CSS 就行。
报纸那种复杂版式也能做出来了。
固定位置也可以
你还能指定某个元素放在特定位置。
比如把 header 固定在最右边的两列:
main {
display: grid-lanes;
grid-template-columns: repeat(auto-fill, minmax(24ch, 1fr));
}
header {
grid-column: -3 / -1;
}

不管屏幕多宽,header 都会出现在右边。其他内容该怎么排怎么排。
横向布局也能做
瀑布流是竖着流,Grid Lanes 也能横着流。

竖着流用 grid-template-columns 定义列:
.container {
display: grid-lanes;
grid-template-columns: 1fr 1fr 1fr 1fr;
}
横着流就用 grid-template-rows 定义行:
.container {
display: grid-lanes;
grid-template-rows: 1fr 1fr 1fr;
}
浏览器会根据你定义的是列还是行,自动判断流的方向。
不用额外设置什么属性,它自己就知道。
容错度控制
有个新概念叫容错度。
假设第一列的卡片高度是 100px,第四列是 99px。下一张卡片应该放哪?
如果追求绝对精确,应该放第四列,因为它矮 1px。
但这 1px 根本看不出来,而且会导致卡片顺序很乱。用户 Tab 切换时会跳来跳去。
所以 Grid Lanes 有个默认容错度 1em。只有高度差超过 1em,浏览器才会认为它们不一样。
小于 1em 的差异会被忽略,卡片会更倾向于从左到右排列。
你可以调整这个值:
.container {
item-tolerance: 2em;
}
设大一点,布局更规整,但可能浪费空间。设小一点,空间利用率高,但顺序会更乱。
根据你的内容大小和内容差异来调。
注意这个属性名字可能还会改,正式发布前留意一下。
现在就能试
Safari 技术预览版 234 已经支持了。
你可以下载来试试,官方 Demo 网站也更新了新语法。
除了图片瀑布流,还有其他用法。
比如做 Mega Menu 的底部链接区域。每组链接高度不同,用 Grid Lanes 排起来非常整齐:
.container {
display: grid-lanes;
grid-template-columns: repeat(auto-fill, minmax(max-content, 24ch));
column-gap: 4lh;
}
各组链接紧密排列,不会浪费空间。

接下来呢
CSS 工作组还有几个细节在讨论,但整体语法已经确定了。
现在可以学起来,可以做 Demo 玩玩,可以给反馈。
WebKit 团队从 2022 年中开始做这个功能,现在终于能用了。
我估计其他浏览器也会很快跟进,毕竟这需求太常见了。
以后做瀑布流,再也不用引 JavaScript 库了。
