2021 年更新
CSS Grid Layout Level 3 包含masonry 功能。
代码将如下所示:
grid-template-rows: masonry
grid-template-columns: masonry
截至 2021 年 3 月,它仅在 Firefox 中可用(激活标志后)。
结束更新;下面的原始答案
弹性盒
使用 flexbox 无法实现动态砌体布局,至少不能以一种干净有效的方式。
Flexbox 是一个一维布局系统。这意味着它可以沿水平或垂直线对齐项目。弹性项目仅限于其行或列。
真正的网格系统是二维的,这意味着它可以沿水平和垂直线对齐项目。内容项可以同时跨越行和列,而 flex 项无法做到。
这就是为什么 flexbox 构建网格的能力有限的原因。这也是 W3C 开发另一种 CSS3 技术Grid Layout 的原因。
row wrap
在带有flex-flow: row wrap 的弹性容器中,弹性项目必须换行到新的行。
这意味着一个弹性项目不能在同一行的另一个项目下换行。
注意上面的 div #3 如何包裹在 div #1 之下,创建一个新行。它不能包裹在 div #2 之下。
因此,当项目不是该行中最高的项目时,会留下空白,造成难看的间隙。
column wrap
如果切换到flex-flow: column wrap,则更容易实现类似网格的布局。但是,列方向容器立即存在四个潜在问题:
- 弹性项目垂直流动,而不是水平流动(就像您在这种情况下需要的那样)。
- 容器水平扩展,而不是垂直扩展(如 Pinterest 布局)。
- It requires the container to have a fixed height, so the items know where to wrap.
- 在撰写本文时,它在 the container doesn't expand to accommodate additional columns 的所有主要浏览器中都存在缺陷。
因此,在这种情况下,列方向容器不是一个选项,在许多其他情况下也是如此。
CSS 网格项目尺寸未定义
如果可以预先确定内容项的各种高度,那么网格布局将是您问题的完美解决方案。所有其他要求都在 Grid 的能力范围内。
必须知道网格项目的宽度和高度,以便与周围项目缩小差距。
因此,在这种情况下,网格,它是最好的 CSS 提供的用于构建水平流动的砌体布局的工具。
事实上,在能够自动缩小差距的 CSS 技术问世之前,CSS 通常没有解决方案。像这样的事情可能需要重排文档,所以我不确定它会有多大用处或效率。
你需要一个脚本。
JavaScript 解决方案倾向于使用绝对定位,这会从文档流中删除内容项,以便重新排列它们而没有间隙。这里有两个例子:
Masonry 是一个 JavaScript 网格布局库。它
通过根据可用的元素将元素放置在最佳位置来工作
垂直空间,有点像石匠在墙上装石头。
来源:http://masonry.desandro.com/
[Pinterest] 确实是一个很酷的网站,但我觉得有趣的是这些插板是如何布置的......所以本教程的目的是我们自己重新创建这种响应式块效果......
来源:https://benholland.me/javascript/2012/02/20/how-to-build-a-site-that-works-like-pinterest.html
CSS 网格定义了项目尺寸
对于内容项的宽度和高度已知的布局,这是纯 CSS 中的水平流动砌体布局:
grid-container {
display: grid; /* 1 */
grid-auto-rows: 50px; /* 2 */
grid-gap: 10px; /* 3 */
grid-template-columns: repeat(auto-fill, minmax(30%, 1fr)); /* 4 */
}
[short] {
grid-row: span 1; /* 5 */
background-color: green;
}
[tall] {
grid-row: span 2;
background-color: crimson;
}
[taller] {
grid-row: span 3;
background-color: blue;
}
[tallest] {
grid-row: span 4;
background-color: gray;
}
grid-item {
display: flex;
align-items: center;
justify-content: center;
font-size: 1.3em;
font-weight: bold;
color: white;
}
<grid-container>
<grid-item short>01</grid-item>
<grid-item short>02</grid-item>
<grid-item tall>03</grid-item>
<grid-item tall>04</grid-item>
<grid-item short>05</grid-item>
<grid-item taller>06</grid-item>
<grid-item short>07</grid-item>
<grid-item tallest>08</grid-item>
<grid-item tall>09</grid-item>
<grid-item short>10</grid-item>
<grid-item tallest>etc.</grid-item>
<grid-item tall></grid-item>
<grid-item taller></grid-item>
<grid-item short></grid-item>
<grid-item short></grid-item>
<grid-item short></grid-item>
<grid-item short></grid-item>
<grid-item tall></grid-item>
<grid-item short></grid-item>
<grid-item taller></grid-item>
<grid-item short></grid-item>
<grid-item tall></grid-item>
<grid-item short></grid-item>
<grid-item tall></grid-item>
<grid-item short></grid-item>
<grid-item short></grid-item>
<grid-item tallest></grid-item>
<grid-item taller></grid-item>
<grid-item short></grid-item>
<grid-item tallest></grid-item>
<grid-item tall></grid-item>
<grid-item short></grid-item>
</grid-container>
工作原理
-
Establish a block-level grid container.(
inline-grid 是另一种选择)
-
grid-auto-rows 属性设置自动生成的行的高度。在此网格中,每行的高度为 50 像素。
-
grid-gap 属性是grid-column-gap 和grid-row-gap 的简写。此规则在网格项目之间设置 10px 的间隙。 (不适用于物品和容器之间的区域。)
-
grid-template-columns 属性设置明确定义的列的宽度。
repeat 表示法定义了重复列(或行)的模式。
auto-fill 函数告诉网格在不溢出容器的情况下排列尽可能多的列(或行)。 (这可以创建类似于 flex 布局的 flex-wrap: wrap 的行为。)
minmax() 函数为每列(或行)设置最小和最大大小范围。在上面的代码中,每列的宽度至少是容器的 30%,并且是任何可用空间的最大值。
fr unit 表示网格容器中可用空间的一小部分。它相当于 flexbox 的 flex-grow 属性。
- 通过
grid-row 和span,我们告诉网格项它们应该跨越多少行。
浏览器支持 CSS 网格
- Chrome - 自 2017 年 3 月 8 日起提供全面支持(版本 57)
- Firefox - 自 2017 年 3 月 6 日起提供全面支持(版本 52)
- Safari - 自 2017 年 3 月 26 日起全面支持(版本 10.1)
- Edge - 自 2017 年 10 月 16 日起提供全面支持(版本 16)
- IE11 - 不支持当前规范;支持过时版本
这是完整的图片:http://caniuse.com/#search=grid
Firefox 中酷炫的网格叠加功能
在 Firefox 开发工具中,当您检查网格容器时,CSS 声明中有一个小网格图标。单击它会在页面上显示网格的轮廓。
更多详情:https://developer.mozilla.org/en-US/docs/Tools/Page_Inspector/How_to/Examine_grid_layouts