结一

2016-10-31 23:54

网格系统 CSS Grid Layout

本文作者:IMWeb 结一 原文出处:IMWeb社区 未经同意,禁止转载

听闻w3cplus大漠在第三届CSS Conf上的演讲主题是CSS Grid Layout,吓得我赶紧抛下红尘俗事闭门谢客苦心钻研,唯恐脚步太慢,遥望大漠一骑绝尘而扼腕叹息。

闲话少说,提起网格系统,大家都应该耳熟能详,如960,当然随着技术与分辨率的进步有了进一步的演变,但设计思想还是一致的。既然是这么实用的东西,CSS当然有了纳入规范之想,这不就出现了我们今天要说的CSS Grid Layout

网格系统浏览器支持

虽说IE10、11早就实现了网格布局,不过那已经是过时的了,新标准目前没有任何浏览器默认正规支持(chrome 54,firefox 49),都需要去手动设置开启:

  • chrome 在地址栏输入“chrome://flags”,找到"experimental web platform features"开启
  • firefox在地址栏输入"about:config",找到"layout.css.grid.enabled"开启

网格系统基础概念

在说CSS Grid Layout之前,我们先来聊聊excel以帮助我们打下基础,如下图:

excel css grid layout

以我们的A1单元格为例,先是有上下左右四条线围着,然后定位是由竖直的A栏与横向的1行二维坐标表示A1,最后还可以将一起的单元格合并。

上面的几个概念我们提炼下:线条,栏(竖直),行(横向),单元格,合并。下面我们把这些概念对应到我们的网格系统

CSS Grid Layout

  • Grid Containers:首先我们要设置父元素的布局为grid,通过使用display属性给元素显式设置了属性值grid或inline-grid,此时这个元素将自动变成网格容器,对应上图的Sheet1
  • Grid Item:Item是container的直接子元素,如果不考虑单元格的合并跟下面的cell是一样的,对应上图的一个个格子,如蓝色的A1
  • Grid Lines:网格线分为水平线和垂直线,对应上图的橙色线条
  • Grid Track:就是由lines构成的水平和垂直空间,对应到上图的水平和垂直灰色区域,而对于table来说就是row和column
  • Grid Cell:简单来说就是单元格了,对应到上图就是蓝色的A1,而对于table来说就是单元格
  • Grid Area:网格区域是由任意四条网格线组成的空间,可能由一个或多个单元格组成。对应到上图就是红色区域,相当于表格中的合并单元格之后的区域

网格系统基本属性

因篇幅有限,这里只简单介绍每个属性的用途,具体的属性取值请参考:A Complete Guide to Grid

先说下container上的属性,这里我大概分为三大类:

第一类:如何去定义一个网格系统,行列及间距等

  • display:grid/inline-grid,定义使用网格系统
  • grid-template-columns:定义垂直栏
  • grid-template-rows:定义水平行
  • grid-template-areas:定义区域
  • grid-column-gap:定义垂直栏与垂直栏之间的间距,如上图的A与B之间的间距
  • grid-row-gap:定义水平行与水平行之间的间距,如上图的1与2之间的间距
  • grid-gap:上面两个栏与行间距的缩写

第二类:对齐的方式,属性跟flex的有点像:

  • justify-items:item在水平行中的对齐方式
  • align-items:item在垂直栏中的对齐方式
  • justify-content:整个水平行在grid范围的对齐方式,这里有个好用的space-evenly值,补足了以前flex的space-aroundspace-between的不足
  • align-content:整个垂直栏在grid范围的对齐方式

第三类:自动分配形式,当定义的行或列数量不够时,item的自动排列方式

  • grid-auto-columns:定义多出的item的自动column的宽度大小
  • grid-auto-rows:定义多出的item自动row的高度大小
  • grid-auto-flow:定义自动item是按照先水平方向排列还是垂直方向排列

最后一个为所有属性的简写grid

接下来是我们的item属性,同样这里我也将它分为两类

第一类:单元格所占格子多少

  • grid-column-start:item的起始栏
  • grid-column-end:item的结束栏
  • grid-column:起始栏和结束栏的简写
  • grid-row-start:item的起始行
  • grid-row-end:item的结束行
  • grid-row:起始行与结束行的简写
  • grid-area:item所在区域

第二类:单元格的自定义对齐方式,这个跟flexbox的item有点相似

  • justify-self:自定义item的水平方向对齐方式
  • align-self:自定义item的垂直方向对齐方式

实例演示

说了那么多,其实都是为了下面的这个实例铺垫,先看下我们要实现的效果(来自我以前写的sass guide首页布局,当然以前肯定不是用grid来实现的):

grid demo

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更强大的布局利器。

0条评论

    您需要 注册 一个IMWeb账号或者 才能进行评论。