Grid Layout,即网格布局是 CSS3 新属性,可以轻松实现二维布局。随着近一年各大浏览器对该属性的支持,Grid 布局的呼声也越来越高。
最开始了解到 Grid 我是无感的,我无脑地把二维网格联想为 excel 表格,一个 excel 能玩儿出多大的花样?
直到有一天看到这个:
我靠,这不是轻松实现了页面布局?
有点儿意思。
1. Grid 基础结构
与 Flexbox 类似,Grid 布局需要用 display: grid
来声明一个容器(以下称为“网格容器”),该容器里的所有子元素自动成为网格项目(以下称为“网格项目”)。
1 | <div class="grid-container"> |
1 | .grid-container { |
2. Grid 常用属性
2.1 行与列
- grid-template-columns 指定每列的宽度
- grid-template-rows 指定每行的高度
- grid-gap 指定列(或行)的间距
举个栗子:
1 | .grid-container { |
grid-gap
为每个网格项目之间添加 5px 的间隙。
fr
单位(fraction)是根据网格容器计算的单位列宽。我们在容器中设置了 grid-template-columns
属性值为 1fr 2fr 1fr
,是将整个容器等分了 4(1+2+1) 列,因此容器的最小(单位)列宽为容器的 1/4 宽。同时,因为属性值有三个值,因此,默认每行显示三个元素,宽度比分别为 1: 2: 1。
当然,更为普遍的单位,例如 px
、em
、rem
和百分比同样可以使用,并且可以在 grid-template-columns
和 grid-template-rows
属性中混合使用,例如:
1 | grid-template-columns: 100px 3em 40%; |
如果上述单位与 fr
同时设置为属性值,则 fr
在剩余空间再进行分割。举个栗子:
1 | grid-template-columns: 50px 1fr 2fr 50px; |
左右分别为 50px,剩余部分再以 1:2 的比例进行分割。
2.2 网格线与合并单元格
grid-area 应用于网格项目,起始行的网格线位置/结束行的网格线位置/起始列的网格线位置/结束列的网格线位置
grid-rows 应用于网格项目,起始行的网格线位置/结束行的网格线位置
- grid-rows-start 应用于网格项目,起始行的网格线位置
grid-rows-end 应用于网格项目,结束行的网格线位置
grid-columns 应用于网格项目,起始列的网格线位置/结束列的网格线位置
- grid-columns-start 应用于网格项目,起始列的网格线位置
- grid-columns-end 应用于网格项目,结束列的网格线位置
举个栗子:
1 | <div class="grid-container"> |
1 | .header { |
这里涉及到一个很重要的概念——网格线。网格线用来在水平和垂直方向分割网格的线。水平方向的网格线是从左向右,垂直方向是从上往下,编号从 1 开始。
在本例中,网格线的位置如下:
注意:这里的网格线编号是以最初的状态来标号的,因此在这个例子中,垂直方向并不存在 line5
,这是因为你看到的第 5 条线是由合并单元格被挤下来的元素生成的.
这样很容易理解 grid-column: 1 / 4
和 grid-row: 2 / 4
轻松实现了我们常见的导航 header 和侧边栏 sidebar。
grid-columns
、grid-rows
和 grid-area
指定的起始位置与结束位置均指的是网格线的编号。几个属性之间的关系如下:
1 | grid-columns: grid-column-start/grid-column-end; |
grid-column
和 grid-row
是一种简写的方法,分开来写等价于:
1 | grid-columns: 1 / 4; |
另一种写法也可以实现相同的效果,以下写法是完全等价的:
1 | grid-column: 1 / 4; |
span
关键字很像我们操作 excel 中的合并单元格,grid-column: 1 / span 3;
代表从第一列开始,合并 3 个单元格,也就是列网格线跨度为 3。grid-row: 2 / span 2;
代表从第 2 根网格线开始,横跨 2 个网格线。
2.3 负的网格线编号
网格线不仅可以从左到右(水平方向)、从上到下(垂直方向)编号,还可以反向编号,这时的编号是负数。
在上面的例子中,负编号如下:
因此,以下两种写法是等价的:
1 | grid-column: 1 / 4; |