Flexbox 和 grid 两种方案实现多行多列布局

5,841 阅读3分钟

需求

要实现一个多行多列的布局,每行 4 列,行数不固定,如下图所示:

怎么实现

方案一:flexbox

一般来说,涉及到多列,首先想到的是 flexbox. 尤其是常见的两行多列布局,flex 屡试不爽。

假设 HTML 是这样的:一个容器元素(classbox)里有十个子元素(classbox-item)。

这个四行多列,先用 flex 实现看看。

CSS 代码如下:

.box {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
}

.box .box-item {
  width: 100px;
  margin-bottom: 10px;
}

效果如下图:

从上图可见,justify-content: space-between; 优雅地令元素平分整行的宽度。

可是如最后一行所示,当元素无法占满一行之时,布局却不尽人意,我们希望最后一行的元素是左对齐的。

修复一下看看。

改造后的 flexbox

.box {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-start;
}

.box .box-item {
  width: 100px;
  margin-bottom: 10px;
  margin-right: 10px;
}

.box .box-item:nth-of-type(4n) {
  margin-right: 0;
}

这里用 justify-content: flex-start; 来实现元素的左对齐。然后在子元素上加 margin-right: 10px; 来保证同一行的元素之间有空隙。

效果如下:

可以看到,最后一行的元素也是左对齐的。

注意到,上面有这样的代码:

.box .box-item:nth-of-type(4n) {
  margin-right: 0;
}

.box-item:nth-of-type(4n) 选中了第 4n 个子元素,即第 4 个,第 8 个。因为这些元素都是行尾的元素,需要令它们的 margin-right0, 不然行宽会大于容器宽度,导致元素被挤到下一行,如图:

怪不得 flexbox 中文名叫做弹性布局,果然很弹。

这里的 flexbox 实现了四列多行的布局。线上 Demo 点这里

可以看到代码不仅要设置容器的样式,还要设置子元素的样式,一大堆。

有没有更为简洁优雅的解决方案呢?请看接下来的 grid 布局。

方案二:grid 布局

grid 布局,中文名是网格布局。顾名思义,它可以让元素像网格一样呈现,网格自身就是多行多列的。

接下来用 grid 实现四行多列的布局:

.box {
  display: grid;
  grid-template-columns: repeat(4, 100px);
  grid-column-gap: 10px;
  grid-row-gap: 10px;
}

实现如图所示:

可以看到,利用 grid 布局,只设置容器的样式,就能够实现多行多列布局。线上 Demo 点这里

代码中, grid-template-columns: repeat(4, 100px); 定义了 grid 布局中列的规则。其中 repeat 是一个函数,它接收两个参数,第一个是重复的次数,第二个是重复的值。 grid-template-columns: repeat(4, 100px); 相当于 grid-template-columns: 100px 100px 100px 100px;.

grid-column-gap: 10px;grid-row-gap: 10px; 分别定义了 grid 布局中列之间的间隔以及行之间的间隔。

兼容性

Grid

若使用一些相对较新的 CSS 特性,不得不考虑的一个点就是兼容性,下面来看看 grid 布局的兼容性。

下图是 caniuse 网站的查询结果:

图上绿色的部分代表浏览器支持,一片绿,表示还是有不少浏览器支持的。Chrome 和 Firefox 根本不用担心。

Flexbox

Flexbox 兼容性:

由图可知,flexbox 的兼容性明显好于 grid 布局。

总结

本文介绍了两种实现多行多列布局的方案,分别是 flexbox 和 grid.

从代码层面来说,grid 的实现要比 flexbox 更加简洁。

从兼容性来说,更多的浏览器支持 flexbox.

参考

[1] 阮一峰.CSS Grid 网格布局教程

[2] MDN.grid-template-columns