CSS终极之战:Grid vs Flexbox
在过去几年里,Flexbox
已经成了前端最流行的布局框架,这并不奇怪,因为我们可以很方便的用它去对齐元素。
然而,前端村儿里面还有个叫Grid
的小孩儿,他和Flexbox
有很多功能相似的地方,有些地方他比Flexbox
要好,但有也有不足。
这也会变成让开发者们纠结的地方,应该用哪个?本文将会在宏观和微观上面对比两个模块。
一维 vs 二维
Flexbox
用来做一维布局,Grid
用来做二维布局
意思是如果你只在一个方向上布局(比如在header里面放三个button),你需要使用Flexbox
他将会比Grid
更加灵活,可以用更少的代码去实现并且更加容易维护。
但是,如果你打算在两个维度上创建一个完整的布局,同时使用行和列,那么你应该使用Grid
二维
在这种情况下,Grid
会更加灵活,并且会使你的标签更简单,代码更容易维护。
你可以结合两者一起使用,在上面的例子中最完美的做法是使用Grid
来布局页面,使用Flexbox
去对齐header里面的内容。
内容优先 vs 布局优先
两者的另一个核心区别是Flexbox
以内容为基础,Grid
以布局为基础,听起来有些抽象,我们来用一个实际的例子去解释一下。
我们会用上一段提到的header,他的HTML是这样的:
1 | <header> |
在使用Flexbox
之前,里面的div会堆叠在彼此之上:
Flexbox header
当我们加了display:flex
之后,他们会漂亮的在一条线上。
1 | header { |
为了让logout button 在最右边,我们简单的给他指定一个margin:
1 | header > div:nth-child(3) { |
效果如下:
值得注意的是:让元素本身决定他放在哪里,我们除了display: flex
之外不添加任何东西。
这是Flexbox
和Grid
的核心差别,当我们用Grid
来创建这个header时,这个差别会更加明显。
尽管用
Grid
创建一维的header不太合适,但在本文中去实现它却是一个很好的练习,因为它教会了我们关于Flexbox
和Grid
的核心区别
Grid header
如果使用Grid
会有多种方法。我准备用非常简单的一种去做,我们的Grid
有十列,每一列都是一个单位宽度 。
1 | header { |
他看起来和Flexbox
的解决方案一样
但是,我们可以在上帝视角去看两者有什么不同,我们来使用chrome的审查元素去看一下:
最关键的区别就是,这种方式必须先定义布局的列。从定义列的宽度开始,然后我们才能将元素放在可用的单元格中。
这种方式强迫我们去分割我们的header有多少列
除非我们改变Grid
,否则我们会被困死在10列中,但是在Flexbox
中我们不会被这个麻烦困扰。
为了把logout放在最右边,我们会把他放在第十列:
1 | header > div:nth-child(3) { |
审查元素时,看起来是这样的:
我们不能简单的添加一个margin-left: auto;
因为它已经被放在了第三个单元格中,想要移动它,我们得再找一个单元格把它放进去。
结合两者
现在我们看下如如何同时使用Grid
和Flexbox
来把header合并进我们的布局,我们先来创建布局。
标签如下:
1 | <div class="container"> |
然后是CSS:
1 | .container { |
把元素放进Grid
:
1 | header { |
下面仅需要来布置好header:我们把它从Grid
中的元素转换为Flexbox
容器。
1 | header { |
现在我们把logout放在右边:
1 | header > div:nth-child(3) { |
现在我们有了同时使用Grid
和Flexbox
的完美布局。下面是这两个容器:
所以现在你应该理解了Flexbox
和Grid
的差别,也知道了如何结合两者使用。
浏览器支持
本文截止前,全球77%流量的网站支持Grid
,这个数字还在不断增长。
我相信2018年将会是
Grid
的一年,他将获得突破,并将成为前端开发人员的必备技能,就像过去几年的Flexbox
一样。