听闻w3cplus大漠在第三届CSS Conf上的演讲主题是CSS Grid Layout,吓得我赶紧抛下红尘俗事闭门谢客苦心钻研,唯恐脚步太慢,遥望大漠一骑绝尘而扼腕叹息。
闲话少说,提起网格系统,大家都应该耳熟能详,如960,当然随着技术与分辨率的进步有了进一步的演变,但设计思想还是一致的。既然是这么实用的东西,CSS当然有了纳入规范之想,这不就出现了我们今天要说的CSS Grid Layout
虽说IE10、11早就实现了网格布局,不过那已经是过时的了,新标准目前没有任何浏览器默认正规支持(chrome 54,firefox 49),都需要去手动设置开启:
在说CSS Grid Layout之前,我们先来聊聊excel以帮助我们打下基础,如下图:
以我们的A1单元格为例,先是有上下左右四条线围着,然后定位是由竖直的A栏与横向的1行二维坐标表示A1,最后还可以将一起的单元格合并。
上面的几个概念我们提炼下:线条,栏(竖直),行(横向),单元格,合并。下面我们把这些概念对应到我们的网格系统
因篇幅有限,这里只简单介绍每个属性的用途,具体的属性取值请参考:A Complete Guide to Grid
先说下container上的属性,这里我大概分为三大类:
第一类:如何去定义一个网格系统,行列及间距等
第二类:对齐的方式,属性跟flex的有点像:
space-evenly
值,补足了以前flex的space-around
和space-between
的不足第三类:自动分配形式,当定义的行或列数量不够时,item的自动排列方式
最后一个为所有属性的简写grid
接下来是我们的item属性,同样这里我也将它分为两类
第一类:单元格所占格子多少
第二类:单元格的自定义对齐方式,这个跟flexbox的item有点相似
说了那么多,其实都是为了下面的这个实例铺垫,先看下我们要实现的效果(来自我以前写的sass guide首页布局,当然以前肯定不是用grid来实现的):
html结构为:
.demo>.item*11
写好结构后,我们就开始使用刚才说得grid来实现我们的效果了。先拆分成最小的单元格为6栏*3行,最小单元格的大小为140px,整体内容一屏水平垂直居中。
html,body{
height: 100%;
}
.grid{
height: 100%;
display: grid; // 网格布局
// 整体水平垂直居中
justify-content: center;
align-content: center;
// 定义6栏3行
grid-template-columns: 140px 140px 140px 140px 140px 140px;
grid-template-rows: 140px 140px 140px;
// 定义item之间的间距为20px
grid-gap: 20px;
background: #efefef;
}
.item{
background: #ccc;
}
现在我们可以看到效果如下:
接下来要合并单元格实现我们的最终效果。合并单元格有两种实现方式一种是line的开始与结束(包括colunm与row),另一种就是在grid上面定义的area,这里我们使用第一种方法。
这里重提下上面的Grid Lines概念,如要实现n栏*m行的网格,则需要n+1条垂直line,m+1条水平线。虽然你看不到线,但是线就在你心中。
第一个item元素单元格占了两列,第一列和第二列,那么就垂直栏开始于第一条line,结束于第三条line,同样第5个item元素也是如此
.item:nth-child(1),
.item:nth-child(5){
grid-column: 1 / 3; // 起始于1,结束于3
}
而第二个item元素栏和行都跨了两个,css代码如下:
.item:nth-child(1),
.item:nth-child(5){
grid-column: 3 / 5; // column起始于3,结束于5
grid-row: 1 / 3; // row起始于1,结束于3
}
同样第七个item元素行跨了两个,第9个item元素栏跨了两个,css代码如下:
.item:nth-child(7){
grid-column: 6;
grid-row: 2 / 4; // row起始于2,结束于4
}
.item:nth-child(9){
grid-column: 2 / 4; // column起始于2,结束于4
}
这个布局就这么简单的完成了,效果可见demo
如果继续深入思考下,不难发现grid的强大,简单来说它的威力是flexbox+table的相加,所以将来这是比flexbox更强大的布局利器。