Grid布局

简介

CSS网格布局(又称“网格”),是一种二维网格布局系统。

最开始我们用的是table(表格)布局,然后用float(浮动),position(定位)和inline-block(行内块)布局,但是这些方法本质上是hack,遗漏了很多功能,例如垂直居中。后来出了flexbox(盒子布局),解决了很多布局问题,但是它仅仅是一维布局,而不是复杂的二维布局,实际上它们(flexbox与grid)能很好的配合使用。
Grid布局是第一个专门为解决布局问题而创建的CSS模块,2012年11月06日成立草案。

初步了解和浏览器支持

使用Grid布局非常简单,你只需要给容器(container)定义:display:grid,并设置列(grid-template-columns)和 行(grid-template-rows)的大小,然后用grid-column和grid-row定义容器子元素(grid-item项目)的位置。
与flexbox布局类似,一开始项目的排列顺序并不重要,可以放置在容器的任何位置,这也使得你非常容易通过媒体查询重新排列你的项目。想象一下,当你定义整个页面的布局时,你只需要几行CSS就可以完成页面重排以便适应各种屏幕宽度

目前浏览器还不支持Grid布局,IE10和IE11支持老的语法。如果你想体验Grid布局的强大,推荐使用开通过“体验新功能”的Chrome, Opera 或 Firefox, Chrome:打开浏览器,输入chrome://flags,找到"experimental web platform features",启用并重启浏览器;Opera:输入opera://flags,与Chrome一样;Firefox:输入layout.css.grid.enabled。

例:

Grid布局

浏览器支持情况

Grid布局

重要术语

在深入了解Grid布局概念之前,我们先了解一些术语。因为这些术语在概念上很相似,如果你不记住Grid定义的含义,会很容易将它们混淆,但是不用担心,这里术语很少。

【1】网格容器(Grid Container)
元素应用display:grid,它是其所有网格项的父元素。下面例子container就是网格容器。
Grid布局
【2】网格项(Grid Item)
网格容器的子元素,下面的item元素是网格项,但sub-item不是。
Grid布局
【3】网格线(Grid Line)
组成网格线的分界线。它们可以是列网格线(column grid lines),也可以是行网格线(row grid lines)并且居于行或列的任意一侧,下面黄色线就是列网格线。
Grid布局
【4】网格轨道(Grid Track)
两个相邻的网格线之间为网格轨道。你可以认为它们是网格的列或行,下面在第二个和第三个网格线之间的黄色部分为网格轨道。
Grid布局
【5】网格单元(Grid Cell)
两个相邻的列网格线和两个相邻的行网格线组成的是网格单元,它是最小的网格单元。下面行网格线1(row grid lines 1)、行网格线2(row grid lines 2)和列网格线2(column grid lines 2)、列网格线3(column grid lines 3)组成的黄色区域为网格单元。
Grid布局
【6】网格区(Grid Area)
网格区是由任意数量网格单元组成,下面行网格线1(row grid lines 1)、行网格线3(row grid lines 3)和列网格线1(column grid lines 1)、列网格线3(column grid lines3)组成的黄色区域为网格区。
Grid布局

设置在网格容器上的属性

Grid布局
(1)display: grid | inline-grid | subgrid;

属性值:
grid: 生成块级网格
inline-grid: 生成行内网格
subgrid: 如果网格容器本身是网格项(嵌套网格容器),此属性用来继承其父网格容器的列、行大小。

注:当元素设置了网格布局,column、float、clear、vertical-align属性无效。

(2)grid-template-columns: < track-size > … | < line-name > < track-size > … ;
grid-template-rows: < track-size > … | < line-name > < track-size> … ;

设置行和列的大小,在行轨道或列轨道两边是网格线。

属性值:
track-size: 轨道大小,可以使用css长度,百分比或用分数(用fr单位)。
line-name: 网格线名字,你可以选择任何名字。
例:
Grid布局
Grid布局
Grid布局
Grid布局
Grid布局
Grid布局
Grid布局
Grid布局
Grid布局
(3)grid-template-areas
通过获取网格项中的grid-area属性值(名称),来定义网格模版。重复网格区(grid-area)名称将跨越网格单元格,‘.’代表空网格单元。

属性值:
grid-area-name: 网格项的grid-area属性值(名字)
‘.’ : 空网格单元
none: 不定义网格区域
Grid布局
上面代码示例会创建四列三行网格,第一行将是header,第二行前两个网格单元是main部分、第三个为空网格单元、第四个为sliderbar,第三行是footer。
Grid布局
(4) grid-column-gap:< line-size>; 和 grid-row-gap: < line-size> ;
网格单元间距。

属性值:
line-size: 网格线间距,设置单位值。

例:
Grid布局
Grid布局
注:间隔仅仅作用在网格单元之间,不作用在容器边缘。

(5) grid-gap:< grid-row-gap> < grid-column-gap>; 是grid-column-gap 和 grid-row-gap简写。
例:
Grid布局
注:如果只设置一个值,那么grid-column-gap 和 grid-row-gap都为那个值。

(6) justify-items: start | end | center | stretch(默认) ;
垂直于列网格线对齐,适用于网格容器里的所有网格项。

属性值:
start: 左对齐。
end: 右对齐。
center: 居中对齐。
stretch: 填满(默认)。
例:
Grid布局
Grid布局
Grid布局
Grid布局
(7)align-items: start | end | center | stretch ;
垂直于行网格线对齐,适用于网格容器里的所有网格项。

属性值:
start: 顶部对齐。
end: 底部对齐。
center: 居中对齐。
stretch:填满(默认)。

例:
Grid布局
Grid布局
Grid布局
Grid布局
(8) justify-content: start | end | center | stretch | space-around | space-between | space-evenly ;
如果用像px非弹性单位定义的话,总网格区域大小有可能小于网格容器,这时候你可以设置网格的对齐方式(垂直于列网格线对齐)。

属性值:
start: 左对齐。
end: 右对齐。
center: 居中对齐。
stretch: 填满网格容器。
space-around: 网格项两边间距相等,网格项之间间隔是单侧的2倍。
space-between: 两边对齐,网格项之间间隔相等。
space-evenly: 网格项间隔相等。
例:
Grid布局
Grid布局
Grid布局
Grid布局
Grid布局
Grid布局
Grid布局
(9)align-content: start | end | center | stretch | space-around | space-between | space-evenly ;
如果用像px非弹性单位定义的话,总网格区域大小有可能小于网格容器,这时候你可以设置网格的对齐方式(垂直于行网格线对齐)。

属性值:
start: 顶部对齐。
end: 底部对齐。
center: 居中对齐。
stretch: 填满网格容器。
space-around: 网格项两边间距相等,网格项之间间隔是单侧的2倍。
space-between: 两边对齐,网格项之间间隔相等。
space-evenly: 网格项间隔相等。

例:
Grid布局
Grid布局
Grid布局
Grid布局
Grid布局
Grid布局
Grid布局
(10)grid-auto-columns: < track-size> … ; 和 grid-auto-rows: < track-size> … ;
自动生成隐式网格轨道(列和行),当你定位网格项超出网格容器范围时,将自动创建隐式网格轨道。

属性值:
track-size: 网格轨道大小,可以是固定值,百分比或者是分数(fr单位)。
例:
Grid布局
Grid布局
我们可以看出,网格项item-b定位在第五根列网格线(column line 5 )和第六根列网格线(column line 6 )之间。但是我们网格容器根本不存在这两条网格线,所以就用两个0宽度来填充。在这里我们可以用网格自动行(grid-auto-rows)和网格自动列(grid-auto-columns)来定义这些隐式轨道宽度。
Grid布局
(11)grid-auto-flow : row(默认) | column | dense ;
在没有设置网格项的位置时,这个属性控制网格项怎样排列。

属性值:
row: 按照行依次从左到右排列。
column: 按照列依次从上倒下排列。
dense: 按先后顺序排列。
例:
Grid布局
Grid布局
Grid布局
(12) grid: none | < grid-template-rows> / < grid-template-columns> | < grid-auto-flow> [< grid-auto-rows> [ / < grid-auto-columns>] ];是一种简写形式,设置网格容器所有属性。

属性值:
none: 设置为所有属性的默认值。
< grid-template-rows> / < grid-template-columns>: 设置行和列的值,其他属性为默认值。
< grid-auto-flow> [ < grid-auto-rows> [ / < grid-auto-columns>] ] : 设置网格自动流、网格自动行、网格自动列的值,其他未设置则为默认值。

例:
Grid布局
Grid布局
设置在网格项上的属性

grid-column-start
grid-column-end
grid-row-start
grid-row-end
grid-column
grid-row
grid-area
justify-self
align-self

①grid-column-start: < number> | < name> | span < number> | span < name> | auto ;
grid-column-end: < number> | < name> | span < number> | span < name> | auto ;
grid-row-start: < number> | < name> | span < number> | span < name> | auto ;
grid-row-end: < number> | < name> | span < number> | span < name> | auto ;

通过网格线来定义网格项的位置。grid-column-start、grid-row-start定义网格项的开始位置,grid-column-end、grid-row-end定义网格项的结束位置。

属性值:
line: 指定带编号或者名字的网格线。
span : 跨越轨道的数量。
span : 跨越轨道直到对应名字的网格线。
auto: 自动展示位置,默认跨度为1。

例:
Grid布局
Grid布局
注:如果未声明grid-column-end或grid-row-end,默认将跨越一个轨道。项目也可以重叠,设置z-index来确定堆叠顺序。

②grid-column: < start-line> / < end-line> | < start-line> / span < value> ;
grid-row: < start-line> / < end-line> | < start-line> / span < value> ;

是 grid-column-start、grid-column-end 和 grid-row-start、grid-row-end 的简写。

例:
Grid布局
③grid-area: < name> | < row-start> / < column-start> / < row-end> / < column-end> ;
定义网格项名字,以便创建模块(容器属性grid-template-areas来定义模块)

属性值:
name: 项目名子。
< row-start> / < column-start> / < row-end> / < column-end>: 可以是数字或网格线名字。

例:
Grid布局
④justify-self: justify-self: start | end | center | stretch;
定义单个网格项垂直于列网格线的对齐方式。

属性值:
start: 网格区域左对齐。
end: 网格区域右对齐。
center: 网格区域居中。
stretch: 网格区域填满。

例:
Grid布局
Grid布局
Grid布局
Grid布局
提示:也可以在容器上设置justify-items,达到全部网格项对齐。

⑤align-self: start | end | center | stretch;
定义单个网格项垂直于行网格线的对齐方式。

属性值:
start: 网格区域顶部对齐。
end: 网格区域底部对齐。
center: 网格区域居中。
stretch: 网格区域填满。

例:
Grid布局
Grid布局
Grid布局
Grid布局
提示:也可以在容器上设置align-items,达到全部网格项对齐。

fr是css一个比较新潮的单位,在Grid布局中常见到它的身影。

1.fr是什么?能帮助解决什么问题?
demo:
Grid布局
细心的朋友会发现在设置grid-template-columns: repeat(4,25%)和grid-column-gap:10px之后,页面的底部是会有水平方向滚动条的。因为在算每列宽度的时候没有将间隔给剔除。

fr正是被用于优雅地解决这样的问题,而不用自己手动calc(…)去计算:
Grid布局

2.fr有趣的实践情况——和其他单位混合使用
比如要实现这样的布局:左侧是固定宽度的导航条,右侧所有列均匀瓜分剩余空间
Grid布局

小结:

fr是在看Grid布局中遇到的陌生的css单位值,平时用的也比较少。学习了css tricks上的An Introduction to the fr CSS unit ,讲得挺通俗易懂。css也在朝着一个“智能”的方向,挺博大精深的。也强烈推荐css tricks,网页设计风格很喜欢,介绍也很仔细。