132

CSS 终极之战:Grid VS Flexbox

 6 years ago
source link: https://zhuanlan.zhihu.com/p/31952490?
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

CSS 终极之战:Grid VS Flexbox

简评:近些年 CSS Flexbox 在前端开发者中变得非常流行。其实并不奇怪,它能让我们更容易创建出动态布局,以及在容器中对其内容。然而城里新来了个小伙叫 CSS Grid,它有许多弹性盒的能力,有时候比弹性盒好用,有时候却不好用。作者点评了弹性盒、网格两者之间的差异,以及什么时候用哪种比较好。

先来看下这节课的截屏预告:

v2-4d32be938dbec4f7ba975ffaf0a1fd81_720w.webp

一维 VS 二维

如果你想从这篇文章中学到精髓,下面的就是:

Flexbox 是为一维布局设计的,而 Grid 是为二维布局设计。

这意味着如果你想要在一个方向上放置项目(比如在标题栏中有三个按钮),那么你应该用Flexbox:

v2-b5e62d0a0880e8de74f3f2920c521cf8_720w.webp

它会比 CSS Grid 更加灵活,同时只需要更少的代码,更容易维护。

然而,当你需要在两个维度 —— 行和列上创建整个布局时,那么你应该使用 CSS Grid:

这种情况下, CSS Grid 会更加灵活,让你的标记更加简单。代码也更容易维护。

当然你可以结合两者使用。上面的例子中将会完美地使用 Grid 做页面布局,用 Flexbox 来对齐标题栏中的内容。在文末,我会确切地展示如何做到这点。

内容优先 VS 布局优先

另一个核心区别在于:Flexbox 以内容为基础,而 Grid 以布局为基础。这看起来有点抽象,所以让我们来看看确切地例子,这会更容易理解。

我们会使用之前的 header, HTML 代码如下:

<header>
    <div>Home</div>
    <div>Search</div>
    <div>Logout</div>
</header>

在我们进入 Flexbox 布局之前,这些 div 是相互叠在一起的:

Flexbox header

然而,当我们给一个 display: flex 样式时,这些元素就会排成一行。

header {
    display: flex;
}

为了将登出按钮移动到最右边,我们只需要找到那个元素,然后给一个外边距:

header > div:nth-child(3) {
    margin-left: auto;
}

结果如下:

这里我希望你们注意一下:我们让这些元素自己决定它们该如何放置。除了最初的 display: flex; 我们不需要预定义任何东西。

这是 Flexbox 和 Grid 的核心差异,当我们用 Grid 重新创建 header 时,这点会更明显。

即便 CSS Grid 不是用来创建一维的 header,它在这篇文章中仍然是一个很好的练习,让我们明白 Flexbox 和 Grid 的核心差异。

Grid header

使用 CSS Grid,我们可以有好几种方式来创建 header。我将使用相当直接的一种,我们的网格有 10 列,每列宽度为 1 个单元:

header {
    display: grid;
    grid-template-columns: repeat(10, 1fr);
}

和 Flexbox 的方案看起来完全一样。

但是,我们可以看看底下有哪些不同。我们将使用 Chrome 检查器来检查列:

关键不同在于这种方式先定义了列 —— 即布局。我们先定义了列的宽度,然后把内容放到可用的网格里。

这种方式迫使我们将 header 分割成多少列。

除非我们改变网格,我们被 10 列网格限制了。而使用 Flexbox 则不会面临这种限制。

为了将登出按钮放到最右边,我们需要把它放在第 10 列:

header > div:nth-child(3) {
    grid-column: 10;
}

检查网格时看起来是这样:

我们不能简单地给一个 margin-left: auto; 因为登出按钮已经被放在布局中的确切的格子中,在第三列。为了移动它,我们要找到另一个格子。

现在看下如何将两者结合起来,将我们的 header 合并到我们的网站布局。我们从构建网站布局开始:

HTML 标记:

<div class="container">
  <header>HEADER</header>
  <aside>MENU</aside>
  <main>CONTENT</main>
  <footer>FOOTER</footer>
</div>
.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;
}

现在添加 header。我们把 header —— CSS Grid 中的一个项目转换为 Flexbox 容器。

header {
    display: flex;
}

现在可以把登出按钮设置到右边了:

header > div:nth-child(3) {
    margin-left: auto;
}

现在两个容器看起来是这样的:

现在你应该深刻地理解了 Flexbox 和 Grid 的不同之处,并且知道如何使用它们了。

浏览器支持

最后,我想提一下浏览器支持。在写这篇文章时,全球网站流量的 77% 支持 CSS Grid,并且还在增加。我相信 2018 将会是 CSS Grid 时代,它会有一个突破,并成为前端开发者的必备技能。就像前几年的 CSS Flexbox 那样。源代码链接

原文链接:The ultimate CSS battle: Grid vs Flexbox

推荐阅读:

极光日报,极光开发者旗下媒体。

每天导读三篇英文技术文章。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK