上次通过一篇文章介绍了下非常流行的Flex布局,所以这次也打算通过这篇文章介绍下Grid布局,这也是目前最流行的布局方式
Flex与Grid
- Flex布局是一维的排版方式,也就是说一次只能控制一个方向(水平方向或者垂直方向),如果需要控制另一个方向需要再添加一层flexbox容器。
- Grid布局是二维的排版方式,一次能控制两个方向,通过将容器分成行和列,便可定义容器内元素的位置。
基本概念
行与列的概念(row & column)
- 水平区域——行
- 垂直区域——列
单元格(cell)
- 行和列交叉的区域就为一个单元格
- 正常情况下,n行和m列产生m * n个单元格->5行5列=5 * 5=25个单元格
网格线(grid line)
-
划分网格的线,称为"网格线"(grid line)。
-
水平网格线划分出行,垂直网格线划分出列。
-
正常情况下,n行有n + 1根水平网格线,m列有m + 1根垂直网格线。
比如下图5行5列的情况下,有6根水平网格线和6根垂直网格线。
启用Grid布局
首先需要准备一个容器元素
|
|
然后设定容器的display:grid
即可
|
|
Grid布局分为display:grid
与display: inline-grid
,grid
下容器元素都是块级元素,而inline-grid
则是行内元素。
行高与列宽(grid-template-rows/columns
)
grid-template-rows
属性:定义每一行的行高grid-template-columns
属性:定义每一列的列宽
比如,下面将grid-template-rows
与grid-template-columns
都设定为5个100px
,中间用空格隔开,grid-template-rows
代表垂直方向分割出5个高度为100px
的空间,grid-template-columns
代表水平方向分割出5个高度为100px
的空间。
|
|
repeat()
函数
如果觉得定义行高(grid-template-rows
)以及列宽(grid-template-columns
)的时候重复书写某个值很麻烦,那么就可以考虑使用repeat()
函数。
语法:
repeat(<length>, [<value> | <mode>])
- 参数1
length
:需要重复的次数 - 参数2
[<value> | <mode>]
:需要重复的值,可以是百分比、具体的值或者是某种模式
比如上面的定义行高与列宽中的代码就可以改写为下面这样
|
|
repeat()
可以和正常的设定值混用
|
|
fr
关键字
如果想按照比例分配行高(grid-template-rows
)以及列宽(grid-template-columns
)的值,那么就可以使用fr
关键字(Fraction,意为"片段")。
fr
表示比例,1fr
表示占1份。- 如果将上面的
grid-template-rows: repeat(5, 100px)
改为grid-template-rows: repeat(5, 1fr)
,即表示即各占5分之1的空间。 fr
关键字同样可以和正常的设定值混用
|
|
auto-fill
关键字
有时,单元格的大小是固定的,但是容器的大小不确定。
如果希望每一行(或每一列)容纳尽可能多的单元格,这时可以使用auto-fill
关键字表示自动填充。
|
|
上面代码表示每列宽度100px
,然后根据容器的宽度自动填充,知道容器不能放置更多的列。
HTML:
|
|
CSS:
|
|
效果图:
auto
关键字
auto
关键字可以让浏览器自己决定长度。
|
|
上面的意思是,第二列的宽度,等于该列单元格的最大宽度。
HTML:
|
|
CSS:
|
|
效果图:
除非单元格内容设置了min-width
,且这个值大于最大宽度。
指定元素的位置
下面给容器添加两个元素,设置对应的背景色
HTML:
|
|
CSS:
|
|
效果如图所示:
这个是默认没有定义元素位置的情况,如果想要指定元素位置需要用到grid-row
与grid-column
属性。
grid-row
与grid-column
grid-row
与grid-column
本身是复合属性。
-
grid-row
指定 垂直方向 上的范围 -
grid-column
指定 水平方向 上的范围 -
grid-row
属性的组成部分:grid-row-start
:上边框所在的水平网格线grid-row-end
:下边框所在的水平网格线
-
grid-column
属性的组成部分:grid-column-start
:左边框所在的垂直网格线grid-column-end
:右边框所在的垂直网格线
如果想使用grid-row
,首先指定grid-row-start
,然后再指定grid-row-end
即可,语法如下:
|
|
gird-column
也是如此,也是先指定grid-column-start
,然后再指定grid-column-end
,语法如下:
|
|
有了这些前置知识后,现在就可以指定元素的位置了,打个比方,如果想让蓝色以及黄色占据下图所示的区域
首先来看蓝色的色块:
- 水平方向上的范围是从1到3,对应的
grid-column
的值为1 / 3
- 竖直方向上的范围是1到4,对应的
grid-row
的值为1 / 4
然后看看黄色的色块:
- 水平方向上的范围是从3到6,对应的
grid-column
的值为3 / 6
- 竖直方向上的范围是4到6,对应的
grid-row
的值为4 / 6
写出对应的CSS,看看效果:
|
|
grid-area
(复合属性)
除了可以用grid-column
与grid-row
指定元素的位置,还可以使用grid-area
属性。
- 该属性为
grid-column
与grid-row
的复合属性
我们直接上代码:
|
|
效果和原本的是一样的,grid-area
的设置顺序是:
grid-row
的第一个值grid-column
的第一个值grid-row
的第二个值grid-column
的第二个值
可以理解为"坐标",即左上角、右下角坐标。
不过个人不太喜欢用,因为没有grid-row
与grid-column
看上去直观。
span
关键字
grid-row
和grid-column
的设定值是由第几至第几,比如第1至第5:1 / 5
实际在开发过程中是不会有之前图片上那样的标尺一眼就可以看出对应的编号的。
因此Grid布局提供了span
关键字,span
是延伸的意思,所以可以理解为:
- 第几开始延伸多少格
所以我们可以将蓝色块的代码修改为下面这样:
|
|
- 这里的
grid-column
意为:从1向后延伸3格 - 这里的
grid-row
意为:从1向后延伸2格
效果如下图:
给网格线(grid line)起别名
实际上我们可以给 网格线(grid line) 起别名,代码如下:
|
|
对应的代码中也可以使用别名了
|
|
给单元格起别名(grid-template-areas
)
- 使用
grid-template-areas
就可以给单元格起别名
首先我们继续给容器增加两个元素
HTML:
|
|
CSS:
|
|
效果图:
现在通过grid-template-areas
给容器的各个单元格命名,从而构建出一个经典的网页布局。
|
|
现在对容器中的元素使用grid-area
属性,并指定对应grid-template-areas
中给方格起的别名,容器中的元素便会自动填充到对应的区域中。
|
|
repeat()
不适用于grid-template-areas
中。
行间距与列间距(grid-row/column-gap
)
如果觉得所有元素紧贴在一起不太好,Grid布局还提供了grid-row-gap
与grid-column-gap
来增加元素间的行间距与列间距
grid-row-gap
属性设置行与行的间隔(行间距)grid-column-gap
属性设置列与列的间隔(列间距)
下面我们将刚才写的经典布局的案例的CSS加上这两个属性
|
|
可以看到内部增加了列间距与行间距后将容器撑大了,所以容器的宽高也需要修改下:
|
|
现在看上去就正常了!
grid-auto-flow
关键字
-
Grid布局提供了
grid-auto-flow
用于控制容器内元素的排列方向(类似Flex布局中的flex-direction
+flex-warp:warp
的效果) -
默认值为
row
,默认的放置顺序是"先行后列",即先填满第一行,再开始放入第二行,具体参考下图数字的排列顺序。 -
设置为
column
时,表示"先列后行",即先填满第一列,再开始放入第二列,具体参考下图数字的排列顺序。
设置单元格中的元素/内容的位置
justify-items
与align-items
justify-items
属性设置单元格内容的水平位置(左中右)。align-items
属性设置单元格内容的垂直位置(上中下)。
可选值:
-
start
:对齐单元格的起始边缘。 -
end
:对齐单元格的结束边缘。 -
center
:单元格内部居中。 -
stretch
:拉伸,占满单元格的整个宽度(默认值)。
比如现在想让容器中元素的编号向左上角对齐可以这么写:
CSS:
|
|
效果:
place-items
(复合属性)
-
该属性为
justify-items
与align-items
的复合属性 -
语法
place-items: <align-items> <justify-items>;
比如刚才的代码就可以简写为:place-items: start start;
justify-self
与align-self
justify-self
属性设置单元格内容的水平位置(左中右),与justify-items
用法完全一致,但只作用于 单个元素 。align-self
属性设置单元格内容的垂直位置(上中下),与align-items
用法完全一致,但只作用于 单个元素 。
比如只想要第二个元素向左下角对其,就可以这么写:
CSS:
|
|
效果:
place-self
(复合属性)
- 该属性为
align-self
属性和justify-self
属性的复合属性。 - 语法:
1
place-self: <align-self> <justify-self>;
所以刚才的代码可以简写为这样:place-self: end end;
设置整个容器中内容的位置
justify-content
与align-content
justify-content
属性是整个内容区域在容器里面的水平位置(左中右)。align-content
属性是整个内容区域的垂直位置(上中下)。
取值:
下图都以justify-content
属性为例
CSS:
|
|
-
start - 对齐容器的起始边框。 默认值
-
end - 对齐容器的结束边框。
-
center - 容器内部居中。
-
stretch - 项目大小没有指定时,拉伸占据整个网格容器。
移除
grid-template-rows
以及grid-template-columns
后 -
space-around - 每个项目两侧的间隔相等。所以,项目之间的间隔比项目与容器边框的间隔大一倍。
-
space-between - 项目与项目的间隔相等,项目与容器边框之间没有间隔。
-
space-evenly - 项目与项目的间隔相等,项目与容器边框之间也是同样长度的间隔。
place-content
(复合属性)
- 该属性是
align-content
和justify-content
的复合属性 - 语法:
1
place-content: <align-content> <justify-content>
如果省略第二个值,浏览器就会假定第二个值等于第一个值。
练习小游戏
GRID GARDEN-链接