本文为译文,原文地址: http://jonibologna.com/spring-into-css-grid,作者,@jonitrythall
CSS 网格(Grid)最近一直受到很多的关注,我终于在过去的一个周末腾出时间来了解它的基本工作原理。道路很曲折,前途很美好(说真的,这是改变生活的东西),但是我在创建示例并分享的同时,整理了一些笔记。
这篇文章不是只看看这个布局功能有多强大,而是希望它在这混乱中把威胁因素移除,或者进入 CSS 网格。
制定一个计划
和学习任何网络新事物一样,我立即打开 Adobe Illustrator,感受自然,网格和紫色带来的灵感,我开始绘制一个基本的户外场景,然后开始尝试用 CSS 网格来实现。
下图为我的最终搞:

标记
标记由一个 class 名为 contain 的 div 主容器以及十二个 class 名为 spring 的子集 div 组成。HTML 和 CSS 代码片段如下:
<div class="contain">
<div class="spring">
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/80625/sun.svg" alt="Sun" width="15%" />
</div>
<div class="spring">
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/80625/cloud_copy.svg" alt="Cloud" width="30%" />
</div>
<div class="spring">
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/80625/cloud_copy.svg" alt="Cloud" width="30%" />
</div>
<div class="spring"><img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/80625/rain.svg" alt="Rain" width="60%" /></div>
<div class="spring">
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/80625/rain.svg" alt="Rain" width="60%" />
</div>
<div class="spring">
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/80625/rain.svg" alt="Rain" width="27%" />
</div>
<div class="spring">
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/80625/dragonfly.svg" alt="Dragonfly" width="30%" />
</div>
<div class="spring">
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/80625/butterfly.svg" alt="Butterfly" width="30%" />
</div>
<div class="spring">
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/80625/dragonfly.svg" alt="Dragonfly" width="30%" />
</div>
<div class="spring">
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/80625/butterfly.svg" alt="Butterfly" width="30%"/>
</div>
<div class="spring">
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/80625/flower1.svg" alt="First flower" />
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/80625/flower2.svg" alt="Second flower" />
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/80625/flower3.svg" alt="Third flower" />
</div>
<div class="spring">
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/80625/flowers2.svg" alt="Fourth flower" />
</div>
</div>
$orange: #FB9C6F;
body {
border: 2px solid $orange;
}
.contain {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: repeat(3, 2fr) 1fr 4fr;
grid-gap: 2px;
background-color: $orange;
}
.spring {
padding: 2em;
display: flex;
justify-content: center;
align-items: center;
background-color: #FFF;
}
// Sun
.spring:nth-child(1) {
grid-column: 1 / 5;
}
// Cloud 1
.spring:nth-child(2) {
grid-column: 1 / 3;
}
// Cloud 2
.spring:nth-child(3) {
grid-column: 3 / 5;
}
// Rain 1
.spring:nth-child(4) {
grid-column: 1 / 2;
}
// Rain 2
.spring:nth-child(5) {
grid-column: 2 / 3;
}
// Rain 3
.spring:nth-child(6) {
grid-column: 3 / 5;
}
// Flowers 1
.spring:nth-child(11) {
grid-column: 1 / 4;
justify-content: space-around;
}
// Flowers 2
.spring:nth-child(12) {
grid-column: 4 / 5;
}
// Just simplifying for smaller window
@media (max-width: 550px) {
.contain {
display: block;
}
.spring:nth-child(3),
.spring:nth-child(5),
.spring:nth-child(6),
.spring:nth-child(7),
.spring:nth-child(8),
.spring:nth-child(11) {
display: none;
}
img {
width: 30%;
}
}
在实现网格之前,布局是标准的状态,所有的图像堆叠在一起。如下图:

columns
使用网格时首先需要在 CSS 网格容器中声明它:
.contain {
display: grid;
}
注意:这里也有
inline-grid和subgrid作为选项。
这里将立即设置容器内所有的子元素为网格项。
初始网格基于使用 grid-template-columns 属性设置的四个相同大小的列。
.contain {
display: grid;
grid-template-columns: repeat(4, 1fr);
}
repeat 函数允许缩短 1fr 1fr 1fr 1fr 的写法。
fr 单位
网格属性可以接受多个不同的单位值,本例中只使用了 fr。这个单位是超级聪明和灵活的,因为它将可用空间划分为分数,所以 1fr 1fr 1fr 1fr 将生成四个相同大小的列。
网格间距
网格间距由每个项目的 2px 橙色间距表示。间隙显示主容器的背景颜色,为橙色,外边框是 body 本身。每个网格包含一个白色背景的图像。

示例使用缩写 grid-gap 来匹配 grid-column-gap 和 grid-row-gap。该属性接受单个共享值或者两个不同的值,第一个参数表示行,第二个表示列。
从列起点和终点来排列项目
一旦在主容器上设置基本列,容器中的每个子元素 div 都可以单独进一步设计,已实现以下网格:

这是通过 grid-column-start 和 grid-column-end 属性或 grid-column 简写来指定元素的起点和终点来完成的。
例如,每个后代元素 div 起点和终点定义如下:
.spring:nth-child(4) {
grid-column: 1 / 2;
}
.spring:nth-child(5) {
grid-column: 2 / 3;
}
.spring:nth-child(6) {
grid-column: 3 / 5;
}
第四列项目(第一个雨图像容器)的 grid-column: 1 / 2 ; 指示它在第一垂直网格线开始并在第二列结束,而第六项(第三个云图像容器)被设置为在第三垂直网格线开始并在第五列结束,使其成为其它的两倍。

最初这可能有点棘手,因为垂直线超过了实际网格列单元的个数。
太阳图像能够通过从第一垂直网线开始并在最后一行终止,即第五行,跨越所有四个可用单元格,从而占据全宽。
.spring:nth-child(1) {
grid-column: 1 / 5;
}

没有必要对蜻蜓图像和蝴蝶图像做任何事情,因为所需的布局与主容器 .contain div 上的列声明一致。

rows
回到容器元素设置行,这是我来演示这个奇怪风景的最后一步。尽管初始列由相等的间距组成,但是行具有更多的变化。

前三行是最小行的两倍,而最大行是最小行的四倍,如下所示: grid-template-rows: repeat(3, 2fr) 1fr 4fr;
这个设计对于行的需求是相当轻的,这就是行样式所需的程度,但是行有自己的一组属性,有些甚至可以与列属性组合来创建速记法,保持 CSS 的简洁。
Flexbox
谈及 flexbox(并且最近创建了一个印刷视觉指南),我只想说,在这个示例中,flexbox 用于将图像在网格中居中,而网格和 flexbox 实际上可以一起使用。
使用如下,使得每张图片都在项目中居中:
.spring {
display: flex;
justify-content: center;
align-items: center;
}
div 包含三个独立的花图像,flexbox 也水平划分它们。

.spring:nth-child(11) {
display: flex;
justify-content: space-around;
}
Robin Rendle 最近在 CSS-Tricks 上写了有关这个主题的一个很好的总结。
浏览器支持
目前浏览器支持状况:

资源
这里有一些比较好的扩展阅读:
- Getting Started with CSS Grid Basic CSS Grid Concepts on MDN CSS Grid Layout on MDN The spec CSS Grid Garden
结尾
要了解 CSS Grid 的功能,还需要学习更多的东西,我迫不及待地写更多的内容,但希望这篇文章可以作为一个有趣的起点。