如何使用CSS创建基于行的砖石布局?

dfddblmv  于 2023-01-27  发布在  其他
关注(0)|答案(4)|浏览(140)

我需要实现一个砖石结构的布局。但是,由于一些原因,我不想使用JavaScript来实现它。

参数:

  • 所有元素具有相同的宽度
  • 元素具有无法在服务器端计算的高度(图像加上各种数量的文本)
  • 如果需要,我可以使用固定的列数

有一个在现代浏览器the column-count property.中工作的简单解决方案
该解决方案的问题在于元素按列排序:

虽然我需要元素按行排序,但至少大致是这样:

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

现在我 * 可以 * 更改服务器端呈现并重新排序项目,将项目数除以列数,但这很复杂,容易出错(基于浏览器如何决定将项目列表拆分为列),所以如果可能的话,我希望避免使用它。
是否有一些flexbox魔术,使这成为可能?

monwx1rj

monwx1rj1#

2021更新

CSS网格布局级别3包含masonry功能。
代码如下所示:

grid-template-rows: masonry
grid-template-columns: masonry

截至2021年3月,它只在Firefox中可用(激活国旗后)。

柔性盒

动态砖石布局是不可能的flexbox,至少不能在一个干净和有效的方式。
弹性框是一维布局系统。这意味着它可以沿水平线或垂直线对齐项目。弹性项目被限制在其行或列中。
真正的网格系统是二维的,这意味着它可以沿水平线和垂直线对齐项。内容项可以同时跨越行和列,而Flex项不能做到这一点。
这就是为什么flexbox构建网格的能力有限,也是为什么W3C开发了另一种CSS3技术Grid Layout的原因。

一个月一个月

flex-flow: row wrap的flex容器中,flex项必须换到新的 * 行
这意味着
弹性项目不能在同一行中的另一个项目下换行*。

注意上面 * div #3 * 是如何在 * div #1 * 下面换行的,创建了一个新行。它不能在 * div #2 * 下面换行。
因此,当项目不是行中最高的项目时,空白会保留下来,从而产生难看的间隙。

column wrap

如果您切换到flex-flow: column wrap,则更容易获得类似网格的布局。但是,列方向容器立即存在四个潜在问题:

  1. Flex项目垂直流动,而不是水平流动(就像您在本例中需要的那样)。
    1.容器水平展开,而不是垂直展开(与Pinterest布局类似)。
  2. It requires the container to have a fixed height, so the items know where to wrap.
    1.在撰写本文时,它在所有主流浏览器中都存在缺陷。
    因此,在这种情况下以及在许多其他情况下,列方向容器都不是一个选项。

CSS网格 * 未定义项目维度 *

网格布局将是一个完美的解决方案,您的问题 * 如果各种高度的内容项目可以预先确定 *。所有其他要求都在网格的能力范围内。
网格项目的宽度和高度必须已知,以便与周围项目闭合间隙。
因此,Grid(CSS为构建水平流动的砖石布局所提供的最佳工具)在这种情况下显得力不从心。
事实上,在CSS技术能够自动填补空白之前,CSS通常没有解决方案。像这样的事情可能需要重排文档,所以我不确定它是否有用或有效。
你需要一个剧本。
JavaScript解决方案倾向于使用绝对定位,它从文档流中删除内容项,以便重新排列它们,使它们之间没有间隙。

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

[Pinterest]真的是一个很酷的网站,但我觉得有趣的是这些插接板是如何布局的...所以本教程的目的是重新创建这种响应块效果自己...

CSS网格 *,已定义项目维度 *

对于内容项的宽度和高度已知的布局,下面是一个纯CSS的水平流砖石布局:
x一个一个一个一个x一个一个二个x
∮ ∮ ∮ ∮

    • 如何运作**

1.建立块级网格容器(inline-grid是另一个选项)。
1.* * grid-auto-rows*属性设置自动生成行的高度。在此网格中,每行的高度为50px。
1.
* grid-gap*属性是grid-column-gapgrid-row-gap的缩写。此规则在 * 网格项目之间设置10px的间距。(它不适用于项目和容器之间的区域。)
1.
* grid-template-columns**属性设置显式定义的列的宽度。

    • repeat**符号定义了重复列(或行)的模式。
    • auto-fill**函数告诉网格在不溢出容器的情况下排列尽可能多的列(或行)。(这可以创建与flex布局的flex-wrap: wrap类似的行为。)
    • minmax()**函数为每列(或行)设置最小和最大大小范围。在上面的代码中,每列的宽度最小为容器的30%,最大为可用空间。
    • fr**单位表示网格容器中可用空间的一部分,相当于flexbox的flex-grow属性。

1.使用**grid-rowspan**,我们告诉网格项它们应该跨越多少行。

    • CSS网格的浏览器支持**
  • Chrome浏览器-自2017年3月8日起全面支持(版本57)
  • Firefox-自2017年3月6日起完全支持(版本52)
  • Safari-自2017年3月26日起完全支持(版本10.1)
  • Edge-自2017年10月16日起全面支持(版本16)
  • IE11-不支持当前规范;支持过时版本

以下是完整的情况:www.example.comhttp://caniuse.com/#search=grid

    • Firefox中很酷的网格覆盖功能**

在Firefox开发工具中,当你检查网格容器时,在CSS声明中有一个很小的网格图标,点击它会在页面上显示网格的轮廓。

更多详情请点击此处:https://developer.mozilla.org/en-US/docs/Tools/Page_Inspector/How_to/Examine_grid_layouts

bq9c1y66

bq9c1y662#

这是最近发现的技术涉及flexbox:https://tobiasahlin.com/blog/masonry-with-css/.
这篇文章对我来说有意义,但我还没有尝试使用它,所以我不知道是否有任何警告,除了迈克尔的回答中提到的。
下面是本文中的一个示例,它结合使用了order属性和:nth-child
堆栈代码段

.container {
  display: flex;
  flex-flow: column wrap;
  align-content: space-between;
  /* Your container needs a fixed height, and it 
   * needs to be taller than your tallest column. */
  height: 960px;
  
  /* Optional */
  background-color: #f7f7f7;
  border-radius: 3px;
  padding: 20px;
  width: 60%;
  margin: 40px auto;
  counter-reset: items;
}

.item {
  width: 24%;
  /* Optional */
  position: relative;
  margin-bottom: 2%;
  border-radius: 3px;
  background-color: #a1cbfa;
  border: 1px solid #4290e2;
  box-shadow: 0 2px 2px rgba(0,90,250,0.05),
    0 4px 4px rgba(0,90,250,0.05),
    0 8px 8px rgba(0,90,250,0.05),
    0 16px 16px rgba(0,90,250,0.05);
  color: #fff;
  padding: 15px;
  box-sizing: border-box;
}

 /* Just to print out numbers */
div.item::before {
  counter-increment: items;
  content: counter(items);
}

/* Re-order items into 3 rows */
.item:nth-of-type(4n+1) { order: 1; }
.item:nth-of-type(4n+2) { order: 2; }
.item:nth-of-type(4n+3) { order: 3; }
.item:nth-of-type(4n)   { order: 4; }

/* Force new columns */
.break {
  flex-basis: 100%;
  width: 0;
  border: 1px solid #ddd;
  margin: 0;
  content: "";
  padding: 0;
}

body { font-family: sans-serif; }
h3 { text-align: center; }
<div class="container">
  <div class="item" style="height: 140px"></div>
  <div class="item" style="height: 190px"></div>
  <div class="item" style="height: 170px"></div>
  <div class="item" style="height: 120px"></div>
  <div class="item" style="height: 160px"></div>
  <div class="item" style="height: 180px"></div>
  <div class="item" style="height: 140px"></div>
  <div class="item" style="height: 150px"></div>
  <div class="item" style="height: 170px"></div>
  <div class="item" style="height: 170px"></div>
  <div class="item" style="height: 140px"></div>
  <div class="item" style="height: 190px"></div>
  <div class="item" style="height: 170px"></div>
  <div class="item" style="height: 120px"></div>
  <div class="item" style="height: 160px"></div>
  <div class="item" style="height: 180px"></div>
  <div class="item" style="height: 140px"></div>
  <div class="item" style="height: 150px"></div>
  <div class="item" style="height: 170px"></div>
  <div class="item" style="height: 170px"></div>
  
  <span class="item break"></span>
  <span class="item break"></span>
  <span class="item break"></span>
</div>
cbwuti44

cbwuti443#

我发现这个解决方案,它是最有可能与所有浏览器兼容.

    • 注意:如果任何人发现任何错误或浏览器支持问题,请更新此答案或评论**
    • CSS专业支持参考:**

column-count, gap, fillbreak-insidepage-break-inside
注意:page-break-inside此属性已替换为break-inside属性。

.container {
  -moz-column-count: 1;
       column-count: 1;
  -moz-column-gap: 20px;
       column-gap: 20px;
  -moz-column-fill: balance;
       column-fill: balance;
  margin: 20px auto 0;
  padding: 2rem;
}
.container .item {
  display: inline-block;
  margin: 0 0 20px;
  page-break-inside: avoid;
  -moz-column-break-inside: avoid;
       break-inside: avoid;
  width: 100%;
}
.container .item img {
  width: 100%;
  height: auto;
}
@media (min-width: 600px) {
  .container {
    -moz-column-count: 2;
         column-count: 2;
  }
}
@media (min-width: 900px) {
  .container {
    -moz-column-count: 3;
         column-count: 3;
  }
}
@media (min-width: 1200px) {
  .container {
    -moz-column-count: 4;
         column-count: 4;
  }
}
CSS-Only Masonry Layout 
  
<div class="container">
  <div class="item"><img src="https://placeimg.com/600/400/animals" alt=""></div>
  <div class="item"><img src="https://placeimg.com/600/600/arch" alt=""></div>
  <div class="item"><img src="https://placeimg.com/600/300/nature" alt=""></div>
  <div class="item"><img src="https://placeimg.com/600/450/people" alt=""></div>
  <div class="item"><img src="https://placeimg.com/600/350/tech" alt=""></div>
  <div class="item"><img src="https://placeimg.com/600/800/animals/grayscale" alt=""></div>
  <div class="item"><img src="https://placeimg.com/600/650/arch/sepia" alt=""></div>
  <div class="item"><img src="https://placeimg.com/600/300/nature/grayscale" alt=""></div>
  <div class="item"><img src="https://placeimg.com/600/400/people/sepia" alt=""></div>
  <div class="item"><img src="https://placeimg.com/600/600/tech/grayscale" alt=""></div>
  <div class="item"><img src="https://placeimg.com/600/200/animals/sepia" alt=""></div>
  <div class="item"><img src="https://placeimg.com/600/700/arch/grayscale" alt=""></div>
</div>
pftdvrlh

pftdvrlh4#

最后一个CSS的解决方案,可以轻松地创建砖石布局,但我们需要耐心,因为目前还没有支持它。
此功能是在CSS网格布局模块级别3中引入的
本模块介绍砖石布局作为CSS网格容器的附加布局模式。
然后
通过为网格容器的一个轴指定值砖石,网格容器支持砖石布局。此轴称为砖石轴,另一个轴称为网格轴。
一个基本的例子是:

.container {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  grid-template-rows: masonry; /* this will do the magic */
  grid-gap: 10px;
}

img {
  width: 100%;
}
<div class="container">
  <img src="https://picsum.photos/id/1/200/300">
  <img src="https://picsum.photos/id/17/200/400">
  <img src="https://picsum.photos/id/18/200/100">
  <img src="https://picsum.photos/id/107/200/200">
  <img src="https://picsum.photos/id/1069/200/600">
  <img src="https://picsum.photos/id/12/200/200">
  <img src="https://picsum.photos/id/130/200/100">
  <img src="https://picsum.photos/id/203/200/100">
  <img src="https://picsum.photos/id/109/200/200">
  <img src="https://picsum.photos/id/11/200/100">
</div>

如果您按如下所述启用该功能,将在Firefox上产生以下结果:https://caniuse.com/?search=masonry
1.打开Firefox并在URL栏中写入:config
1.用砖石建筑进行搜索
1.你会得到一面旗,让它成真

如果我们缩小屏幕,React部分是完美的!

相关问题