我需要实现砌体布局。但是,由于多种原因,我不想使用JavaScript进行操作。
参数:
- 所有元素都具有相同的宽度
- 元素具有无法计算的服务器端的高度(图像加各种文本),
- 我可以使用固定数量的列生活,
如果我有一个琐碎的解决方案, 可以在现代浏览器中起作用, column-count-count
属性。
该解决方案的问题是元素在列中排序:
当我需要排成行的元素时,至少至少:
我尝试过的方法那是不起作用的:
现在i 可以更改服务器端渲染并重新排序项目数量的项目列的数量,但这很复杂,容易出错(基于浏览器决定将项目列表拆分为列),因此,如果可能的话,我想避免使用。
是否有一些flexbox魔术可以实现这一目标?
I need to implement a masonry layout. However, for a number of reasons I don't want to use JavaScript to do it.

Parameters:
- All elements have the same width
- Elements have a height that cannot be calculated server side (an image plus various amounts of text)
- I can live with a fixed number of columns if I have to
there is a trivial solution to this that works in modern browsers, the column-count
property.
The problem with that solution is that elements are ordered in columns:

While I need the elements to be ordered in rows, at least approximately:

Approaches I've tried that don't work:
Now I could change the server side rendering and reorder the items dividing the number of items by the number of columns, but that's complicated, error-prone (based on how browsers decide to split the item list into columns), so I'd like to avoid it if possible.
Is there some flexbox magic that makes this possible?
发布评论
评论(4)
我发现这个解决方案,它很可能与所有浏览器兼容。
注意:如果有人发现任何错误或浏览器支持问题。请更新此答案或评论
css proppery支持参考:
列计数,间隙,填充 break-inside , page-break-inside
注意:
page-break-inside
此属性已被break> break-inside
属性所取代。I find This solution, It is most probably compatible with all browsers.
Note: if anyone finds any error or browser support issues. please update this answer Or comments
CSS Profpery Support reference:
column-count, gap, fill break-inside, page-break-inside
Note:
page-break-inside
This property has been replaced by thebreak-inside
property.这是使用CSS
列
的响应方式。注意:元素是按列排序的,而不是按行排序。
here's the responsive way using css
columns
.Note: elements are ordered by column and not by row.
2021更新
CSS网格布局3级3包括
砌体
功能。代码将看起来像这样:
截至2021年3月,它仅在Firefox(激活标志之后)可用。
下面的原始答案
Flexbox
无法使用
flexbox,至少没有以干净有效的方式使用动态砌体布局。 FlexBox是一个一维布局系统。这意味着它可以沿水平或垂直线对齐。弹性项目仅限于其行或列。
真正的网格系统是二维的,这意味着它可以沿水平和垂直线对齐。内容项可以同时跨越行和列跨越,flex项目无法做到。
这就是为什么Flexbox的建筑网格能力有限的原因。这也是W3C开发另一种CSS3技术的原因, grid布局 。
行包裹
在带有
Flex-Flow的Flex容器中:行包裹
,Flex项目必须包装到New Rows 。这意味着 flex项目不能在同一行中的另一个项目下包裹 。
在上面的情况下, div#3 在 div#1 下面包裹,创建一个新行。它不能在 div#2 下包裹。
结果,当项目不是排最高的项目时,空白处仍然存在,从而造成难看的空白。
列包装
如果切换到
flex-flow:column wrap
,一个类似网格的布局更可实现。但是,柱方向容器立即在蝙蝠中有四个潜在的问题:结果,在这种情况下,在许多其他情况下,都不是列方向容器。
CSS网格带有项目尺寸未定义的
网格布局,如果可以预先确定内容项目的各个高度,则是您问题的完美解决方案。所有其他要求都符合网格的能力。
必须知道网格项目的宽度和高度,以便与周围物品缩小差距。
因此,在这种情况下,网格是建造水平砌体布局的最佳CSS所提供的。
实际上,在CSS技术到达具有自动缩小差距的能力之前,CSS通常没有解决方案。这样的事情可能需要将文档进行回流,因此我不确定它将有多有用或有效。
您需要一个脚本。
JavaScript解决方案倾向于使用绝对定位,该定位从文档流中删除内容项,以便在没有间隙的情况下重新安排它们。这里有两个示例:
css grid 带有项目尺寸定义的
布局,其中内容项的宽度和高度已知,这是一个纯CSS中的水平流动砌体布局:
jsfiddle demo
inline-grid
将是其他选项)grid-auto-rows
属性设置自动生成的行的高度。在此网格中,每一行高50px。grid-gap
网格 - 列 - gap
和网格 - 行gap
的速记。该规则在网格项目之间设置了10px Gap 。 (它不适用于项目和容器之间的区域。)网格 - 拼写 - 列
属性设置了明确定义的列的宽度。重复
重复 < /strong> 符号定义了重复列(或行)的模式。auto-fill
函数告诉网格在不溢出容器的情况下将尽可能多的列(或行)对齐。 (这可以与Flex Layout的Flex-wrap:Wrap
。)创建类似的行为。
minmax()
功能为每列(或行)设置最小和最大尺寸范围。在上面的代码中,每列的宽度至少为容器的30%,最大的可用空间的最大值。
fr
frFlex-Grow
属性相当。with
gode> gode> gode> gode> gode> gode> gode> gode> gode> gode> gode> gode> gode> gode> gode> gode> gode> gode>
grid-row
和
< /a>我们正在告诉网格项目,它们应该覆盖多少行。span
2021 Update
CSS Grid Layout Level 3 includes a
masonry
feature.Code will look like this:
As of March 2021, it's only available in Firefox (after activating the flag).
end update; original answer below
Flexbox
A dynamic masonry layout is not possible with flexbox, at least not in a clean and efficient way.
Flexbox is a one-dimensional layout system. This means it can align items along horizontal OR vertical lines. A flex item is confined to its row or column.
A true grid system is two-dimensional, meaning it can align items along horizontal AND vertical lines. Content items can span across rows and columns simultaneously, which flex items cannot do.
This is why flexbox has a limited capacity for building grids. It's also a reason why the W3C has developed another CSS3 technology, Grid Layout.
row wrap
In a flex container with
flex-flow: row wrap
, flex items must wrap to new rows.This means that a flex item cannot wrap under another item in the same row.
Notice above how div #3 wraps below div #1, creating a new row. It cannot wrap beneath div #2.
As a result, when items aren't the tallest in the row, white space remains, creating unsightly gaps.
column wrap
If you switch to
flex-flow: column wrap
, a grid-like layout is more attainable. However, a column-direction container has four potential problems right off the bat:As a result, a column-direction container is not an option in this case, and in many other cases.
CSS Grid with item dimensions undefined
Grid Layout would be a perfect solution to your problem if the various heights of the content items could be pre-determined. All other requirements are well within Grid's capacity.
The width and height of grid items must be known in order to close gaps with surrounding items.
So Grid, which is the best CSS has to offer for building a horizontally-flowing masonry layout, falls short in this case.
In fact, until a CSS technology arrives with the ability to automatically close the gaps, CSS in general has no solution. Something like this would probably require reflowing the document, so I'm not sure how useful or efficient it would be.
You'll need a script.
JavaScript solutions tend to use absolute positioning, which removes content items from the document flow in order to re-arrange them with no gaps. Here are two examples:
CSS Grid with item dimensions defined
For layouts where the width and height of content items are known, here's a horizontally-flowing masonry layout in pure CSS:
jsFiddle demo
How it works
Establish a block-level grid container. (
inline-grid
would be the other option)The
grid-auto-rows
property sets the height of automatically generated rows. In this grid each row is 50px tall.The
grid-gap
property is a shorthand forgrid-column-gap
andgrid-row-gap
. This rule sets a 10px gap between grid items. (It doesn't apply to the area between items and the container.)The
grid-template-columns
property sets the width of explicitly defined columns.The
repeat
notation defines a pattern of repeating columns (or rows).The
auto-fill
function tells the grid to line up as many columns (or rows) as possible without overflowing the container. (This can create a similar behavior to flex layout'sflex-wrap: wrap
.)The
minmax()
function sets a minimum and maximum size range for each column (or row). In the code above, the width of each column will be a minimum of 30% of the container and maximum of whatever free space is available.The
fr
unit represents a fraction of the free space in the grid container. It's comparable to flexbox'sflex-grow
property.With
grid-row
andspan
we're telling grid items how many rows they should span across.This is recently discovered technique involving flexbox: https://tobiasahlin.com/blog/masonry-with- CSS/。
这篇文章对我来说很有意义,但是我没有尝试使用它,所以我不知道是否有任何警告,除了迈克尔的答案中提到。
这是文章中的一个示例,使用
order
属性,与结合:nth-Child
。堆栈片段
This is recently discovered technique involving flexbox: https://tobiasahlin.com/blog/masonry-with-css/.
The article makes sense to me, but I haven't tried to use it, so I don't know if there are any caveats, other than mentioned in Michael's answer.
Here's a sample from the article, making use of the
order
property, combined with:nth-child
.Stack snippet