CSS Grid 布局

为什么CSS Grid很重要?

  因为 CSS Grid 布局是 Web 的第一个真正的布局系统。它的目的是将内容组织成行列的形式,最终使开发人员能高度控制我们眼前屏幕上页面的显示效果。这意味着我们终于可以摒弃多年的各种 hack 和 trick 了,CSS Grid 布局不仅仅可以使复杂的布局和精美的排版成为可能,而且还可以使其变的干净利落可维护
CSS网格布局是浏览器Flexbox布局之后最重要的布局方式

专业术语 

在整个网格中常用到的术语有:网格线(Grid lines)、水平或纵向网格轨道(Grid tracks)。网格轨道其实就相当于行(rows)和列(columns),而且两者之间有一个间距(Gutters)。在网格轨道相交的区域,就是单元格(Grid cells),相当于table中的单元格著作权归作者所有。

网格线(Grid lines)


上图突出显示的红线就是第二列的网格线(line2)。

网格轨道(Grid track )

网格轨道就是相邻两个网格线之间的空间,就好比表格中行或列。所在在网格中其分为grid column和grid row。每个网格轨道可以设置一个大小,用来控制宽度或高度。

图中突出显示的就是行线line2和line3之间组成的网格轨道。

网络单元格(Grid cell)


图中突出显示的单元格是由行线line2、line3和列表line2、line3组成的。

网格区域(Grid area)

格区域是由任意四条网格线组成的空间,所以他可能包含一个或多个单元格。相当于表格中的合并单元格之后的区域。

图中突出显示的网格区域是行线line1、line3和列线line2、line4之间的区域,其主要包括了四个网格单元格。

网格容器(Grid Containers)

通过使用display属性给元素显式设置了属性值grid或inline-grid,此时这个元素将自动变成网格容器。这个类似于flexbox一样,将元素设置设置为display:flex,元素将自动变成弹性盒模型。

由于网格容器不是块容器,所以有部分属性在网格布局中将会失效:

  1. 多列布局模块中的所有column-*属性运用在网格容器上将失效
  2. float和clear使用在网格项目(网格单元格Grid Cell)上将失效
  3. vertical-align使用在网格单元格上将失效
  4. ::first-line和::first-letter这样的伪元素不能应用在网格容器上

CSS 网格布局具体实例

如下代码

1
2
3
4
5
6
7
8
<div class="wrapper">
<div class="letter">
A
</div>
<div class="letter">
B
</div>
</div>

首先,我们使用 font-size 和 color 设置这些字母的字体和颜色,然后使用诸如 align-items 和 justify-content 之类的 flexbox 属性将其居中。CSS Grid 没有替换 flexbox 属性,尽可能保留了它们的功能。我们甚至可以将这些属性与 CSS Grid 结合。但是现在先让我们回到这个 demo:

在上面这个例子中,一个大的 div 又包含着两个 div ,它们默认属性是 display: block。接下来我们用 Grid layout 设置父类元素:

1
2
3
.wrapper {
display: grid;
}

完整的html和css代码如下:

1
2
3
4
5
6
7
8
<div class="wrapper">
<div class="letter">
A
</div>
<div class="letter">
B
</div>
</div>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
body,html {
padding: 0;
margin: 0;
}
.wrapper {
display: grid;
}
.letter {
background-color: #0069b3;
display: flex;
justify-content: center;
align-items: center;
padding: 20px;
font-size: 70px;
color: white;
line-height: 1;
font-family: 'hobeaux-rococeaux-background', Helvetica;
font-weight: 200;
cursor: pointer;
transition: all .3s ease;
}

则显示结果如下:

事实上,想让我们的 grid 起作用,首先需要给它设置一个确切的行数和列数。在这个例子中,我们可以让两个字母并排排列:

1
2
3
4
5
6
.wrapper {
display: grid;
grid-template-columns: 1fr 1fr;
grid-column-gap: 1px;
background-color: black;
}

效果如下:

首先我们用 grid-template-columns 创建了一个两列的网格,如果你以前没见过这样的,那 1fr 可能看起来比较奇怪 ,但它是有效的 CSS 单元,可以将每一列列为我们网格的一小部分。在这个例子中,意味着让两列等宽。
两列之间的黑线是 wrapper 勾勒的每个字母 div 的背景,因为我们将 grid-column-gap 设置为了 1px。通常,我们会设置更大的距离,尤其是对于两个相邻的文本框来说。但在本例中,1px 就足够了。
如果我们再添加两个新字母会怎样呢?我们应该怎么改变布局?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<div class='wrapper'>
<div class='letter'>
A
</div>
<div class='letter'>
B
</div>
<div class='letter'>
C
</div>
<div class='letter'>
D
</div>
</div>

加两个字母之后也没啥神奇的效果。加两个字母对网格没什么影响,为什么呢?因为我们已经将其设置成了两列,所以这两个字母的 div 直接被放在了它们下面,并且正好是 1fr宽:

grid-column-gap 只用于列,要想实现A,C之间以及B,D之间也有1px的距离。需要设置grid-row-gap

1
2
3
4
.wrapper {
grid-column-gap: 1px;
grid-row-gap: 1px;
}

效果如下

响应式网格如何实现

1
2
3
4
5
6
7
8
9
10
11
12
.wrapper {
display: grid;
grid-template-columns: 1fr 1fr;
@media screen and (min-width: 500px) {
grid-template-columns: 1fr 1fr 1fr;
}
@media screen and (min-width: 800px) {
grid-template-columns: 1fr 1fr 1fr 1fr;
}
}


分析下段代码

1
2
3
4
5
.wrapper {
display: grid;
grid-template-columns: 3fr 1fr 1fr;
grid-template-rows: 1fr 3fr;
}

我们现在可以设置行高之间的关系。如果我们把前面的行高设成 1fr ,最后一个则设置为 3fr,这意味着第二行的行高是第一行的3倍:

实现一个基本的网格布局,总结一下这四个基本步骤:

  1. 创建一个容器,通过display:grid;声明这个容器是一个网格容器
  2. 同样在容器中设置grid-template-columns和grid-template-rows声明网格轨道(声明行和列)
  3. 在网格容器中添加子元素,创建网格项目(单元格)
  4. 使用grid-column和grid-row来指定网格项目(单元格)的列和行

参考文献 CSS Grid 布局入 门
     什么是 CSS Grid

坚持原创技术分享,您的支持将鼓励我继续创作!