Grid VS Flexbox

对于Web开发者来说,网页布局一直是个比较重要的问题。但实际上,在网页开发很长的一段时间当中,我们甚至没有一个比较完整的布局模块。总的来说 Web 布局经历了四个阶段......

一、前言

原文链接:blog.catwen.cn

对于Web开发者来说,网页布局一直是个比较重要的问题。但实际上,在网页开发很长的一段时间当中,我们甚至没有一个比较完整的布局模块。总的来说 Web 布局经历了以下四个阶段:

1、table表格布局,通过 Dreamweaver 拖拽表格或者手写 table 标签布局

  • 优点:方便排列有规律、结构均匀的内容或数据

  • 缺点:产生垃圾代码、影响页面下载时间、可读性差,灵活性不大难于修改

2、float浮动及position定位布局,借助元素元素盒模型本身的特性以及 float position 等属性等进行布局(div+css)

  • 优点:代码精简、提高页面下载速度、表现和内容相分离等

  • 缺点:比较灵活,难于控制

3、flex弹性盒模型布局,革命性的突破,解决传统布局方案上的三大痛点 排列方向、对齐方式,自适应尺寸。是目前最为成熟和强大的布局方案

  • 优点:简单,方便,快速
  • 缺点:对旧版本的浏览器支持不太好

4、grid栅格布局,二维布局模块,具有强大的内容尺寸和定位能力,适合需要在两个维度上对齐内容的布局

  • 缺点:尽管是最新浏览器目前也还没有得到全面支持

Grid Layout 是一种基于二维网格的布局系统,旨在完全改变我们设计基于网格的用户界面的方式,弥补网页开发在二维布局能力上的缺陷

与flex分为伸缩容器和伸缩项目类似,grid也分为网格容器和网格项目

二、下面作简要的分析对比:

一维 VS 二维

Flexbox用来做一维布局,Grid用来做二维布局

意思是如果你只在一个方向上布局(比如在header里面放三个button),你需要使用Flexbox

image

他将会比Grid更加灵活,可以用更少的代码去实现并且更加容易维护。

但是,如果你打算在两个维度上创建一个完整的布局,同时使用行和列,那么你应该使用Grid

image

在这种情况下,Grid会更加灵活,并且会使你的标签更简单,代码更容易维护。

你可以结合两者一起使用,在上面的例子中最完美的做法是使用Grid来布局页面,使用Flexbox去对齐header里面的内容。

浏览器支持情况

image.png image.png 很明显,Grid的支持并不太好,所以吧,也就只能说Flex 是现在时,Grid 或许是个将来时,以后的事儿谁知道呢。

内容优先 vs 布局优先

两者的另一个核心区别是Flexbox以内容为基础,Grid以布局为基础,听起来有些抽象,我们来用一个实际的例子去解释一下。

我们会用上一段提到的header,他的HTML是这样的:

1
2
3
4
5
<header>
<div>Home</div>
<div>Search</div>
<div>Logout</div>
</header>

在使用Flexbox之前,里面的div会堆叠在彼此之上:

当我们加了display:flex之后,他们会漂亮的在一条线上。

1
2
3
header {
display:flex;
}

为了让logout button 在最右边,我们简单的给他指定一个margin:

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

效果如下:

值得注意的是:让元素本身决定他放在哪里,我们除了display: flex之外不添加任何东西。

这是FlexboxGrid的核心差别,当我们用Grid来创建这个header时,这个差别会更加明显。

尽管用Grid创建一维的header不太合适,但实现它却是一个很好的练习,因为它教会了我们关于FlexboxGrid的核心区别

如果使用Grid会有多种方法。我准备用非常简单的一种去做,我们的Grid有十列,每一列都是一个单位宽度 。

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

他看起来和Flexbox的解决方案一样

但是,我们可以在上帝视角去看两者有什么不同,我们来使用chrome的审查元素去看一下:

最关键的区别就是,这种方式必须先定义布局的列。从定义列的宽度开始,然后我们才能将元素放在可用的单元格中。

这种方式强迫我们去分割我们的header有多少列

除非我们改变Grid,否则我们会被困死在10列中,但是在Flexbox中我们不会被这个麻烦困扰。

为了把logout放在最右边,我们会把他放在第十列:

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

审查元素时,看起来是这样的:

我们不能简单的添加一个margin-left: auto;因为它已经被放在了第三个单元格中,想要移动它,我们得再找一个单元格把它放进去。

结合两者

现在我们看下如如何同时使用GridFlexbox来把header合并进我们的布局,我们先来创建布局。

标签如下:

1
2
3
4
5
6
<div class="container">
<header>HEADER</header>
<aside>MENU</aside>
<main>CONTENT</main>
<footer>FOOTER</footer>
</div>

然后是CSS:

1
2
3
4
5
.container {
display: grid;
grid-template-columns: repeat(12, 1fr);
grid-template-rows: 50px 350px 50px;
}

把元素放进Grid

1
2
3
4
5
6
7
8
9
10
11
12
header {
grid-column: span 12;
}
aside {
grid-column: span 2;
}
main {
grid-column: span 10;
}
footer {
grid-column: span 12;
}

下面仅需要来布置好header:我们把它从Grid中的元素转换为Flexbox容器。

1
2
3
header {
display: flex;
}

现在我们把logout放在右边:

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

现在我们有了同时使用GridFlexbox的完美布局。下面是这两个容器:

Flex 和 Grid 并不是互斥的技术,相反,它们是互补的。

Flex 一般用来做 Page Components 的局部布局,而且一般只做一维的布局,比如导航栏。

Grid 则一般用来做二维平面的布局,通常用于整个页面的规划。

这也是这两个技术发明的初衷,它们相辅相成,并行不悖。

坚持原创技术分享,您的支持将鼓励我继续创作!
0%