CSS 砌体布局的方法

Avatar of Chris Coyier
Chris Coyier

DigitalOcean 为您旅程的每个阶段提供云产品。立即开始使用 200 美元的免费积分!

在 Web 上,砌体布局是指将大小不一的项目排列起来,使其不会出现不均匀的间隙。我猜这个术语是由 David DeSandro 为 Web 创造(或至少推广)的,因为他流行的 Masonry JavaScript 库自 2010 年以来一直存在。

JavaScript 库。并非反对 JavaScript,但可以理解我们可能不想依赖它来进行布局。如今我们是否可以在 CSS 中直接做些什么?有点。

垂直顺序加上参差不齐的底部可以吗?

如果可以,那么 CSS 列就可以很好地完成工作。

Flexbox 也可以创建带有参差不齐结尾的垂直列

但它不太聪明,因为您需要设置某种高度才能使其换行列。您还必须明确指定宽度,而不是让它为您决定列。

但这是可行的,如果空间足够,它会自动调整间隙。

您需要干净的底部边缘吗?Flexbox/JavaScript 组合可以提供帮助。

Jamie Perkins 最初编写了此代码,然后 Janosh Riebesell 重新编写了它,现在我将其移植到这里。

它完全弄乱了顺序,并且要求子元素对自身高度灵活,但它确实起到了作用。

水平线砌体可以吗?

如果您只是想要不规则的砖块外观,那么水平砌体要容易得多。如果您不关心参差不齐的边缘,甚至可以使用浮动元素。如果您想保持块状… 允许使用 flex-grow 的 flexbox 是最佳选择。

您可能会认为 CSS 网格可以提供帮助

CSS 网格非常棒,在 CSS 开发人员的日常生活中非常有用,但它并非真正为砌体样式布局而设计。CSS 网格用于定义线条并在这些线条上放置元素,而砌体布局则允许元素在其可能结束的位置结束,但仍会施加一些位置影响。

Balázs Sziklai 提供了一个很好的自动流式网格示例,这些网格都很好地堆叠在一起,并且具有很好的水平排序

但您可以看到线条有多严格。不过有一种方法!

网格 + JavaScript 操作的行跨度

Andy Barefoot 撰写了一份很棒的指南。诀窍是设置相当短的重复网格行,让元素根据需要水平落入网格中,然后调整其高度以匹配网格,并进行一些相当简单的计算来确定它们应该跨越多少行。

Rahul Arora 也走过这条路

这两者都非常酷,因为 DOM 顺序和视觉顺序都是有意义的。

Flexbox 布局中顺序发生变化的元素

通常,当您想到使用order在 flexbox 或网格布局中移动元素时,您处于危险区域,因为选项卡顺序可能会遵循 DOM 顺序,而 DOM 顺序不再与预期的选项卡顺序匹配,因为视觉上元素四处移动。在此由 Diederik van Leeuwen 演示的示例中,order用于创建最初为列方向的 flexbox,但通过一些巧妙的 JavaScript 操作将其转换为水平排序。

CSS 列布局中 DOM 顺序发生变化的元素

人们通常想要的是列堆叠(元素高度各不相同),但具有水平排序。上面最后一个网格演示很好地处理了它,但这不是唯一的方法。

Jesse Korzan 使用 CSS 列解决了这个问题。它 也需要 JavaScript才能完成。在这种情况下,它会移动 DOM 中的元素以按从左到右的顺序排列它们,同时使用 CSS 列布局提供水平堆叠。这会带来一些可访问性问题,因为视觉顺序(从左到右)和源顺序(从上到下)存在很大差异‐ 尽管也许可以使用编程方式的tabindex来解决?

还有原始库和变体

浮动,我的美人。

以及它更新、更流行的版本:Colcade

这里还有 MagicGrid,其中使用 JavaScript 库对 flexbox 布局进行了轻微操作。

CSS Houdini!

Houdini 被分解成不同的 API,这些 API 都会 在不同的时间发布。Paint 和 Typed OM API 发展得最远,但对 Layout API 也有一些支持,这令人难以置信地令人兴奋,因为它解锁了诸如砌体布局等可能性。flex-gro

这里有 Google 的一个演示