CSS Grid和Flexbox是CSS布局中最强大的布局系统,Flexbox的布局首先解决了很多复杂的布局问题,包括移动响应式页面也能够很好的处理,也是目前流行的一种布局方式。
而CSS Grid的则是对Flexbox的一种补充,相对Flexbox,Grid网格布局更适合复杂的界面布局。但是CSS Grid和Flexbox具体有什么不同呢?用哪一个更好?如何权衡?
1、CSS Grid网格布局可以代替Flexbox布局吗?
我们刚刚接触CSS Grid时候,可能会问:这个Grid网格布局可以代替Flexbox吗?只使用Grid而放弃Flexbox吗?不,不是这样的,Grid能做到Flexbox不能做到或不适合做的事,Flexbox仍然是我们布局的好工具,能做到Grid不能做到的。
比如,我们仍然会使用一些又老又旧的CSS技巧来布局,例如:float,很多时候都会使用到float,又如position定位布局等,这些都是布局技术中的一部分,我们要知道,CSS Grid也是其中之一。
我们会在页面某部分使用Grid,其它地方则不用,它不像我们使用的一些强大的框架,比如Bootstrap或Foundation,它不需要处理整个页面的布局,而是处理某个特定容器的布局。
所以我们也可以在项目中混用Flexbox和CSS Grid,下面是两者混用的一个例子。
先看HTML代码:
<!--页头-->
<header class="header">
<div class="navigation">
<ul class="navigation-left">
<li>首页</li>
<li>发现</li>
<li>热门推荐</li>
</ul>
<ul class="navigation-right">
<li>注册</li>
<li>登录</li>
</ul>
</div>
</header>
<!--页面主体-->
<div class="wrapper">
<div class="main">
</div>
<div class="sidebar">
</div>
</div>
<!--页脚-->
<footer class="footer">
<ul class="info">
<li>关于我们</li>
<li>隐私政策</li>
<li>版权声明</li>
</ul>
</footer>
这是标准的页面构成:页头,主体内容,侧边栏,页脚,直接放在body下面。
下面我们看一下CSS代码:
*{
margin: 0;
padding: 0;
}
ul{
list-style: none;
}
/*页头*/
.header .navigation, .wrapper{
width: 1200px;
margin: auto;
}
.header{
height: 60px;
margin-bottom: 30px;
border-bottom: 1px solid #e5e5e5;
}
.header .navigation{
height: 100%;
display: flex;
justify-content: space-between;
}
.header .navigation .navigation-left,
.header .navigation .navigation-right{
height: 100%;
display: flex;
align-items: center;
}
.header .navigation li{
padding: 0 15px;
}
/*页头*/
/*页面主体*/
.wrapper{
height: 790px;
display: grid;
grid-template-columns: 9fr 3fr;
}
.wrapper .main{
margin: 0 15px;
height: 100%;
background-color: #83bdff;
}
.wrapper .sidebar{
margin: 0 15px;
height: 100%;
background-color: #ffa5cb;
}
/*页面主体*/
/*页脚*/
.footer{
height: 60px;
margin-top: 30px;
border-top: 1px solid #e5e5e5;
display: grid;
grid-template-rows: auto 1fr auto;
grid-template-areas: ". info .";
justify-content: center;
}
.footer .info{
height: 60px;
grid-area: info;
display: flex;
align-items: center;
}
.footer .info li{
font-size: 13px;
padding: 0 15px;
}
/*页脚*/
你可以看到有些地方使用了CSS Grid,有些地方使用了Flexbox。当然这个例子太简单,这个例子全部使用Flexbox或全部使用CSS Grid都可以。因为CSS Grid是二维布局,所以全局布局我们完全可以用grid-template-areas指定所有区域。
2、那么你为什么要使用Flexbox?为什么你要使用CSS Grid布局?你应该在什么时候使用哪个?
如果我们只想要往一个方向布局,Flexbox就很有用。你可以把它想成一大堆盒子排在一条无限长的线上,但它并不是无限的长,实际上是有限的空间。盒子可能会跳行,可能不会,跳行与否,浏览器每次都只会考虑一个纬度,浏览器不会跨行做计算,它只会计算一个方向。
Grid能够布局两个方向的元素。实际上,Grid总是想要布局在两个方向上,你无法使用它做交错布局,它总是同时考虑行和列,它会想要调整你的网格,同时考虑两个方向发生的事。
这张图片显示了是一个使用Grid布局,来排列两个方向的东西。
这张图显示了在Flexbox时,计算是按每一行计算的,一次一行,不管其它行的事,你可以看到东西并没有对齐,它依赖于内容的大小,页面上东西的大小。
这张图显示出Grid擅长什么,Flexbox擅长什么。
有些情况Flexbox或Grid是通用的,他们可以做同样的事情,有一件情况,Grid可以做但是Flexbox无法做到的是“重叠元素”,如果你的情况是两者都能做到,但是你想要重叠元素,那你肯定想要使用Grid。
这里有个例子:
图片是内容,不是背景图片。图片右上角有一个按钮元素,我们不想使用绝对定位,或者添加更复杂的时候绝对定位会无效。我们使用Grid,但是我们也可以使用Flexbox,但是因为有重叠,我们可以在这种情况下使用CSS Grid。
3、全局页面定位搭建使用CSS Grid还是Flex box?
这要视情况确定,如果所有主要的全局容器元素都同级分布,因为这时元素呈二维分布,推荐考虑用CSS Grid。如:
<div class="container">
<!--页头-->
<header class="header"></header>
<!--页面主体-->
<div class="main"></div>
<!--侧边栏-->
<div class="sidebar"></div>
<!--页脚-->
<footer class="footer"></footer>
</div>
CSS样式可以这样写:
.container{
display: grid;
grid-template-columns: 3fr 1fr;
grid-template-areas:
"header header"
"main sidebar"
"footer footer";
}
这样就可以基本完成整体布局了,你也可以使用Flexbox,但是使用Flexbox情况可能会有些复杂,因为Flexbox只能在一个方向上布局,为了达到效果,这时候你需要将元素进行嵌套,用一次或两次Flexbox布局才能达到相同的效果。
现在看来我们可以根据元素是一维分布还是二维分布,来选择CSS Grid或Flexbox。
4、使用CSS Grid对齐元素方便吗?还是使用Flexbox对齐元素更方便?
对齐组件元素是前端开发中必不可少的操作,我们借助一个例子来看看CSS Grid和Flexbox的对齐操作哪一个更方便。
我们的操作对象如下,这是一个顶部导航栏,内容需要左右对齐:
<div class="navigation">
<ul class="navigation-left">
<li>首页</li>
<li>发现</li>
<li>热门推荐</li>
</ul>
<ul class="navigation-right">
<li>注册</li>
<li>登录</li>
</ul>
</div>
1)CSS
Grid的布局写法如下:
.navigation{
height: 100%;
display: grid;
grid-template-columns: 1fr 1fr;
}
.navigation .navigation-left{
justify-self: start;
}
.navigation .navigation-right{
justify-self: end;
}
但是此时li元素并没有水平对齐,我们还需要在两个ul上再添加对齐样式,我们可以添加如下样式实现:
ul{
justify-self: start;
display: grid;
grid-template-columns: auto auto 1fr;
align-items: center;
}
2)Flexbox的做法如下:
.navigation{
height: 100%;
display: flex;
justify-content: space-between;
}
.navigation .navigation-left,
.navigation .navigation-right{
height: 100%;
display: flex;
align-items: center;
}
Flexbox的对齐方式写法比较简洁一些,而CSS Grid则显得有些复杂,推荐使用Flexbox,但是最好的是你更熟练哪种就用哪种。
5、响应式页面设计用CSS Grid还是Flexbox?
这个问题需要根据你原先使用的布局确定,例如,如果原先使用的是CSS Grid布局:
.container{
display: grid;
grid-template-columns: 3fr 1fr;
grid-template-areas:
"header header"
"main sidebar"
"footer footer";
}
则响应式的写法:
.container{
display: grid;
grid-template-columns: 1fr;
grid-template-areas:
"header"
"main"
"footer";
}
这种形式是不是比较简单,这是因为你在整体布局中使用了Grid。如果你在刚开始整体布局使用的是Flexbox或者其它形式,那么情况又会不一样。最好保持整体布局和响应式布局一致,这样会比较清晰明了,一致的写法会简单很多。
像上面第一个代码例子,整体布局并没有用到Grid或Flexbox,那么在响应式里就似乎就不太好了,所以记得在整体布局的时候要使用适当的布局,下面是实现效果:
6、Flexbox和Grid的浏览器兼容性如何?
1)Grid
PC端:Chrome57+,Opera44+,Firefox52+,IE11+,Safari10.1,Edge16+
移动端:iOS10.3,Android67,Android69,Android Firefox62
2)Flexbox最新版本
Chrome20,Safari3.1+,Firefox2-21,IE10,Android2.1+,iOS3.2+
7、结语
现在你可以看到Flexbox和CSS Grid和float,position一样,属于CSS布局的一种,我们最好按照每个开发场景的不同选择不同的布局,比如对于整体布局这种内容较大的布局我们可以使用Grid;推荐使用Flexbox处理组件对齐方式;面向响应式设计我们又要注意,有必要在开始时确定布局方式,这样才更好处理后面的布局,使用CSS Grid是个不错的选择。