边学边玩CSS Grid

avatar
前端 @奇虎360

本文作者:刘观宇,360奇舞团高级前端工程师、技术经理,曾参加360导航、360影视、360金融、360游戏等多个大型前端项目。关注W3C标准、IOT、人工智能与机器学习的最新进展,W3C CSS工作组成员。

十年磨一剑,霜刃未曾试。今日把示君,谁有不平事。 —— 唐·贾岛《剑客》

游戏概况

Grid Garden1是Codepip2创建的一款寓教于乐的在线网页游戏,游戏共有28关。玩家可以通过过关的方式掌握CSS最新标准CSS Grid。

游戏的设定是一个花园种植胡萝卜的场景,玩家通过在代码区填写CSS Grid的相关代码完成除草、浇水等任务。通过玩家的辛勤劳作,一定能够吃上纯天然、无公害的胡萝卜。

打开游戏,我们发现,游戏存在多语言版。在左侧底部就可以切换各种语言。事实上,笔者对自己的英语水平是非常有信心的,所以毫不犹豫的切换到——简体中文版。

除了代码区和任务区,玩家可以在选关区选择28关的任意一关来挑战;当玩家在代码区敲入代码时候,右侧的任务和结果展示区会实时根据代码展现结果。如果代码完成了任务,则点击提交按钮,会进入下一关,如果玩家通关的话,则展示通关特效;如果代码不能完成任务,提交按钮会灰掉。如果玩家硬来,代码区会有一个错误特效供玩家欣赏:-(

除了游戏本身,游戏的目的是加深玩家对CSS Grid的理解。说到CSS Grid,这可是一种强大的Web页面布局方式。恰当的使用CSS Grid,可以高效地解决很多常见的布局问题,而且优雅、简洁。完整的CSS Grid属性参考,可查阅这里3。由于CSS Grid标准尚属CR(CR,Candidate Recommendation)阶段,如果你是最新标准的爱好者,还可以跟进CSS工作组关于CSS Grid的最新进展4

尽管如此,现在主流浏览器都已经有了不同程度的支持,支持度如下图所示:

说到这里,各位都迫不及待地想要在游戏中一试身手了吧,那么话不多说,Let's Go。

过关实录

跟网格项玩耍

也许各位玩家完全没有接触过CSS Grid,刚刚进来可能会有些不知所措。我们姑且认为前面几关是教学关。一般游戏的教学关都会有一个人物在屏幕上蹦来蹦去外加叨逼叨来普及各种概念和操作。那么笔者现在就来饰演一下这个人物。

  1. CSS Grid元素主要分为两大类:网格容器网格项网格容器是父元素,网格项是子元素。
  2. 对于网格容器网格项各有不同的属性修饰。
  3. 声明Grid布局要做的事情是在网格容器的CSS代码中指定display: grid;display: inline-grid;或者display: subgrid;
  4. 网格线构成网格结构的分界线,是定位网格项的参照。下图就是行row和列column的第一个网格线的位置。换句话说,对于一个每行有5列的网格,它的每一行总共有6个网格线。如果这点看不清楚,那可能需要复习植树问题了:-(

5. 网格轨道是指相邻的网格线之间的部分,下图箭头所指是一个网格轨道。

掌握了这些知识我们就可以开始过关之旅了。

第1关到第11关设置主要是针对网格项属性grid-column-startgrid-column-end展开的,相当的简单,相信玩家一定可以很快的完成。

下面简单总结一下第1-11关:

  1. grid-column-startgrid-column-end作用于网格项
  2. 上述值可配合使用来解决跨行跨列问题。
  3. grid-column-startgrid-column-end中,start不一定比end小,逆向是被允许的。
  4. 可以设置负值,负值的意思是从最后一个网格线算起的数值。
  5. 除了取数值外,还可以使用span关键字。格式是span <number>意思是跨越多少个网格轨道
  6. 可以使用grid-column: <start>/<end>来简写, span关键字适用此缩写。

上面可能出错的地方在于,设置数值时候,是确定网格线的顺序而非网格轨道的顺序,尤其是负数时候,而span后面跟着的数字是网格轨道的个数。只要牢记这点就很容易。

第12关与第13关,主要展示了CSS Grid在行row上设置的能力,二维空间的设置是Grid布局比flex布局拓展的一个方面。

这两关也比较简单。

从第14关开始,我们开始综合运用行与列的属性。 第14和15关的过关,需要灵活利用上述关键字。规范中还可以给轨道线命名,这里暂时没有遇到,我们先不使用“命名”这个利器。

第16关的意思是可以行列的简写方式,依然可以使用grid-area属性再次化简,grid-area接收4个由/隔开的值,依次为:grid-row-start, grid-column-start, grid-row-end, grid-column-end

第17关告诉我们,重迭覆盖是不影响计算机制的。

依然很简单,过。

针对17关的重叠,第18-19关引入了属性关键字:orderorder类似于z-index,表明叠放顺序,数值越大,越在上。允许负数。

很简单是不是。

跟网格容器玩耍

上面我们对网格项的“一波操作猛如虎”,下面我们再来看一看,对于网格容器的操作,能不能“横扫千军我做主”。

第20关到第22关主要针对网格容器的属性grid-template-columnsgrid-template-rows展开的。

下面简单总结一下第20-22关:

  1. grid-template-columnsgrid-template-rows用于设置Grid布局的行列中网格轨道的大小
  2. repeat函数可以简化多个同值,格式为repeat(N, value),其中N是个数,value是值。repeat可以与其他值混用,如:grid-template-columns: repeat(N-1, value) value
  3. 定义上述属性时,允许长度单位混合使用。

第23-25关,主要说明了关键字fr的使用。

下面总结一下第23-25关:

  1. fr是“分数”的英文单词fraction的简写。
  2. fr用于等分等分网格容器剩余空间。那么fr是怎么分配空间的呢?举个例子说明:设有A、B、C三个网格轨道,他们的grid-template-columns的设置依次是1fr2fr3fr。那么他们共同把一个行分为6等分,则A,B,C的空间就依次获得了这一行的1/6、2/6和3/6。
  3. fr是可以和其他单位混用的,如grid-template-columns: 1fr 50px 1fr 1fr;。计算优先级记住一点即可:除了auto之外,先计算所有固定值(包括百分数)后,剩下的空间再计算fr

第26关介绍grid-template-rows与前面的grid-template-columns语法类似。留给玩家尝试。

第27关介绍了grid-template-columnsgrid-template-rows的简写方式grid-template,写法是:grid-template-rows / grid-template-columns

经历了百转千回,我们终于来到了关底,我们来看看大BOSS的尊容:

WTF?只能写一行代码么? 仔细想想:grid-template最简洁,格式是/隔开的先行后列。 先解决行:需要把50px先分出去,后面100%给到花草。再解决列,列的场景是典型的fr使用场景,杂草占空间的1/5,胡萝卜占4/5。

于是代码是:grid-template: 1fr 50px/1fr 4fr;

Bingo!恭喜你,通关成功!

结语

是的,我们已经最快速度领略了CSS Grid的风采。然而,对于整个的CSS Grid我们仅仅做了最常用的展示,更多的好玩的做法,还要等待大家的发掘,以及标准的演进。

文内链接

  1. cssgridgarden.com/
  2. codepip.com/
  3. developer.mozilla.org/zh-CN/docs/…
  4. drafts.csswg.org/css-grid/

相关文章

致谢

感谢李松峰老师、高峰、刘博文对本文修订提出的中肯意见。 设计师王旋美眉帮忙设计了精美的题图。 在此诚挚的表示感谢。

关于奇舞周刊

《奇舞周刊》是360公司专业前端团队「奇舞团」运营的前端技术社区。关注公众号后,直接发送链接到后台即可给我们投稿。