❕Grid
a two-dimensional grid-based layout system
CSS grid layout,又称 CSS grid 或 grid,是一种基于二维网格的布局系统,它擅长将页面划分成行和列。
和 table 一样,grid 也能让元素对齐到 row 和 column 中。但 grid 能更容易地实现更多其它布局,比如它的子元素可以 position(定位)自己,即子容器实际上是 overlap(重叠)和 layer(分层)的,类似于 CSS 的 positioned elements(定位元素)。
和 flexbox 类似,grid items 的 order 也能通过 CSS 来设置,好处是可以用 media query 来灵活摆放。
1. 相关术语
grid container:设置了
display: grid
的元素grid item:是 grid container 的(直接)子元素
grid line:是构成 gird 结构的 dividing lines,位于行或列的任意一侧
可以是 vertical 的 column grid lines
也可以是 horizontal 的 row grid lines
grid track:两条相邻 grid lines 之间的空间。可以视为 grid 的 row 或 column
grid area:被四条 grid lines 围起来的总空间。可能是由多个 grid cells 组成的
grid cell:被两条相邻 row grid lines 和两条相邻 column grid lines 围起来的空间。它是 grid 的 unit

2. container 属性
2.1 display
display
定义了一个 grid container,为其内容建立了一个新的 grid formatting context(grid 格式化上下文)。
display: grid; /* block-level grid */
display: inline-grid; /* inline-level grid */
2.2 行和列
2.2.1 “布局”行和列
grid-template-columns
grid-template-rows
以上两个属性用“以空格分隔的 values 列表”的形式定义了 grid 的 columns 和 rows,其中 value 是 track size 的值,它们之间的空间就是 grid line。
value 的取值可以是:<track-size>
, <line-name>
。
(1)<track-size>
/* 列 */
grid-template-columns: 1fr 1fr 1fr; /* fr: a fraction of the free space */
grid-template-columns: repeat(3, 1fr); /* 效果同上 */
grid-template-columns: 50px 1fr 100px; /* <length> */
grid-template-columns: 10% 1fr 30%;
/* 行 */
grid-template-rows: 1fr 1fr;
(2)<line-name>
grid lines 会被自动分配对应的数字,正序是从 1 到 n,倒序是从 -1 到 -n。如下:
也可以给 grid lines 命名。比如:
/* grid lines 用默认编号 */
grid-template-columns: 40px 50px auto 50px 40px;
/* 给 grid lines 命名 `[]` */
grid-template-columns: [first] 40px [line2] 50px [line3] auto [col4-start] 50px [five] 40px [end];
/* 给一个 grid line 命多个名字 `[?-?]` */
grid-template-rows: [row1-start] 25% [row1-end] 100px [third-line] auto [last-line];
如果设置的 <line-name>
是重复的,可以用 repeat()
简化下。比如:
grid-template-columns: 20px [col-start] 20px [col-start] 20px [col-start];
grid-template-columns: repeat(3, 20px [col-start]);
上面代码的多个 grid lines 有相同的名字,如果想引用某个 line,可以用 line name 和 count。比如:
grid-column-start: col-start 2;
2.2.2 给行和列“贴瓷砖”
grid-template-areas
定义了一个 grid template,通过引用“子容器”的 grid-area
属性指定的 grid area 的 name。
grid-template-areas
本身就提供了 grid structure 的可视化。看个例子:
/* 父容器 */
.grid {
display: grid;
/* 会创建一个 4 列 3 行的 grid */
grid-template-areas:
"header header header header" /* 重复的 grid-area name 会让内容横跨这些 cells */
"main main . sidebar" /* . 表示 empty cell */
"footer footer footer footer";
}
/* 子容器 */
.grid>div:nth-child(1) {
grid-area: header;
background-color: orange;
}
.grid>div:nth-child(2) {
grid-area: main;
background-color: deepskyblue;
}
.grid>div:nth-child(3) {
grid-area: sidebar;
background-color: pink;
}
.grid>div:nth-child(4) {
grid-area: footer;
background-color: green;
}
关于 grid-template-areas
属性的相关说明:
每个 row 必须有相同数量的 cells,否则该声明会失效
连续的多个
.
只代表一个 empty cell,除非它们之间有“空格”分隔符它不 name(命名)grid lines,只 name(命名)areas,虽然此时 area 两端的 lines 会被自动命名。比如 grid area 是
foo
,那么该 area 起始的 row line 和 column line 都叫foo-start
,最后的 lines 都叫foo-end
。这就意味着,有的 line 可能会有多个名字,比如上例中最左侧的 line 有三个名字header-start
,main-start
,footer-start
当它设置的 column 的数量和
grid-template-columns
的个数不一致时优先取
grid-template-columns
的值若
grid-template-areas
少了,就用其它子容器补齐若
grid-template-areas
多了,则多出来的子容器width:auto
(整体会保证列对齐)
可以这样理解:
grid-template-columns/rows
负责 layout(布局)grid-template-areas
负责 span(平铺/贯穿/横跨)



2.2.3 属性缩写
grid-template
是以上三个属性的缩写,格式是:
<grid-template-areas> <grid-template-rows> / <grid-template-columns>
看几个例子,代码如下:
grid-template:
"a a a" 40px
"b c c" 40px
"b c c" 40px / 1fr 1fr 1fr;
grid-template:
"b b a" auto
"b b c" 2ch
"b b c" 1em / 20% 20px 1fr;
grid-template:
"a a ." minmax(50px, auto)
"a a ." 80px
"b b c" auto / 2em 3em auto;
以上代码,会依次显示下面的布局:
相关说明:
格式
<grid-template-rows> / <grid-template-columns>
会把grid-template-areas
设置成none
当设置
grid-template: none
时,表示这三个属性的值都是它们的 initial values。也就是说,grid-template
不会隐式重置 grid properties,而通常写none
都是想 reset 各个属性的值。所以,与缩写相比,更推荐用单个属性此外,个人的使用感受是:不推荐用缩写。一是功能上杂糅了对 rows 和 columns 的“布局”和“贴片”,二是视觉上也怪眼花缭乱的...
2.3 分配“整体”的剩余空间
有时,内容的总 size 会比 grid container 的小,此时就可以用以下属性设置 grid 在 row 或 column 上的对齐。
justify-content
:在 row axis 上分配剩余空间align-content
:在 column axis 上分配剩余空间place-content
缩写:<align-content> / <justify-content>
取值可以是:
start
,end
,center
stretch
space-around
,space-between
,space-evenly
2.4 cell 内沿 axis 的对齐
用来设置 grid items 在 grid cell 里沿 row axis 或 column axis 的对齐。
justify-items
align-items
place-items
缩写:<align-items> / <justify-items>
取值可以是:
公共取值:
start
,end
,center
,stretch
baseline
:align-items
属性时
2.5 间隔
指定 grid line 的 size,可以视作是 columns 之间或 rows 之间的 gutter(间距)with,不含外边缘。
row-gap
column-gap
gap
缩写:<row-gap> <column-gap>
/* standard */
row-gap: 15px;
column-gap: 10px;
gap: 15px 10px;
/* 旧用法 */
grid-row-gap: 15px;
grid-column-gap: 10px;
grid-gap: 15px 10px;
2.6 指定隐式创建的 track size
grid-auto-colums
指定隐式创建的 track size。
隐式创建,也称自动生成。当 grid items 多于 grid cells 时,或当一个 grid item 放在了显式 grid 之外时,就会创建隐式 track。这样做的好处是,让 grid 更灵活地摆放它的 items,因为我们可以不必(显式地)指定每个 track,也不必手动放置每个 item。显式指定 track 的属性有 grid-template-rows
和 grid-template-columns
。
通过两个例子,感受下增加了 grid-auto-colums
属性之后的 UI。如下:

说明:
grid-column: 5 / 6
表示从 column line 5 到 column line 6grid-row: 2 / 3
表示从 row line 2 到 row line 3
2.7 有隐式 track 时如何放置 items
当有创建隐式 track 时,就会启动 auto-placement algorithm(自动放置算法)来布局 items。grid-auto-flow
属性就是用来控制该算法的工作方式的,它可以指定 items 如何流入 grid。
取值可以是:
row
(默认):依次填充每 row,并根据需要添加新 rowcolumn
:依次填充每 column,并根据需要添加新 columndense
:如果后面有更小的 items 来了,则尝试更早地填充 grid holes
单词“dense”:密集的,稠密的
dense 算法,会回溯找能填的 holes,所以 items 可能会乱序
单词“sparse”:稀少的,稀疏的
sparse 算法,只向前移动 items,但从来不回溯,所以 items 是有序的
看个例子:
.container {
display: grid;
grid-template-columns: repeat(5, 60px);
grid-template-rows: repeat(2, 30px);
}
.item:nth-child(1) {
grid-column: 1;
grid-row: 1 / 3;
}
.item:nth-child(5) {
grid-column: 5;
grid-row: 1 / 3;
}
当分别设置 grid-auto-flow
的值是 row
和 column
时,items 的布局依次如下图:
.container {
grid-auto-flow: row;
}
.container {
grid-auto-flow: column;
}
2.8 grid
缩写
grid
缩写grid
是个缩写属性,用来设置所有 explicit(显式)和 implicit(隐式)的 grid 属性。
grid-template-rows
grid-template-columns
grid-template-areas
grid-auto-rows
grid-auto-columns
grid-auto-flow
缩写的属性值的形式看起来挺费劲的,这里就不展开介绍了,等把单个属性用熟练了再补充。
3. items 属性
3.1 放置和堆叠
通过引用特定的 grid lines 来确定 grid item 的位置。
当 items 之间相互重叠时,可以使用 z-index
控制它们的堆叠顺序。如果没有指定 grid-xxx-end
,则 item 默认会跨 1 个 track。
grid-column-start
grid-column-end
grid-row-start
grid-row-end
grid-column
缩写:<grid-column-start> / <grid-column-end>
grid-row
缩写:<grid-row-start> / <grid-row-end>
eg1. 使用默认编号的 grid line
grid-column-start: 2;
grid-column-end: 4; /* 从 line2 到 line4(实际跨了2列) */
grid-column-end: span 3; /* 从 line2 开始,跨 3 列 */
eg2. 命名的 grid line
/* 图左 */
.item-a {
grid-column-start: 2;
grid-column-end: five;
grid-row-start: row1-start;
grid-row-end: 3;
}
/* 图右 */
.item-b {
grid-column-start: 1;
grid-column-end: span col4-start;
grid-row-start: 2;
grid-row-end: span 2;
}
eg3. 缩写
.item-c {
grid-column: 3 / span 2;
grid-row: third-line / 4;
}
3.2 给 item 命名
grid-area
属性可以给 item 一个名字,以便被 grid-template-areas
属性引用。
grid-area: header;
grid-area: main;
grid-area: sidebar;
grid-area: footer;
grid-area
属性也可以用作更短的缩写。
/* <grid-row-start> / <grid-column-start> / <grid-row-end> / <grid-column-end> */
grid-area: 1 / col4-start / last-line / 6;
3.3 cell 内沿 axis 的对齐
设置本 item 在单个 grid cell 里沿 row axis 或 column axis 的对齐方式
justify-self
align-self
place-self
缩写:<align-self> / <justify-self>
作用同父容器的在 cell 内沿 axis 对齐,只是这三个属性只控制本 item。
主要参考
Last updated