首先要做的事情:您将无法使用浮动实现柱状包装布局:正如其他评论者所指出的那样,浮动不是这样工作的。CSS 中也没有“自动砌体布局”模块,我怀疑这是您真正想要的。我还假设单独放置每个项目是不可能的。
您将获得的最接近的东西是网格布局——我们将在最后谈到这一点。剧透:这真的很酷,但是浏览器支持真的很好之前还需要一段时间。
所以,TL;DR:没有跨浏览器的方法可以在 CSS 中进行智能的、逐行的、类似砌体的布局。但是网格布局非常接近。如果你迫不及待,请使用 JS 或将设计切换为适用于包装列的设计。
如果你选择 JS 路由,你可以使用Grid Layout JS polyfill!这样,您现在可以编写网格布局语法,并在将来某个时候不再需要它时删除 polyfill。
具有多列的列式布局
从其他答案和评论来看,柱状环绕布局并不是您想要的。万一你仍然决定走那条路,你可以用Multi Column layout来做。支持非常好:除了 IE<10,几乎所有的东西。
一个简单的示例,以防万一您想将布局更改为多列方向:这是一个具有 2 列多列布局的 JSBin。请注意,您不需要同时设置column-count
and column-width
:设置 a column-count
(and column-gap
),其余的将自行排序。
哦,如果你得到带有边距的错误渲染(例如,边距环绕新列,创建不均匀的布局),通常的解决方法是display: inline-block; width: 100%;
在.module
. 您的里程可能会有所不同:对于已经存在很长时间的东西,multicol 肯定是错误的。
使用 flexbox 的列式布局
再坚持一下柱状布局,你也可以使用 flexbox。(我看到另一个关于 Flexbox 的答案,但遗憾的是,这是一种完全过时的语法,在现代浏览器中不起作用)。
在 multi-col 与 flexbox 中包装成列之间的区别在于 flexbox 不会为您将项目平衡到列中(它并不是真正为那种类型的布局而设计的),因此您需要设置特定的高度以强制列包裹。如果您有一个容器元素 ( .container
) 和其中的.module
项目,则以下是基本方法:
.container {
display: flex;
flex-flow: column wrap;
height: 1000px; /* or whatever works for you */
}
.module {
/* whatever props you want for modules */
}
...不计算 IE10 的前缀和语法变体,它使用了稍旧的规范变体。(还有旧的 flexbox,它不支持 flex wrapping,所以我们会忘记它)。简单的 JSBin 包装 flexbox 示例在这里。
使用网格布局自动放置的密集包装
最后,我们进入网格布局。这个新规范有一些非常酷的特性,允许我们做一些接近“砌体”布局的事情。
注意:您需要在 Chrome Canary、WebKit Nightly 或 Firefox 开发者版中查看这些示例。在 IE10+(以及 Edge)中有一个旧的 Grid Layout 实现,但它不包含我们需要的所有新的 hotness属性。
首先是标记:我们将使用一个包装器元素 +.module
里面的项目(包装器不是绝对必要的——我们可以将模块直接放入body
,但我只是觉得这样更清楚):
<div class="container">
<div class="module"></div>
<div class="module"></div>
<!-- and so on -->
</div>
接下来,我们告诉容器是一个网格容器:
.container {
display: grid;
}
然后我们将它设置为具有 2 个等宽列(1 个“小数单位”)的列的“模板”,以及列之间的间隙以及 20px 的行:
.container {
display: grid;
/* 2 columns, equally wide: */
grid-template-columns: 1fr 1fr;
/* gaps between each column and row. */
grid-column-gap: 20px;
grid-row-gap: 20px;
/* ...can also be shortened to grid-gap: 20px; */
}
我们还没有给它一个行模板,但我们只需要让它根据需要自动创建它们。为此,我们设置grid-auto-rows
属性,以50px
根据需要添加尽可能多的高行:
.container {
display: grid;
grid-template-columns: 1fr 1fr;
grid-column-gap: 20px;
grid-row-gap: 20px;
/* automatically create rows, 50px tall each: */
grid-auto-rows: 50px;
}
在这一点上,我们还没有在容器中放置任何项目,至少没有明确地放置。使用网格,您可以准确指定项目应属于网格的哪个区域。问题是,您不必这样做!除非您另有说明,否则网格将自动将它们放置在第一个可用插槽中,从左上角开始并默认逐行排列。
相反,我们需要告诉它有些项目比其他项目大。我们不为此使用大小,而是告诉奇数项目跨越 2 行,每 3 个项目跨越 4 行。
.module {
background: yellow;
}
.module:nth-child(odd) {
grid-row: span 2;
background: green;
}
.module:nth-child(3n) {
grid-row: span 4;
background: orange;
}
最后,我们需要告诉网格使用“密集”算法,这意味着它将对每个项目进行一次放置传递,试图避免在自动放置中产生“洞”。
.container {
display: grid;
grid-template-columns: 1fr 1fr;
grid-column-gap: 20px;
grid-row-gap: 20px;
grid-auto-rows: 50px;
/* use the "dense" algorithm: */
grid-auto-flow: row dense;
}
这为我们提供了非常接近“砌体”布局的东西,正如在密集网格布局的 JSBin 示例中所看到的那样——再次注意,您将需要 Chrome/WebKit 或 Firefox 的 nightly/dev 版本来查看它是如何工作的。
这是在 Chrome Canary 中查看的结果图像:
需要注意的一些事项:
- 打包算法在这里
row dense
并没有真正的区别,因为这些物品碰巧堆叠在一起,没有留下任何洞,但我把它放在那里是为了完整性。
- 如您所见,最后一行有一个单独的项目——网格不能神奇地调整大小(例如 jQuery Masonry 插件),它只能根据网格位置或跨度来调整大小。这不是装箱算法布局的灵丹妙药。也就是说,一旦你掌握了它,它就会变得非常强大和有趣。在一年左右的时间内(我猜最多),它将出现在所有主要(常绿)浏览器中。