CSS终极对决:Grid vs Flexbox
由 Mux 主办的 DEV 全球展示挑战赛:展示你的项目!
在过去几年里,CSS Flexbox 在前端开发人员中变得非常流行。这并不奇怪,因为它让我们能够更轻松地创建动态布局并在容器内对齐内容。
然而,现在出现了一种名为 CSS Grid 的新技术,它拥有与 Flexbox 类似的许多功能。在某些情况下,它比 Flexbox 更胜一筹,而在另一些情况下则不然。
这似乎是开发者们感到困惑的地方。因此,本文将从微观和宏观两个层面比较这两个模块。
如果你想认真学习这两个模块,请查看我的免费课程CSS Grid和CSS Flexbox。
现在我们开始吧!
一维与二维
如果你只能从这篇文章中记住一个教训,那就记住这一点:
Flexbox 适用于一维布局,而 Grid 适用于二维布局。
这意味着,如果您要沿一个方向布局元素(例如,在标题中放置三个按钮),则应该使用 Flexbox:
它比 CSS Grid 更灵活,也更容易维护,所需的代码量也更少。
但是,如果您要创建一个完整的二维布局(包含行和列),那么您应该使用 CSS Grid:
在这种情况下,CSS Grid 将为您提供更大的灵活性,使您的标记更简单,代码也更容易维护。
当然,你可以将两者结合起来。在上面的例子中,使用 Grid 布局页面,然后用 Flexbox 来对齐页眉内的内容,就非常理想。这样就能兼具两者的优点。本文末尾我会详细讲解具体操作方法。
内容优先 vs 布局优先
两者之间的另一个核心区别在于,Flexbox 基于内容,而 Grid 基于布局。这听起来可能有点抽象,所以让我们来看一个具体的例子,这样更容易理解。
我们将使用上一段的标题。以下是相应的 HTML 代码:
<header>
<div>Home</div>
<div>Search</div>
<div>Logout</div>
</header>
在将其转换为 Flexbox 布局之前,这些 div 元素会像这样彼此堆叠:

我添加了一些基本样式,但这与 Flexbox 或 Grid 无关,所以我就不赘述了。
Flexbox 标题
但是,当我们给它一个按钮时,display: flex;物品就会整齐地排列成一行。
header {
display: flex;
}
要将注销按钮移到最右侧,我们只需选中该元素并为其添加边距:
header > div:nth-child(3) {
margin-left: auto;
}
结果如下:
我想让大家注意的是,我们让物品本身来决定它们的摆放方式。除了最初设定的规则之外,我们不需要预先定义任何其他东西display: flex;。
这就是 Flexbox 和 Grid 之间的核心区别,当我们使用 Grid 重新创建此标题时,这一点会更加明显。
尽管 CSS Grid 并非为创建一维标题而设计,但在本文中进行这样的练习仍然是一个很好的例子,因为它能让我们了解 Flexbox 和 Grid 之间的核心区别。
网格标题
我们可以使用 CSS Grid 以多种方式创建页眉。我将采用一种非常简单的方法,其中网格有十列,每列的宽度为一个分数单位。
header {
display: grid;
grid-template-columns: repeat(10, 1fr);
}
它看起来将与 Flexbox 解决方案完全相同。
不过,我们可以深入了解一下,看看有什么不同之处。我们将使用 Chrome 开发者工具来检查列行:
这种方法的关键区别在于,我们必须先定义列——也就是布局。我们首先定义列宽,然后将内容放置在可用的网格单元格中。
这种方法迫使我们决定将表头拆分成多少列。
除非我们更改网格布局,否则就只能使用十列。这是使用 Flexbox 布局时不会遇到的限制。
为了将登出按钮移到最右侧,我们将其放在第十列,如下所示:
header > div:nth-child(3) {
grid-column: 10;
}
以下是我们在检查网格时看到的情况:
我们不能直接移动它,margin-left: auto;因为注销按钮已经放置在布局中的特定单元格内,也就是第三列。要移动它,我们必须找到另一个网格单元格来放置它。
将两者结合起来
现在我们来看看如何将两者结合使用,把页眉融入到网站布局中。我们先从构建网站布局开始。
以下是标记代码:
<div class="container">
<header>HEADER</header>
<aside>MENU</aside>
<main>CONTENT</main>
<footer>FOOTER</footer>
</div>
以下是CSS代码:
.container {
display: grid;
grid-template-columns: repeat(12, 1fr);
grid-template-rows: 50px 350px 50px;
}
我们将按如下方式将物品放置在网格上:
header {
grid-column: span 12;
}
aside {
grid-column: span 2;
}
main {
grid-column: span 10;
}
footer {
grid-column: span 12;
}
现在我们只需添加页眉。我们将把页眉(它是CSS 网格中的一个元素)转换为 Flexbox 容器。
header {
display: flex;
}
现在我们可以把注销按钮设置在右侧:
header > div:nth-child(3) {
margin-left: auto;
}
这样我们就得到了一个非常不错的布局,它结合了 Grid 和 Flexbox 的优点。以下是这两个容器的示意图:
现在你应该对 Flexbox 和 Grid 之间的一般和具体区别有了深刻的了解,并且知道如何将它们一起使用。
浏览器支持
在结束之前,我还需要提一下浏览器支持情况。截至本文发布时,全球 92% 的网站流量支持 CSS Grid,而且这个比例还在不断攀升。
我相信CSS Grid会成为前端开发人员的必备技能,就像CSS Flexbox在过去几年里的发展一样。
点击下方图片即可查看课程预览。
感谢阅读!我叫佩尔,是Scrimba的联合创始人,我热爱帮助人们学习新技能。如果您想收到新文章和资源的通知,请在Twitter上关注我。
文章来源:https://dev.to/scrimba/the-ultimate-css-battle-grid-vs-flexbox-24jn











