grid-template-rows: masonry 是最理想的瀑布流方案,但仅 Chrome/Edge 116+ 支持,需用 @supports 包裹并降级为 display: grid + grid-auto-flow: dense,配合 minmax 列宽、aspect-ratio 防塌陷及禁用 grid-auto-rows。

纯 CSS 实现“视觉错落、语义正确”的瀑布流,grid-template-rows: masonry 是目前最接近理想的方案,但它只在 Chrome/Edge 116+ 支持;生产环境必须 fallback 到 display: grid + grid-auto-flow: dense 组合,配合明确的列宽控制和 aspect-ratio 防塌陷。
为什么 column-count 看似简单却容易翻车
它把卡片当文本流切分,DOM 顺序和视觉顺序不一致:第 1 个卡片永远在第 1 列顶部,第 4 个可能出现在第 1 列底部——这对 SEO、屏幕阅读器、键盘 tab 顺序都是硬伤。
- 卡片内有按钮或表单时,
tab键会按文档流跳转,不是从左到右、从上到下地“视觉浏览” - 打印样式(
@media print)下直接变成单列长条,无法控制分页位置 -
break-inside: avoid在图片未加载完成时失效(高度为 0),导致先错位、后重排,用户可见抖动 - 列数写死(如
column-count: 3),缩屏后卡片过窄,文字挤成一团
grid-template-rows: masonry 怎么用才不白写
这个属性是真正的 Masonry 布局引擎,浏览器自动找最短列插入新卡片,但仅限新版 Chromium。关键是要写好降级逻辑,不能让它被忽略。
- 必须包裹在
@supports (grid-template-rows: masonry)块里,否则旧浏览器会整个规则块失效 - 降级样式要立即生效:外面先写通用
display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)) - 卡片必须设
aspect-ratio: 9/16或类似值,否则加载前高度为 0,masonry无法计算列高 - 禁用
grid-auto-rows—— 它和masonry冲突;真正需要的是每张卡片自身撑开高度
fallback 到传统 Grid 时,grid-auto-flow: dense 的真实作用
它不是让卡片“自动填空”,而是允许 Grid 在已有轨道中回填被 grid-row 跳过的空行。没有显式行定位时,它的效果很有限,必须配合其他约束才能模拟错落感。
生成可在 deepbi 沙箱 iframe 内运行或作为独立文件运行的交互式 HTML 页面,使用 `window.deepbi` JS SDK 实现数据查询、空间管理、文件浏览及用户操作。当用户提出以下需求时启用该能力: - 创建 KPI 仪表盘、数据表格、文件浏览器、成员列表、管理页面; - 明确要求“转成 dhtml”、“转译成 HTML”、“把 XX 页面转成……”、“控制台页面”、“管理后台”、“DeepBI 页面迁移”; - 提及位于 `apps/console/src/featur
立即学习“前端免费学习笔记(深入)”;
- 给容器加
grid-auto-rows: 10px(值本身无关紧要),这是触发 dense 行分配的前提 - 卡片不要设固定
height,靠内容或aspect-ratio自然撑开,否则 dense 无法错开 - 避免对卡片使用
margin-top或transform微调位置——这会破坏 Grid 的自动布局逻辑 - 如果卡片内有
position: absolute元素(比如角标 badge),其父卡片必须设position: relative,否则绝对定位脱离上下文
移动端真正在意的不是“错不错落”,而是“点不点得中”
iOS Safari 对 overflow: auto 容器里的事件区域识别极差,尤其当卡片高度为 0 或含 position: absolute 子元素时,点击直接失灵。
- 每张卡片加
min-height: 1px,哪怕只是占位,也能唤醒 Safari 的事件捕获层 - 瀑布流容器加
-webkit-overflow-scrolling: touch(iOS 16.4+ 已弃用,但部分企业内网仍需) - 禁用
overflow: hidden在容器上,否则跨列标题(如 span 多列的 banner)会被截断 - 图片加载闪跳问题,
aspect-ratio是首选;不支持的旧 Safari 可用伪元素 +padding-bottom回退
真正难处理的不是怎么让卡片错落,而是忘记卡片是否参与了外层布局的对齐逻辑——比如父级用了 align-items: start,那再怎么调子元素的 margin-top: auto 都没用。先看外层容器的 display 和对齐设置,再动卡片内部。


















