只有CSS的砌体布局,但水平排列元素

我需要实现一个相当普通的砌体布局。 但是,由于一些原因,我不想使用JavaScript来做到这一点。

在这里输入图像描述

参数:

  • 所有的元素都有相同的宽度
  • 元素的高度不能计算在服务器端(一个图像加上不同数量的文本)
  • 如果必须的话,我可以生活在固定数量的专栏中

有一个简单的解决scheme,可以在现代浏览器中使用column-count属性。

该解决scheme的问题是元素按列sorting:

在这里输入图像描述

虽然我需要sorting的元素,至less大约:

在这里输入图像描述

我尝试过的方法不起作用:

  • 制作项目display: inline-block : 浪费垂直空间。
  • 制作项目float: left : 大声笑,没有。

现在,我可以更改服务器端渲染,并重新排列项数除以列数的项目,但这是复杂的,容易出错(基于浏览器如何决定将项目列表拆分成列),所以我想如果可能的话避免它。

有没有一些新的灵活的魔术,使这成为可能?

Flexbox的

至less不是以一种干净而有效的方式,灵活的砌体布局是不可能的。

Flexbox是一种一维布局系统。 这意味着它可以沿水平或垂直线alignment项目。 Flex项目被限制在其行或列中。

真正的网格系统是二维的,这意味着它可以沿着水平线和垂直线alignment项目。 内容项目可以同时跨行和列,这是Flex项目无法做到的。

这就是为什么flexbox的网格build设能力有限。 这也是W3C开发另一个CSS3技术Grid Layout的原因


row wrap

在具有flex-flow: row wrap的柔性容器中flex-flow: row wrap柔性项目必须换到新

这意味着Flex项目不能包装在同一行中的另一个项目下

在这里输入图像描述

注意上面的div#3是如何在div#1下面包装的,创build一个新的行。 它不能包装在div#2下面。

结果,当物品不是最高的时候,空白仍然存在,造成难看的差距。

在这里输入图像描述


column wrap

如果切换到flex-flow: column wrap ,则可以获得类似网格的布局。 然而,一个列方向的容器有四个潜在的问题:

  1. Flex项目垂直stream动,而不是水平(如你在这种情况下需要)。
  2. 该容器水平扩展,而不是垂直(如Pinterest布局)。
  3. 它要求容器有一个固定的高度,所以项目知道在哪里包装。
  4. 在撰写本文时,在所有主要浏览器中,容器不能扩展以容纳其他列的缺陷。

因此,在这种情况下,在许多其他情况下,列方向容器不是一种select。


项目尺寸未定义的 CSS网格

网格布局将是一个完美的解决scheme, 如果内容项目的各种高度可以预先确定你的问题。 所有其他要求都在网格的能力范围内。

网格物品的宽度和高度必须是已知的,以缩小与周围物品的距离。

因此,在这种情况下,Grid是build立水平stream动的砌体布局所需的最好的CSS。

事实上,在CSS技术到来之前能够自动缩小差距,CSS一般没有办法解决。 像这样的东西可能需要回stream文件,所以我不知道这将是多么有用或有效。

你需要一个脚本。

JavaScript解决scheme倾向于使用绝对定位,即从文档stream中删除内容项目,以便无间隙地重新排列它们。 这里有两个例子:

  • Desandro砌体

    砌体是一个JavaScript网格布局库。 它的工作原理是根据可用的垂直空间将元素放置在最佳位置,有点像镶嵌在墙上的石匠。

    来源: http : //masonry.desandro.com/

  • 如何build立一个像Pinterest一样工作的网站

    Pinterest的确是一个很酷的网站,但是我觉得有趣的是这些插件是如何布置的…所以本教程的目的是重新创build这个响应块效果。

    来源: https : //benholland.me/javascript/2012/02/20/how-to-build-a-site-that-works-like-pinterest.html


具有已定义项目维度的 CSS网格

对于内容项宽度和高度已知的布局,以下是纯CSS中的水平stream动砌体布局:

 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>