在 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 的一个演示
很棒的文章,Chris!我最近在桌面上遇到的与网格相关的挑战是一个用例,其中移动设备的顺序需要与桌面布局不同,但您希望将内容按 DOM 中的重要性顺序排列。
我挑战自己只使用 CSS(最终产品中必须使用 JS 中的一行代码来启动它)。
我在这里写了一篇关于我的解决方案的文章:http://joshpalmeri.com/blog/2018/10/01/complex-layouts-with-css-grid-or-flexbox-or-neither-2/
很想知道您的想法!
-Josh
我喜欢原始的砌体库,但看起来当元素换行时,列不会扩展以填充空缺空间。有什么解决方法吗?
“打乱顺序”的例子并不是因为使用了 Flexbox、Masonry 或其他任何东西。出于某种原因,JS 代码只是随机打乱了子元素的顺序(通过赋予它们一个等于其索引模 3 的
order
属性值)。请注意,它从 1、4、7、10、13 开始递增,然后又回到 2、5、8、11 等递减。我不知道它为什么这么做;高度已经随机了,所以它不像是在帮助平衡它们或其他什么。“网格布局,使用密集自动放置”是我最喜欢的技巧,我希望我们能够让它在“小行高”版本中更好地工作。最终,这可能需要作为与网格布局分离的、基于相同概念的东西来处理。
总结得很好!Colcade 也应该得到推广(DeSandro 的另一个疯狂创作)。
正如他所说
示例,基于这篇文章中的示例修改而来
PS。喜欢新的网站!所有细节都处理得非常棒。不过,我想我发现了一个小问题。评论中的链接(至少在预览中)悬停时看起来很棒,但在其他情况下则无法区分。需要一条细细的橙色到粉色的渐变下划线或类似的东西 :)
还有 CSS 多列布局,Rachel Andrew 撰写了一篇深入的文章(https://www.smashingmagazine.com/2019/01/css-multiple-column-layout-multicol/),其中也涵盖了一些关于砌体布局的内容。
是的!非常有用。这是本文中的第一个演示。
React spring 非常棒
https://codesandbox.io/embed/26mjowzpr
我最近为客户开发了一个使用https://packery.metafizzy.co的砌体布局网站。这对于重新排序以及存储和检索顺序非常有帮助。
Magic Grid 也有一个 Vue.js 版本:https://github.com/imlinus/Vue-Magic-Grid
去年,我在使用原始 Masonry 填充包含不同宽度和高度图像的网格时遇到了一些问题。我在 React 中写了关于这些问题以及如何解决它们的文章https://www.damiannicholson.com/posts/2018/07/14/creating-a-layout-like-pinterest-with-react-and-the-partition-problem/,因为您希望图像能够紧密排列,并且底部边缘整齐,同时还要保留图像的长宽比(即不拉伸图像)。
大家好。几乎我每隔一个项目都需要用到砌体布局样式。我最近发现了一个对 Masonry 进行的小幅重写,它是一个非常小的 js 文件,结合了 flexbox。如果有人感兴趣,可以查看一下
https://columnsjs.com
它在 IE 以及所有其他现代浏览器中都能正常工作。
干杯
https://github.com/paulcollett/vue-masonry-css
来自 Guido Jansen
基于单个像素的网格让我有点不适应。它似乎性能不是很好,尤其是在窗口的
resize
事件处理程序中,但它确实很巧妙。