之前有写了 玩游戏掌握 Flexbox 布局 - 送小青蛙回家。Grid 布局比 Flexbox 布局更强大。游戏作者还写了个学习 Grid 布局的游戏: Grid Garden。通过写 CSS 代码来栽种胡萝卜花园:将水流移动到胡萝卜上,将农药移动到杂草上。
该游戏一共有 28 关。通关成功,你能掌握 Grid 布局的如下知识点:
游戏地址:https://cssgridgarden.com/ 。
第 01 关
可以用 grid-column-start
来指定网格项列的开始位置。
用 grid-column-start
给第三列的胡萝卜浇水吧~
代码:
#garden {
display: grid;
grid-template-columns: 20% 20% 20% 20% 20%;
grid-template-rows: 20% 20% 20% 20% 20%;
}
#water {
/* 添加的代码 start */
grid-column-start: 3;
/* 添加的代码 end */
}
第 02 关
继续用 grid-column-start
来给第五列的杂草喷药吧~
代码:
#garden {
display: grid;
grid-template-columns: 20% 20% 20% 20% 20%;
grid-template-rows: 20% 20% 20% 20% 20%;
}
#poison {
/* 添加的代码 start */
grid-column-start: 5;
/* 添加的代码 end */
}
第 03 关
可以用 grid-column-end
来指定网格项列的结束位置。同时设置 grid-column-start
和 grid-column-end
可以将网格项拓展到多列。
用 grid-column-start
和 grid-column-end
给第一到第三列的胡萝卜浇水吧~
代码:
#water {
grid-column-start: 1;
/* 添加的代码 start */
grid-column-end: 4;
/* 添加的代码 end */
}
第 04 关
grid-column-end
可以比 grid-column-start
小。grid-column-start
和 grid-column-end
的属性是完全等效的。下面的两段代码的效果是一模一样的:
grid-column-start: 1;
grid-column-end: 3;
grid-column-start: 3;
grid-column-end: 1;
设置 grid-column-end
的值小于5,来给胡萝卜浇水。
代码:
#water {
grid-column-start: 5;
/* 添加的代码 start */
grid-column-end: 2;
/* 添加的代码 end */
}
第 05 关
grid-column-start
和 grid-column-end
的值可以设置为负值。负值表示从右往左数,如 -1 表示右边的第一列。
将 grid-column-end
设置为负值来给胡萝卜浇水吧~
代码:
#water {
grid-column-start: 1;
/* 添加的代码 start */
grid-column-end: -2;
/* 添加的代码 end */
}
第 06 关
将 grid-column-start
设置为负值来除草吧~
代码:
#poison {
/* 添加的代码 start */
grid-column-start: -3;
/* 添加的代码 end */
}
第 07 关
span
关键词来指定要跨越的宽度。请注意 span
只能是正值。如:grid-column-end: span 2;
表示跨越 2 列。
用 span
来浇水吧~
代码:
#water {
grid-column-start: 2;
/* 添加的代码 start */
grid-column-end: span 2;
/* 添加的代码 end */
}
第 08 关
继续用 span
来浇水吧~
代码:
#water {
grid-column-start: 1;
/* 添加的代码 start */
grid-column-end: span 5;
/* 添加的代码 end */
}
第 09 关
也可以在 grid-column-start
中用 span。
继续用 span
来浇水吧~
代码:
#water {
/* 添加的代码 start */
grid-column-start: span 3;
/* 添加的代码 end */
grid-column-end: 6;
}
第 10 关
grid-column
是 grid-column-start
和 grid-column-end
的缩写,中间用 /
分隔。如:grid-column: 2 / 4;
就会设置网格项从第二列开始,到第四列结束。
用 grid-column
来浇水吧~
代码:
#water {
/* 添加的代码 start */
grid-column: 4 / 6;
/* 添加的代码 end */
}
第 11 关
grid-column
中也可以用 span
。
grid-column
中用 span
来浇水吧~
代码:
#water {
/* 添加的代码 start */
grid-column: 2 / span 3;
/* 添加的代码 end */
}
第 12 关
用 grid-row-start
来指定网格项行的开始位置。
用 grid-row-start
来浇水吧~
代码:
#water {
/* 添加的代码 start */
grid-row-start: 3;
/* 添加的代码 end */
}
第 13 关
grid-row
是 grid-row-start
和 grid-row-end
的缩写。
用 grid-row
来浇水吧~
代码:
#water {
/* 添加的代码 start */
grid-row: 3 / span 3;
/* 添加的代码 end */
}
第 14 关
同时使用 grid-column
和 grid-row
来除草吧~
代码:
#poison {
/* 添加的代码 start */
grid-row: 5;
grid-column: 2;
/* 添加的代码 end */
}
第 15 关
继续使用 grid-column
和 grid-row
来浇水吧~
代码:
#water {
/* 添加的代码 start */
grid-row: 1 / 6;
grid-column: 2 / 6;
/* 添加的代码 end */
}
第 16 关
grid-area
是 grid-row-start
, grid-column-start
, grid-row-end
, grid-column-end
的缩写,值之间用 /
分隔。
用 grid-area
来浇水吧~
代码:
#water {
/* 添加的代码 start */
grid-area: 1 / 2 / 4 / 6;
/* 添加的代码 end */
}
第 17 关
一个容器下,可以设置多个网格项。
设置第二个 grid-area
来浇水吧~
代码:
#water-1 {
grid-area: 1 / 4 / 6 / 5;
}
#water-2{
/* 添加的代码 start */
grid-area: 2 / 3 / 5 / -1;
/* 添加的代码 end */
}
第 18 关
根据 order
值来决定重叠的网格项的上下顺序,类似 z-index
。值越大,越在上面,默认值是 0。
第二列的胡萝卜中毒了并且最后有杂草的那一列也浇了水。现在就改变中毒的网格项的 order
的值来修复它们吧!
代码:
#poison {
/* 添加的代码 start */
order: 1;
/* 添加的代码 end */
}
第 19 关
order
值可以是负数。
现在水和中毒的土地是交替出现的,并且所有的杂草都出现在每一列的开始。设置中毒土地的正确的 order
值来修复它们吧!
代码:
.poison {
/* 添加的代码 start */
order: -1;
/* 添加的代码 end */
}
第 20 关
在容器上,使用 grid-template-columns
设置有几列,以及每列的宽度。如 grid-template-columns: 20% 20% 20% 20% 20%;
,创建了5个列,每一列设置为容器宽度的20%。
为 grid-template-columns
设置一个新的值来给你的胡萝卜浇水吧!你想要将第一列的宽度设置为50%。
代码:
#garden {
display: grid;
/* 添加的代码 start */
grid-template-columns: 50% 20% 20%;
/* 添加的代码 end */
grid-template-rows: 20% 20% 20% 20% 20%;
}
#water {
grid-column: 1;
grid-row: 1;
}
第 21 关
repeat函数
可以对相同宽度的网格项做缩写。grid-template-columns: 20% 20% 20% 20% 20%;
可以缩写为 grid-template-columns: repeat(5, 20%);
。
使用 grid-template-columns
属性以及 repeat函数
,创建8列,每列占12.5%的宽度。这样你就不会给花园浇过多的水。
代码:
#garden {
display: grid;
/* 添加的代码 start */
grid-template-columns: repeat(8, 12.5%);
/* 添加的代码 end */
grid-template-rows: 20% 20% 20% 20% 20%;
}
第 22 关
grid-template-columns
不仅仅只接受百分比的值,也接受像像素或 em
这样的长度单位。你甚至可以将不同的长度单位混合使用。
将列的宽度设置为 100px、3em 和 40%。
代码:
#garden {
display: grid;
/* 添加的代码 start */
grid-template-columns: 100px 3em 40%;
/* 添加的代码 end */
grid-template-rows: 20% 20% 20% 20% 20%;
}
第 23 关
网格系统也引入了一个新的单位,分数 fr
。每一个 fr
单元分配一个可用的空间。比如说,如果两个元素分别被设置为 1 fr
和 3 fr
,那么空间就会被平均分配为4份;第一个元素占据1/4,第二个元素占据3/4。
杂草占据了第一行的左 1/6,胡萝卜占据着剩下的 5/6。创建两个列,并使用 fr
单位来定义它们的宽度。
代码:
#garden {
display: grid;
/* 添加的代码 start */
grid-template-columns: 1fr 5fr;
/* 添加的代码 end */
grid-template-rows: 20% 20% 20% 20% 20%;
}
第 24 关
当列的宽度采用像素,百分比或者 em
的单位的时候,其他使用 fr
单位设置的列将会平分剩下的空间。
这里的胡萝卜在左边形成了一个50像素的列,并且杂草在右边也占据着50像素的宽度。使用 grid-template-columns
属性,创建这两个列,使用 fr
再创建三列,使其平均占据剩下的空间。
代码:
#garden {
display: grid;
/* 添加的代码 start */
grid-template-columns: 50px repeat(3,1fr) 50px;
/* 添加的代码 end */
grid-template-rows: 20% 20% 20% 20% 20%;
}
第 25 关
现在,在你的花园的左边有一列杂草,占据75像素宽。剩余空间的3/5正在长着胡萝卜,剩下的2/5已经杂草泛滥了。用 grid-template-columns
属性,将 px
和 fr
单位结合起来,来制作必要的列。
代码:
#garden {
display: grid;
/* 添加的代码 start */
grid-template-columns: 75px 3fr 2fr;
/* 添加的代码 end */
grid-template-rows: 100%;
}
第 26 关
在容器上,使用 grid-template-rows
来设置行。
用 grid-template-rows
属性来为花园中除了顶部50像素之外的所有区域浇水。注意:水被设置为仅填充第五行,所以你总共需要创建5行。
代码:
#garden {
display: grid;
grid-template-columns: 20% 20% 20% 20% 20%;
/* 添加的代码 start */
grid-template-rows: 50px 0 0 0 1fr;
/* 添加的代码 end */
}
第 27 关
grid-template
是 grid-template-rows
和grid-template-columns
的缩写形式,值之间用 /
分隔。比如,grid-template: 50% 50% / 200px;
将创建一个具有两行的网格,每一行占据50%,以及一个200像素宽的列。
尝试着使用grid-template属性来浇水,需要包括你的花园上部的60%,以及左侧的200像素。
代码:
#garden {
display: grid;
/* 添加的代码 start */
grid-template: 60% 40% / 200px 1fr;
/* 添加的代码 end */
}
第 28 关
你在花园的底部留下了50像素的小路,其他的空间用来种植胡萝卜。不幸的是,胡萝卜地的20%已经杂草丛生了,最后一次用 CSS 网格布局来规划你的花园吧!
代码:
#garden {
display: grid;
/* 添加的代码 start */
grid-template: 1fr 50px / 20% 1fr;
/* 添加的代码 end */
}
总结
Grid 布局比 Flexbox 布局更强大。本文介绍的只是 Grid 布局的基础用法。想了解更多 Grid 布局的内容,推荐阅读:最强大的 CSS 布局 —— Grid 布局。