实现 Masonry 布局

实现 Masonry 布局

·

1 min read

效果图

以上是效果图,这里使用 grid 布局来实现。

实现

先放完整代码,接着逐个进行解析。

.container {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  grid-gap: 10px;
  height: 300px;
  grid-auto-flow: dense;
}

.item {
  background: rgba(0, 0, 0, 0.2);
  grid-column: span 1;
  grid-row: span 1;
}
.item:nth-child(3) {
  grid-column: span 2;
  grid-row: span 2;
}

容器部分

fr 单位

fraction 的缩写,你可以理解成“份数”,比如有个网格容器,他有两列:grid-template-columns: 1fr 2fr;,第一列占 1 份,第二列占两份,如果总宽度是 300px,那么他们的宽度分别是 100px 和 200px。

在前文例子中的意思是让容器中每一个网格轨道的占用份数相同,让他们自动适应总宽度的变化。

minmax

用于定义网格轨道的最小和最大尺寸,这里的 minmax(300px, 1fr) 表示最小不会小于 300px,最大尺寸根据总宽度自由调整。

repeat

用于生成重复生成一段模式,比如刚刚我们定义了网格轨道的宽度规则,接着可以将他重复 12 次,在水平方向上铺满容器。

auto-fit

用于自动调整网格单元的数量和大小,让他们适应容器尺寸。

用在 repeat 中时,浏览器会尽可能多地去创建列,同时保持每一列的最小宽度,比如 repeat(auto-fit, minmax(200px, 1fr)),当容器宽度为 800px 时,会有 4 列,每一列都是 200px,但当容器宽度为 700px 的时候,只会有 3 列,其中每一列都是 233.33px。

height

在网格布局中,如果给容器一个固定的高度,但没有明确指定行高,那么网格单元的高度会自动计算,以至于填满容器。

grid-gap

网格单元间的间距。

grid-auto-flow

grid-auto-flow 在默认情况下的值是 row,也就是会先填满一行,再考虑下一行,在值为 dense 时,会尝试自动去填充留下的空洞(不保证单元的顺序),看两张图就明白了:


在以上的规则组合下,这个容器就变成了:

  1. 每个列的网格轨道占用的宽度都是相同的,且最小为 300px

  2. 容器宽度可以自由调整

  3. 网格单元会填充满容器,过多时会自动换行

单元部分

grid-column/grid-row

分别定义了网格单元在水平方向上的起始结束位置与在垂直方向上的起始结束位置,两个位置的值可以是数字,代表具体的网格线,比如 grid-column: 1 / 3/ 表示范围,整体的意思是开始于第一条网格线,结束于第三条网格线,跨越了两列。

span 关键字用于直接指定网格单元应该跨越多少行/列,比如 grid-column: span 2 直接指定单元要跨越两列,以单元当前所在的网格线作为起点


例子中默认的网格单元都是 1x1,对于一些特殊的“大方块”,他们可以跨越多格,比如:

.item:nth-child(3) {
  grid-column: span 2;
  grid-row: span 2;
}

Codepen