之前有写了 玩游戏掌握 Flexbox 布局 - 送小青蛙回家。Grid 布局比 Flexbox 布局更强大。游戏作者还写了个学习 Grid 布局的游戏: Grid Garden。通过写 CSS 代码来栽种胡萝卜花园:将水流移动到胡萝卜上,将农药移动到杂草上。

该游戏一共有 28 关。通关成功,你能掌握 Grid 布局的如下知识点:

玩游戏入门 Grid 布局 - Grid Garden - 图1

游戏地址:https://cssgridgarden.com/

第 01 关

可以用 grid-column-start 来指定网格项列的开始位置。

玩游戏入门 Grid 布局 - Grid Garden - 图2

grid-column-start 给第三列的胡萝卜浇水吧~

代码:

  1. #garden {
  2. display: grid;
  3. grid-template-columns: 20% 20% 20% 20% 20%;
  4. grid-template-rows: 20% 20% 20% 20% 20%;
  5. }
  6. #water {
  7. /* 添加的代码 start */
  8. grid-column-start: 3;
  9. /* 添加的代码 end */
  10. }

第 02 关

玩游戏入门 Grid 布局 - Grid Garden - 图3

继续用 grid-column-start 来给第五列的杂草喷药吧~

代码:

  1. #garden {
  2. display: grid;
  3. grid-template-columns: 20% 20% 20% 20% 20%;
  4. grid-template-rows: 20% 20% 20% 20% 20%;
  5. }
  6. #poison {
  7. /* 添加的代码 start */
  8. grid-column-start: 5;
  9. /* 添加的代码 end */
  10. }

第 03 关

可以用 grid-column-end 来指定网格项列的结束位置。同时设置 grid-column-startgrid-column-end 可以将网格项拓展到多列。

玩游戏入门 Grid 布局 - Grid Garden - 图4

grid-column-startgrid-column-end 给第一到第三列的胡萝卜浇水吧~

代码:

  1. #water {
  2. grid-column-start: 1;
  3. /* 添加的代码 start */
  4. grid-column-end: 4;
  5. /* 添加的代码 end */
  6. }

第 04 关

grid-column-end 可以比 grid-column-start 小。grid-column-startgrid-column-end 的属性是完全等效的。下面的两段代码的效果是一模一样的:

  1. grid-column-start: 1;
  2. grid-column-end: 3;
  1. grid-column-start: 3;
  2. grid-column-end: 1;

玩游戏入门 Grid 布局 - Grid Garden - 图5

设置 grid-column-end 的值小于5,来给胡萝卜浇水。

代码:

  1. #water {
  2. grid-column-start: 5;
  3. /* 添加的代码 start */
  4. grid-column-end: 2;
  5. /* 添加的代码 end */
  6. }

第 05 关

grid-column-startgrid-column-end 的值可以设置为负值。负值表示从右往左数,如 -1 表示右边的第一列。

玩游戏入门 Grid 布局 - Grid Garden - 图6

grid-column-end 设置为负值来给胡萝卜浇水吧~

代码:

  1. #water {
  2. grid-column-start: 1;
  3. /* 添加的代码 start */
  4. grid-column-end: -2;
  5. /* 添加的代码 end */
  6. }

第 06 关

玩游戏入门 Grid 布局 - Grid Garden - 图7

grid-column-start 设置为负值来除草吧~

代码:

  1. #poison {
  2. /* 添加的代码 start */
  3. grid-column-start: -3;
  4. /* 添加的代码 end */
  5. }

第 07 关

span 关键词来指定要跨越的宽度。请注意 span 只能是正值。如:grid-column-end: span 2; 表示跨越 2 列。

玩游戏入门 Grid 布局 - Grid Garden - 图8

span 来浇水吧~

代码:

  1. #water {
  2. grid-column-start: 2;
  3. /* 添加的代码 start */
  4. grid-column-end: span 2;
  5. /* 添加的代码 end */
  6. }

第 08 关

玩游戏入门 Grid 布局 - Grid Garden - 图9

继续用 span 来浇水吧~

代码:

  1. #water {
  2. grid-column-start: 1;
  3. /* 添加的代码 start */
  4. grid-column-end: span 5;
  5. /* 添加的代码 end */
  6. }

第 09 关

也可以在 grid-column-start 中用 span。

玩游戏入门 Grid 布局 - Grid Garden - 图10

继续用 span 来浇水吧~

代码:

  1. #water {
  2. /* 添加的代码 start */
  3. grid-column-start: span 3;
  4. /* 添加的代码 end */
  5. grid-column-end: 6;
  6. }

第 10 关

grid-columngrid-column-startgrid-column-end 的缩写,中间用 / 分隔。如:grid-column: 2 / 4; 就会设置网格项从第二列开始,到第四列结束。

玩游戏入门 Grid 布局 - Grid Garden - 图11

grid-column 来浇水吧~

代码:

  1. #water {
  2. /* 添加的代码 start */
  3. grid-column: 4 / 6;
  4. /* 添加的代码 end */
  5. }

第 11 关

grid-column 中也可以用 span

玩游戏入门 Grid 布局 - Grid Garden - 图12

grid-column 中用 span 来浇水吧~

代码:

  1. #water {
  2. /* 添加的代码 start */
  3. grid-column: 2 / span 3;
  4. /* 添加的代码 end */
  5. }

第 12 关

grid-row-start 来指定网格项行的开始位置。

玩游戏入门 Grid 布局 - Grid Garden - 图13

grid-row-start 来浇水吧~

代码:

  1. #water {
  2. /* 添加的代码 start */
  3. grid-row-start: 3;
  4. /* 添加的代码 end */
  5. }

第 13 关

grid-rowgrid-row-startgrid-row-end 的缩写。

玩游戏入门 Grid 布局 - Grid Garden - 图14

grid-row 来浇水吧~

代码:

  1. #water {
  2. /* 添加的代码 start */
  3. grid-row: 3 / span 3;
  4. /* 添加的代码 end */
  5. }

第 14 关

玩游戏入门 Grid 布局 - Grid Garden - 图15

同时使用 grid-columngrid-row 来除草吧~

代码:

  1. #poison {
  2. /* 添加的代码 start */
  3. grid-row: 5;
  4. grid-column: 2;
  5. /* 添加的代码 end */
  6. }

第 15 关

玩游戏入门 Grid 布局 - Grid Garden - 图16

继续使用 grid-columngrid-row 来浇水吧~

代码:

  1. #water {
  2. /* 添加的代码 start */
  3. grid-row: 1 / 6;
  4. grid-column: 2 / 6;
  5. /* 添加的代码 end */
  6. }

第 16 关

grid-areagrid-row-start, grid-column-start, grid-row-end, grid-column-end 的缩写,值之间用 / 分隔。

玩游戏入门 Grid 布局 - Grid Garden - 图17

grid-area 来浇水吧~

代码:

  1. #water {
  2. /* 添加的代码 start */
  3. grid-area: 1 / 2 / 4 / 6;
  4. /* 添加的代码 end */
  5. }

第 17 关

一个容器下,可以设置多个网格项。

玩游戏入门 Grid 布局 - Grid Garden - 图18

设置第二个 grid-area 来浇水吧~

代码:

  1. #water-1 {
  2. grid-area: 1 / 4 / 6 / 5;
  3. }
  4. #water-2{
  5. /* 添加的代码 start */
  6. grid-area: 2 / 3 / 5 / -1;
  7. /* 添加的代码 end */
  8. }

第 18 关

根据 order 值来决定重叠的网格项的上下顺序,类似 z-index。值越大,越在上面,默认值是 0。

玩游戏入门 Grid 布局 - Grid Garden - 图19

第二列的胡萝卜中毒了并且最后有杂草的那一列也浇了水。现在就改变中毒的网格项的 order 的值来修复它们吧!

代码:

  1. #poison {
  2. /* 添加的代码 start */
  3. order: 1;
  4. /* 添加的代码 end */
  5. }

第 19 关

order 值可以是负数。

玩游戏入门 Grid 布局 - Grid Garden - 图20

现在水和中毒的土地是交替出现的,并且所有的杂草都出现在每一列的开始。设置中毒土地的正确的 order 值来修复它们吧!

代码:

  1. .poison {
  2. /* 添加的代码 start */
  3. order: -1;
  4. /* 添加的代码 end */
  5. }

第 20 关

在容器上,使用 grid-template-columns 设置有几列,以及每列的宽度。如 grid-template-columns: 20% 20% 20% 20% 20%;,创建了5个列,每一列设置为容器宽度的20%。

玩游戏入门 Grid 布局 - Grid Garden - 图21

grid-template-columns 设置一个新的值来给你的胡萝卜浇水吧!你想要将第一列的宽度设置为50%。

代码:

  1. #garden {
  2. display: grid;
  3. /* 添加的代码 start */
  4. grid-template-columns: 50% 20% 20%;
  5. /* 添加的代码 end */
  6. grid-template-rows: 20% 20% 20% 20% 20%;
  7. }
  8. #water {
  9. grid-column: 1;
  10. grid-row: 1;
  11. }

第 21 关

repeat函数 可以对相同宽度的网格项做缩写。grid-template-columns: 20% 20% 20% 20% 20%; 可以缩写为 grid-template-columns: repeat(5, 20%);

玩游戏入门 Grid 布局 - Grid Garden - 图22

使用 grid-template-columns 属性以及 repeat函数,创建8列,每列占12.5%的宽度。这样你就不会给花园浇过多的水。

代码:

  1. #garden {
  2. display: grid;
  3. /* 添加的代码 start */
  4. grid-template-columns: repeat(8, 12.5%);
  5. /* 添加的代码 end */
  6. grid-template-rows: 20% 20% 20% 20% 20%;
  7. }

第 22 关

grid-template-columns 不仅仅只接受百分比的值,也接受像像素或 em 这样的长度单位。你甚至可以将不同的长度单位混合使用。

玩游戏入门 Grid 布局 - Grid Garden - 图23

将列的宽度设置为 100px、3em 和 40%。

代码:

  1. #garden {
  2. display: grid;
  3. /* 添加的代码 start */
  4. grid-template-columns: 100px 3em 40%;
  5. /* 添加的代码 end */
  6. grid-template-rows: 20% 20% 20% 20% 20%;
  7. }

第 23 关

网格系统也引入了一个新的单位,分数 fr。每一个 fr 单元分配一个可用的空间。比如说,如果两个元素分别被设置为 1 fr 和 3 fr ,那么空间就会被平均分配为4份;第一个元素占据1/4,第二个元素占据3/4。

玩游戏入门 Grid 布局 - Grid Garden - 图24

杂草占据了第一行的左 1/6,胡萝卜占据着剩下的 5/6。创建两个列,并使用 fr 单位来定义它们的宽度。

代码:

  1. #garden {
  2. display: grid;
  3. /* 添加的代码 start */
  4. grid-template-columns: 1fr 5fr;
  5. /* 添加的代码 end */
  6. grid-template-rows: 20% 20% 20% 20% 20%;
  7. }

第 24 关

当列的宽度采用像素,百分比或者 em 的单位的时候,其他使用 fr 单位设置的列将会平分剩下的空间。

玩游戏入门 Grid 布局 - Grid Garden - 图25

这里的胡萝卜在左边形成了一个50像素的列,并且杂草在右边也占据着50像素的宽度。使用 grid-template-columns 属性,创建这两个列,使用 fr 再创建三列,使其平均占据剩下的空间。

代码:

  1. #garden {
  2. display: grid;
  3. /* 添加的代码 start */
  4. grid-template-columns: 50px repeat(3,1fr) 50px;
  5. /* 添加的代码 end */
  6. grid-template-rows: 20% 20% 20% 20% 20%;
  7. }

第 25 关

玩游戏入门 Grid 布局 - Grid Garden - 图26

现在,在你的花园的左边有一列杂草,占据75像素宽。剩余空间的3/5正在长着胡萝卜,剩下的2/5已经杂草泛滥了。用 grid-template-columns 属性,将 pxfr 单位结合起来,来制作必要的列。

代码:

  1. #garden {
  2. display: grid;
  3. /* 添加的代码 start */
  4. grid-template-columns: 75px 3fr 2fr;
  5. /* 添加的代码 end */
  6. grid-template-rows: 100%;
  7. }

第 26 关

在容器上,使用 grid-template-rows 来设置行。

玩游戏入门 Grid 布局 - Grid Garden - 图27

grid-template-rows 属性来为花园中除了顶部50像素之外的所有区域浇水。注意:水被设置为仅填充第五行,所以你总共需要创建5行。

代码:

  1. #garden {
  2. display: grid;
  3. grid-template-columns: 20% 20% 20% 20% 20%;
  4. /* 添加的代码 start */
  5. grid-template-rows: 50px 0 0 0 1fr;
  6. /* 添加的代码 end */
  7. }

第 27 关

grid-templategrid-template-rowsgrid-template-columns 的缩写形式,值之间用 / 分隔。比如,grid-template: 50% 50% / 200px; 将创建一个具有两行的网格,每一行占据50%,以及一个200像素宽的列。

玩游戏入门 Grid 布局 - Grid Garden - 图28

尝试着使用grid-template属性来浇水,需要包括你的花园上部的60%,以及左侧的200像素。

代码:

  1. #garden {
  2. display: grid;
  3. /* 添加的代码 start */
  4. grid-template: 60% 40% / 200px 1fr;
  5. /* 添加的代码 end */
  6. }

第 28 关

玩游戏入门 Grid 布局 - Grid Garden - 图29

你在花园的底部留下了50像素的小路,其他的空间用来种植胡萝卜。不幸的是,胡萝卜地的20%已经杂草丛生了,最后一次用 CSS 网格布局来规划你的花园吧!

代码:

  1. #garden {
  2. display: grid;
  3. /* 添加的代码 start */
  4. grid-template: 1fr 50px / 20% 1fr;
  5. /* 添加的代码 end */
  6. }

总结

Grid 布局比 Flexbox 布局更强大。本文介绍的只是 Grid 布局的基础用法。想了解更多 Grid 布局的内容,推荐阅读:最强大的 CSS 布局 —— Grid 布局