N3xtchen 的数字花园

Search

Search IconIcon to open search

CSS 布局: Grid(网格)

上次更新于 Mar 21, 2023 编辑源文件

Grid 布局1 由 W3C 前 CSS 工作组主席 Bert Bos 和谷歌工程师 Tab Atkins Jr. 共同设计和开发。该规范于 2017 年 6 月 6 日成为官方 W3C 推荐标准,并且已成为现代 Web 开发中广泛使用的布局模型之一。Grid 布局的设计理念是提供一种灵活、强大、直观的方式来实现多种精美页面布局。它提供了一种二维网格来定义和控制页面上的工作区域,以及一个简单易用的 API 来管理和布置网格项。

# Grid 布局的特点

Grid 布局 具有非常强大、灵活、易于维护和自适应等特点,非常适合用于开发复杂的网格布局。

  1. 二维布局:可以在水平方向和垂直方向上同时处理布局。
  2. 分割轨道:允许将轨道分割为具有相同或不同大小的网格单元格,从而创建复杂的布局。
  3. 明确布局:开发人员可以使用明确的语法和属性来定义各个元素的位置和大小。
  4. 自适应布局:具有自适应的特点,可以根据设备大小和方向动态地调整布局。
  5. 灵活性:具有非常大的灵活性,可以处理各种情况,包括多列、多行、等高度和非等高度的网格。
  6. 重叠单元格:允许网格单元格重叠,从而可以创建更复杂的布局。

# Grid 布局的适用场景

  1. 多列布局:使用Grid 布局创建多列布局非常容易,可以定位和对齐列,从而在网格和剩余空间之间创建新的缩放和滚动上下文。
  2. 多行布局:Grid 布局的行轨道和列轨道都可以设置空间,可以通过使用无数线实现多行布局,无论是网格或其他非结构化元素都可以嵌套在行中。
  3. 水平和垂直居中:使用 Grid 布局可以非常容易地将元素居中,只需要将它们发布到网格的中心即可。这还可以方便地实现垂直对齐。
  4. 自适应布局:使用Grid 布局可以让元素自由地在多个屏幕尺寸上自适应,这使得开发 Responsive Layout 等越来越受欢迎。

# 能够取代表格布局和多列布局吗?

在过去,表格布局多列布局被广泛用于创建复杂的网格式页面布局,但它们都有一些缺点。表格布局的缺点包括难以使单元格大小相等,以及单元格过度嵌套的风险;多列布局仅适用于单行内容,无法有效地处理多行内容。

# Grid 布局的模型介绍

Grid lines

Grid 布局中,网格容器(Grid Container) 的内容通过定位和对齐放置在网格中。Grid 是一组相交的水平和垂直网格线(Grid Lines),将网格容器的空间分成网格区域(Grid Areas)网格项(Grid Items)(代表网格容器的内容)可以放置在其中。网格线分为两组:一组定义沿块轴运行的列(Columns),另一组定义沿内联轴运行的行(Rows)2

上图的的 CSS 的代码实现如下:

1
2
3
4
5
#grid {
	display: grid;
	grid-template-columns: 150px 1fr;
	grid-template-rows: 50px 1fr 50px;
}

网格轨道(Grid Track) 是指的通用术语(就是某一行或者某一列),换句话说,它是两个相邻网格线之间的空间。每个网格轨道分配了一个尺寸函数,该函数控制该列或行可以增长多宽或多高,从而控制其边界网格线之间的距离。

网格单元格(Grid Cell) 是网格行和网格列的交点,是网格中可以在定位网格项时引用的最小单位

网格区域(Grid Area) 是用于布置一个或多个网格项的逻辑空间。一个网格区域由一个或多个相邻网格单元组成。它由四条网格线约束网格区域的每一侧各一条,并参与其相交的网格轨道的大小调整。网格区域可以使用网格容器grid-template-areas 属性显式命名,或通过其边界网格线隐式引用。使用 grid-placement 属性将网格项分配给网格区域

网格区域网格项的区别?以及如何使用呢?

网格区域间不可相互重叠的,而且它是逻辑空间而不是实际空间;而网格项代表网格容器的具体内容,不同的网格项可以相互重叠(所以多个网格项可以占用同一个网格区域,而且分配同一个网格区域网格项之间不会相互影响,可以看一下官方的例子3)。

如果你的布局要求是需要将若干个网格单元格组合在一起,形成一个大的区域,然后将元素放置在这个大的区域中,那么使用网格区域可能更加方便

如果你的布局要求是需要在整个网格容器灵活地布局多个元素,并且它们的尺寸和位置也没有明显的规律,那么使用网格项更加方便

# fr:可变长度的单位

我们先看一个例子,grid-template-columns: 150px 1fr 1fr; 说明将声明一个有 3 列的网格布局

frfraction 的缩写,故名思义,分数网格容器根据分数自动伸缩长度。某一列/行的份额计算方式:$$剩余空间 *\frac{fr_{某一行或列}}{\sum^{i=1}_{i<={最大行或列数}}{fr_i}}$$ 将行/列上,将不可伸缩的行/列的宽度固定(就是例子中的第一列),对于可伸缩的行/列(即单位是 fr,就是例子中第 2 和 3 列)根据份额百分比进行伸缩。

# 网格布局的使用

假设我需要将第一行作为 header,最后一行作为 footer,中间左边是 sidebar 以及中间右边作为 main

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#header {
	background-color: blue;
	grid-row: 1;
	grid-column: 1 / span 2;
}

#sidebar {
	background-color: yellow; 
	grid-row: 2;
	grid-column: 1;
}

#main {
	background-color: green; 
	grid-row: 2;
	grid-column: 2;
}

#footer {
	background-color: grey; 
	grid-row: 3;
	grid-column: 1 / span 2;
}