一砖一瓦:帮助我们构建 CSS Masonry

Patrick Brosset
Patrick Brosset
Alison Maher
Alison Maher

发布时间:2025 年 7 月 23 日,最后更新时间:2026 年 2 月 13 日

Microsoft Edge 和 Google Chrome 团队很高兴地宣布,CSS 瀑布流已准备好从 Chrome 和 Edge 140 开始进行早期开发者测试。

由于 CSS 瀑布流规范和语法仍存在一些未解决的问题,您的反馈对于帮助我们确定 API 的最终形式至关重要。欢迎试用此功能,并告诉我们您的想法。

立即在 Chromium 中测试 CSS 砌体

如需立即测试 CSS Masonry,请执行以下操作:

  1. 使用 Chrome 或 Edge 140 或更高版本(或其他具有匹配版本的基于 Chromium 的浏览器)。
  2. 在新标签页中前往 about:flags。
  3. 搜索“CSS Masonry Layout”。
  4. 启用该标志。
  5. 重启浏览器。
实验页面上的 Masonry 条目。

启用该功能后,您可以查看 Microsoft Edge 演示(查看演示源代码),了解该功能的实际效果,也可以继续阅读,详细了解该功能和可用语法。

什么是砌体?

CSS 瀑布流是一种布局模式,可让您以 CSS 网格、Flexbox 或多列布局不易实现的方式,创建类似砖块的项排列。

CSS 瀑布流可用于以列或行格式排列内容,内容在这些列或行中以折叠方式放置。

内容以瀑布流布局排列。

您可以将瀑布流布局想象成一条高速公路,唯一的限制是不同车道的数量和大小。在车道内,车辆可以采用任意长度,并且始终尝试尽可能靠近目的地,即瀑布流布局的起点。

演示使用车道中排队的车辆来展示布局。

布局项仅在一个方向上受到约束,并且可以沿另一个方向自由呼吸,而不管附近的其他项如何。瀑布流与网格的不同之处在于,其轨道仅在一个方向上定义。

在瀑布流布局中,内容的视觉顺序不如最终设计重要。 无论您要展示什么商品,Masonry 都能让您充分利用可用空间。 因此,对于视觉效果密集且内容的视觉顺序不如最终结果重要的页面,此布局是一个不错的选择。

瀑布流布局的一个有趣之处在于,它还允许项跨越多个轨道,就像网格一样。在这种情况下,系统会继续以尽可能填满可用空间的方式放置内容。

图片中包含车辆,这次大型车辆跨越两列。

这种自动放置行为可以产生非常有趣的结果,这也是网页设计师长期以来一直试图实现的效果。例如,请查看纽约市照片库演示,其中展示了如何以紧凑的方式沿多列显示照片,同时允许某些项(此示例中的标题)跨多列:

标题跨列显示的图库。

以下是砌体布局的其他一些应用示例。

博客布局,显示每个帖子的缩略图和说明。

一个新闻网站,其文章卡片采用瀑布流布局。
点击此处查看博客演示。

一个新闻网站,其中文章以列的形式显示,有些文章比其他文章宽,主打图片横跨整个页面宽度。

一个新闻网站,其中部分文章跨列显示。
点击此处查看新闻网站演示。

照片集合,具有不同的列大小,某些照片跨多列。

摄影网站瀑布流布局。
点击此处查看自然演示。

权宜解决方法及其局限性

目前,若要在 Web 上实现此设计模式,您需要使用 JavaScript 库或使用 CSS 网格、Flexbox 或多列的权宜解决方法。 不过,这样做可能会带来一些不利影响,包括:

  • 性能较差:依赖 JavaScript 库或自定义代码来模拟 CSS 瀑布流布局会影响性能,从而导致负面的用户体验。
  • 代码复杂性更高:
    • 为了模仿 CSS 瀑布流布局,在 CSS 网格、Flexbox 或多列中确保项的正确放置和空间的分布很难实现。
    • 处理特定功能(例如跨多列或多行的项、项的自定义排序或根据视口进行调整)也可能会导致复杂性和限制。
  • 维护负担更重:复杂的自定义 CSS 或 JavaScript 代码更难维护。

CSS 网格是一种非常灵活的出色布局模式,可让您创建许多不同样式的布局,无论是针对整个网页、组件,还是仅用于对齐各个项。但是,它不具有与砌体相同的特性。

在 CSS 网格中,行和列是严格定义的,项只能存在于网格单元格中。如果您尝试沿其中一个轴打包内容,但内容的大小不适合其各自的单元格,则您必须选择在内容之间留出间隙或拉伸内容以填充空白空间。

网格会将项放置在固定轨道中。

与瀑布流布局一样,Flexbox 只关注一个方向,并让内容决定其在另一个方向上要占据的空间。这意味着,只要您愿意让各项在块方向上一次一列地布局,就可以使用 Flexbox 获得类似于瀑布流布局的布局。Flex 容器还需要定义块大小或高度,以便内容换行到新的 Flex 行,从而创建新列。

按列对内容进行排序的 Flex 布局。

多列还可以创建类似于瀑布流的布局,同样将项排列在列中。此外,多列布局不允许您为每列设置不同的尺寸。它们的大小都相同,而砌体在定义打包项的轨道时提供了很大的灵活性。

这里需要记住的一点是,网格、Flexbox 或多列布局并非比瀑布流布局差。这些布局类型非常实用,有很多应用场景。重点在于:如果您想要的是瀑布流布局,那么 CSS 瀑布流就是您的不二之选。

CSS 瀑布流布局的发展现状

CSS 工作组正在 CSS 网格级别 3 规范中起草瀑布流。该规范仍在制定中,暂时包含两种不同的建议语法。第一种方法为 display 属性使用了一个新关键字,而第二种方法则将瀑布流直接集成到 CSS 网格布局中。

使用 display: masonry

此语法将 CSS 瀑布流作为其自己的 display 类型引入。如需详细了解该方法及其动机,请参阅 Google Chrome 团队发布的博文需要反馈:我们应该如何定义 CSS 瀑布流?,以及本文的其余部分。Chromium 中的当前原型基于此提案。

display: grid; grid-template-*: masonry;

在此语法中,CSS 瀑布流直接集成到 CSS 网格中。在基于行的瀑布流布局中,通过将关键字 masonry 应用于 grid-template-columns 定义来触发瀑布流 模式; 在基于列的瀑布流 布局中,通过将关键字应用于 grid-template-rows 定义来触发瀑布流模式。

如需详细了解此提案及其动机,请参阅 WebKit 帖子帮助我们选择 CSS 中 Masonry 的最终语法。

请注意,此提案的替代方案是 item-pack 属性和 collapse 关键字,它们会触发 CSS 瀑布流,而不是使用两个网格模板属性之一。

自 Chrome 和 WebKit 团队发布帖子以来,CSSWG 一直在讨论要采用的整体语法。您的反馈有助于我们进一步开发这些论坛。

如需详细了解讨论的当前状态,请参阅问题 11593(其中概述了当前的一组瀑布流语法讨论主题)和问题 11243(其中总结了迄今为止的语法争论)。

创建您自己的 CSS 瀑布流布局

让我们来点好玩的,创建一个 CSS 瀑布流布局。

虽然 CSS 瀑布流的语法仍在讨论中,但您现在就可以在 Chromium 中测试我们对该功能的实现,只需启用 CSS 瀑布流布局标志即可,如立即测试 CSS 瀑布流中所述。以下示例演示了开发者试用版中提供的功能。

创建瀑布流容器

如需创建第一个基于列的瀑布流容器,请使用 display:masonry,并使用 grid-template-columns 定义列大小。由于 masonry-direction 默认为 column,因此设置此属性是可选的。

.masonry {
  display: masonry;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 10px;
}
所有列大小相同的瀑布流布局。
在此处查看相同大小的列演示

对于基于行的瀑布流容器,请改用 display:masonry,使用 grid-template-rows 定义行大小,然后设置 masonry-direction:row。

.masonry {
 display: masonry;
 masonry-direction: row;
 grid-template-rows: repeat(auto-fit, minmax(160px, 1fr));
 gap: 10px;
}
所有行大小相同的瀑布流布局。
点击此处查看相同大小行演示

您可能已经注意到,此语法与 Google 的原始提案略有不同。无论 CSS 瀑布流使用何种触发器,CSS 工作组都决定在 CSS 瀑布流布局中重复使用网格模板大小调整和放置属性。

虽然这样可以提高布局类型之间的属性重用率,但您可能会感到困惑,我们非常希望听取您对此主题的意见。我们可能会探索为 grid-template-columns 和 grid-template-rows 等属性创建更通用的别名,例如 template-columns 或 template-rows,这些别名可同时用于网格和瀑布流。

使用默认轨道大小

随着新显示类型的出现,我们有机会重新思考属性默认值。

在网格中,grid-template-columns 和 grid-template-rows 默认为 none,根据当前定义,这通常会生成单列或单行。对于瀑布流,此默认设置通常会导致布局不理想。

Chromium 中的实现添加了新提议的 none 定义,该定义将取代 CSS 瀑布流中的默认轨道大小。此新默认轨道大小为 repeat(auto-fill, auto) 值。此值可创建出色的瀑布流布局,而无需定义轨道大小:

.masonry {
  display: masonry;
  gap: 10px;
}
采用自动调整大小的列的瀑布流布局。
点击此处查看默认轨道大小演示

如图所示,瀑布流容器会创建尽可能多的自动调整大小的列,以适应可用空间。

使用 CSS 网格时,所有项都会在轨道调整大小之前放置,这意味着无法使用此轨道自动调整大小定义。不过,借助 CSS 瀑布流,此限制不再适用,因为放置和大小调整相互交织且简化。解除此限制后,我们便可以为瀑布流布局提供更实用的轨道默认大小。

试用 masonry 简写属性

如前所述,Chromium 中的当前实现依赖于 grid-template-* 属性来定义布局中的瀑布流轨道。不过,由于瀑布流只有一个维度,因此我们还实现了 masonry 简写属性,您可以使用该属性一次性定义瀑布流方向和轨道定义,而无需使用令人困惑的 grid- 前缀属性。

例如,以下两个代码段将创建等效的 CSS 瀑布流容器。

.masonry {
 display: masonry;
 masonry: "a a b" 50px 100px 200px row;
}

.masonry {
  display: masonry;
  masonry-direction: row;
  grid-template-rows: 50px 100px 200px;
  grid-template-areas: "a" "a" "b"
}
包含三行的瀑布流布局,各行尺寸逐渐增大。
点击此处查看瀑布流简写演示

CSS 工作组仍在讨论 masonry 简写形式。欢迎立即试用,并与我们分享您的想法。

使用自定义轨道尺寸

在定义轨道大小时,瀑布流布局与网格布局一样灵活,可让您微调布局轨道的数量和大小。砌体轨道也不必都具有相同的大小,例如:

.masonry {
 display: masonry;
 masonry: repeat(2, 3rem) repeat(auto-fit, 5rem) 12rem;
}
具有各种不同轨道大小的瀑布流布局。
点击此处查看自定义轨道大小演示

在此示例中,我们定义了两个 3rem 轨道,后跟数量不定的 5rem 轨道,最后是一个 12rem 轨道。

跨多个轨道

在瀑布流布局中,项不一定要局限于其所在的轨道,因为它们可以根据需要跨越多个轨道。当某些项比其他项更重要且需要更多空间时,这会非常有用。

例如:

.masonry {
  display: masonry;
  masonry: repeat(auto-fill, minmax(12rem, 1fr));
}

.important-item {
  grid-column: span 2;
}
采用瀑布流布局,其中内容项跨越多个轨道。
在此处查看跨多个轨道的演示

您还可以使用此功能跨多个轨道,使某些项占据容器的整个长度:

.masonry {
 display: masonry;
 masonry: repeat(auto-fill, minmax(12rem, 1fr));
}

.full-bleed {
 grid-column: 1 / -1;
}

新闻网站演示版就是使用此方法在文章中展示订阅广告。

新闻网站布局,其中横幅广告占据了整个区域。

微调瀑布流项位置

在 CSS 瀑布流中,内容会放置在运行位置最短的列或行中。

假设有一个两列的瀑布流容器。如果容器的第一列中有一个 110 像素高的项,第二列中有一个 100 像素高的项,则第三个项将放置在第二列中,距离瀑布流方向的起点更近 10 像素。

两列瀑布流布局。

如果您认为 10 像素的运行位置差异对您的情况来说足够小,并且希望将第三项放在第一列中,以便更好地匹配来源顺序,请使用 item-tolerance 属性。

新的 item-tolerance 属性用于控制商品展示位置的敏感度。

在前面的示例中,您可以将 item-tolerance: 10px; 应用于容器,以自定义项放置位置的变化:

.masonry {
  display: masonry;
  masonry: 200px 200px;
  gap: 10px;
  item-tolerance: 10px;
}
两列瀑布流布局。
在此处查看商品容差演示

请注意,规范草案将此属性称为 item-slack。CSS 工作组最近决定改用 item-tolerance 作为名称,并且该规范很快就会更新。

其他可用属性

您可以使用与 CSS 网格相同的模板大小和放置属性(例如 grid-row、grid-column、grid-area、grid-template-areas 或 order)来调整瀑布流容器网格轴中项的大小和位置。在创建瀑布流布局时,充分体验 CSS 网格的强大功能。

征求反馈

我们迫不及待地想让您探索 CSS 瀑布流,发挥创意,并发现它能帮助您解锁的新功能。一个很好的入门方法是查看我们的演示及其源代码,并开始在 Chromium 中构建您自己的示例(请记得先启用该标志)。

您的反馈非常重要,有助于我们完善该 API,并确保其设计能够满足您在 Web 上的需求。欢迎试用瀑布流布局,并与我们分享您的想法!

如果您对 API 的形式有任何想法或反馈,请在问题 11243 中发表评论,或者如果您更愿意在自己的博客或社交媒体上发表帖子,请务必在 X 或 LinkedIn 上告诉我们。

Chromium 仍在实现 CSS 瀑布流。如果您确实要测试它,请注意,我们仍在积极开发它,您可能会遇到它无法按预期运行的情况。目前的一些限制包括:密集打包、反向放置、子网格支持、流外支持、基线支持、DevTools 支持、分片支持、间隙装饰支持等。

如果您在测试该功能时发现 bug,请通过提交新的 Chromium bug 来分享您的反馈。