读者请注意,本文章更新于 704 天前,文中某些信息可能已经过时,如有任何问题,请在文章末尾评论处留言!
机器人
AI摘要
AIGPT
生成中...

网格布局(grid)

网格布局是一套二维页面布局系统,以下内容来自学习css网格布局

启用网格

display 属性设为 gridinline-grid 就创建了一个网格容器,容器的所有直接子节点自动成为网格项目

  1. display: grid 网格项目按行排列,网格项目占用整个容器的宽度
  2. display: inline-grid 网格项目宽度由自身宽度决定
  3. display: subgrid 继承其父级网格容器的行列大小,它是其父级网格容器的一个网格项目

column、float、clearvertical-align 对网格容器没有效果

网格容器的一些属性

grid-template-columnsgrid-template-rows

属性 grid-template-columnsgrid-template-rows 用来显式定义网格,分为行轨道和列轨道

grid-template-rows 定义行尺寸,即轨道尺寸,轨道尺寸可以是任何非负的长度值(px、%、em 等)

html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>网格布局</title>
<style>
.container{
display: grid;
grid-template-rows: 50px 100px;
}

.item {
display: flex;
align-items: center;
justify-content: center;
border: 1px solid #fff;
border-radius: .2rem;
font-size: .8em;
min-height: 3rem;
padding: .75rem;
color: #f0f0f3;
background-color: #e91e63;
}

body {
font-family: -apple-system,BlinkMacSystemFont,.SFNSDisplay-Regular,Roboto,Helvetica,Arial,sans-serif;
}
</style>
</head>
<body>
<div class="container">
<!-- 网格项目1的轨道是50px -->
<div class="item">1</div>
<!-- 网格项目2的轨道是100px -->
<div class="item">2</div>
<!-- 网格项目3和4的轨道取决于本身的高度 -->
<div class="item">3</div>
<div class="item">4</div>
</div>
</body>
</html>
轨道尺寸
轨道尺寸
轨道尺寸

grid-template-columns 用于定义列的尺寸,例如 grid-template-columns: 1fr 1fr 2fr; fr 表示按比列划分空间,前两列宽度相同,是最后一列宽度的一半,fr 可以和其它单位混用,混用时,fr 的计算基于其它单位分配后的剩余空间

css
1
2
3
4
.grid {
display: grid;
grid-template-columns: 3rem 25% 1fr 2fr;

fr和其它尺寸混用
fr和其它尺寸混用
fr和其它尺寸混用

轨道最小最大尺寸设置

函数 minmax() 用来定义轨道最小/最大边界值,minmax 接收两个参数,第一个参数表示最小轨道尺寸,第二个参数表示最大轨道尺寸,长度值可以是 auto,表示轨道尺寸可以根据内容大小进行伸长或收缩

css
1
2
3
4
5
6
7
.grid {
display: grid;
/* 轨道最小100px,即最小100px */
grid-template-rows: minmax(100px, auto);
/* 第一列轨道最大50%,不能超过整个容器的50% */
grid-template-columns: minmax(auto, 50%) 1fr 3em;
}
轨道最小最大尺寸设置
轨道最小最大尺寸设置
轨道最小最大尺寸设置

重复的网格轨道

使用函数 repeat() 用来定义重复的网格轨道,特别是有多个相同轨道的项目,函数 repeat 接收两个参数:第一个参数表示重复的次数,第二个参数表示轨道尺寸

css
1
2
3
4
5
.grid {
display: grid;
grid-template-rows: repeat(4, 100px);
grid-template-columns: repeat(3, 1fr);
}
repeat函数
repeat函数
repeat函数
css
1
grid-template-columns: 30px repeat(3, 1fr) 30px;
repeat函数
repeat函数
repeat函数

定义网格间隙

属性 grid-column-gapgrid-row-gap 定义网格间隙,网格间隙只创建在行列之间,项目和边界之间无间隙,间隙尺寸可以是任何非负的长度值

css
1
2
3
4
5
.grid {
display: grid;
grid-row-gap: 20px;
grid-column-gap: 5rem;
}
网格间隙
网格间隙
网格间隙

属性 grid-gapgrid-row-gapgrid-column-gap 的简写形式,第一个值表示行间隙,第二个值表示列间隙,如果只给定一个值,即表示行间隙也表示列间隙

css
1
2
3
4
.grid {
display: grid;
grid-gap: 100px 1em;
}
网格间隙
网格间隙
网格间隙
css
1
2
3
4
.grid {
display: grid;
grid-gap: 2rem;
}
网格间隙
网格间隙
网格间隙

网格线命名

当利用属性 grid-template-rowsgrid-template-columns 定义网格的时候,可以同时定义网格线的名称,网格线名称可以用来定位网格项目

为避免混淆,网格线名称应避免使用规范中的关键字(span 等)

定义网格线名称的方法是要将其放在中括号内([name-of-line]),并和网格轨道相对应

css
1
2
3
4
5
.grid {
display: grid;
grid-template-rows: [row-1-start] 1fr [row-2-start] 1fr [row-2-end];
grid-template-columns: [col-1-start] 1fr [col-2-start] 1fr [col-3-start] 1fr [col-3-end];
}
网格线命名
网格线命名
网格线命名

可以给同一网格线定义多个名称,方法就是在中括号内用空格将多个名称分开,每个网格线名都可以被引用,以用来定位网格项目

css
1
2
3
4
5
.grid{
display: grid;
grid-template-rows: [row-start row-1-start] 1fr [row-1-end row-2-start] 1fr [row-2-end row-end];
grid-template-columns: [col-start] 1fr [col-2-start] 1fr [col-3-start] 1fr [col-end];
}
网格线给定多个名称
网格线给定多个名称
网格线给定多个名称

函数 repeat() 可以定义同名网格线,多个网格线拥有同样的名字,同名的网格线会被分配一个位置编号,作为其唯一标识

css
1
2
3
4
5
.grid{
display: grid;
grid-template-rows: repeat(3, [row-start] 1fr [row-end]);
grid-template-columns: repeat(3, [col-start] 1fr [col-end]);
}
重复同名网格线
重复同名网格线
重复同名网格线

用网格区域命名

一组区域名称要放在单引号或双引号内,每一个名称之间以空格分割,每一组名称定义一行,每一个名称定义一列

css
1
2
3
4
5
6
7
8
.grid{
display: grid;
grid-template-areas: "header header"
"content sidebar"
"footer footer";
grid-template-rows: 150px 1fr 100px;
grid-template-columns: 1fr 200px;
}
网格区域命名
网格区域命名
网格区域命名

网格项目上的一些属性

用网格线编号定位项目

网格线本质上是用来表示网格轨道的开始和结束,每条网格线编号都以1开始,以1为步长向前编号,其中包括行列两组网格线

css
1
2
3
4
5
6
.item1{
grid-row-start: 2;
grid-row-end: 3;
grid-column-start: 2
grid-column-end: 3;
}
网格项目定位
网格项目定位
网格项目定位

属性 grid-rowgrid-row-startgrid-row-end 的简写形式

属性 grid-columngrid-column-startgrid-column-end 的简写形式

如果只指定一个值,它表示 grid-row-startgrid-column-start

如果两个值都指定,第一个表示 grid-row-startgrid-column-start 第二个值表示 grid-row-endgrid-column-end,而且它们之间必须使用 / 隔开

css
1
2
3
4
.item1{
grid-row: 2;
grid-column: 3 / 4;
}
网格项目定位
网格项目定位
网格项目定位

属性 grid-areagrid-column-startgrid-column-endgrid-row-startgrid-row-end 的简写形式

如果四个值都指定,第一个表示 grid-row-start,第二个表示 grid-column-start,第三个表示 grid-row-end,第四个表示 grid-column-end,同样的它们之间需要使用 / 进行分割

css
1
2
3
.item1{
grid-area: 2 / 2 / 3 / 3;
}
网格项目定位
网格项目定位
网格项目定位

网格项目跨越行列

网格项目默认都占用一行和一列,但可以使用定位项目的属性来指定项目跨越多行多列

css
1
2
3
4
.item1{
grid-column-start: 1;
grid-column-end: 4;
}
网格项目跨列
网格项目跨列
网格项目跨列
css
1
2
3
4
.item1{
grid-row-start: 1;
grid-row-end: 4;
}
网格项目跨行
网格项目跨行
网格项目跨行
css
1
2
3
4
.item1{
grid-row: 2 / 5;
grid-column: 2 / 4;
}
网格项目跨行跨列
网格项目跨行跨列
网格项目跨行跨列

关键字span可以指定跨越行和列的数量

css
1
2
3
4
.item1{
grid-row: 2 / span 3;
grid-column: span 2;
}
span指定跨越行和列的数量
span指定跨越行和列的数量
span指定跨越行和列的数量

用网格线名称定义项目

利用命名的网格线来进行网格项目定位,注意:引用网格线名称不用加中括号

css
1
2
3
4
5
6
.item1{
grid-row-start: row-2-start;
grid-row-end: row-end;
grid-column-start: col-2-start;
grid-column-end: col-end;
}
网格名称进行项目定位
网格名称进行项目定位
网格名称进行项目定位
css
1
2
3
4
.item1{
grid-row: row-start 2 / row-end 3;
grid-column: col-start / col-start 3;
}

用同名网格线来定位项目时,应注意在网格线名称和编号之间有一个空格

同名网格线定位项目
同名网格线定位项目
同名网格线定位项目

使用网格区域定位项目

网格区域名称可以用在属性 grid-row-startgrid-row-endgrid-column-startgrid-column-end 的值中,用来定位项目

css
1
2
3
4
5
6
header{
grid-row-start: header;
grid-row-end: header;
grid-column-start: header;
grid-column-end: header;
}
网格区域名称定位项目
网格区域名称定位项目
网格区域名称定位项目
css
1
2
3
4
footer{
grid-row: footer;
grid-column: footer;
}
网格区域名称定位项目
网格区域名称定位项目
网格区域名称定位项目

网格区域名称也可以用于简写属性 grid-area 的值中

css
1
2
3
aside{
grid-area: sidebar;
}
网格区域名称简写
网格区域名称简写
网格区域名称简写

隐式网络

隐式网络用来在显式网格之外定位项目,有时在显示网格中没有足够的空间,或者要在显式网格之外定位项目就要用到隐式网格,这时可以把这些项目放置在隐式网格中

隐式网格可以通过属性 grid-auto-rowsgrid-auto-columnsgrid-auto-flow 来定义

css
1
2
3
4
5
6
.grid{
display: grid;
grid-template-rows: 70px;
grid-template-columns: repeat(2, 1fr);
grid-auto-rows: 140px;
}

上面 css 只定义了一个行轨道,项目 1270px,第二行轨道由隐式网格自动创建并为项目 34 分配了空间,属性 grid-auto-rows 定义了隐式网格的行轨道尺寸,即项目 34 的高度是 140px

网格区域名称简写
网格区域名称简写
网格区域名称简写

缺省的网络布局方向是行的方向(row)

css
1
2
3
4
.grid{
display: grid;
grid-auto-flow: row;
}
隐形网格
隐形网格
隐形网格

缺省的网格布局方向是定义为列的方向(column)

隐形网格
隐形网格
隐形网格
css
1
2
3
4
5
6
.grid{
display: grid;
grid-template-columns: 30px 60px;
grid-auto-flow: column;
grid-auto-columns: 1fr;
}

上例中只定义了两个列轨道尺寸 30px60px

隐式网格中自动创建了其他列并给项目 345 分配空间,分配的尺寸通过 grid-auto-columns 定义

隐形网格
隐形网格
隐形网格

隐式命名的网格区域

网格线名称可以任意指定,但分配以 -start-end 结尾的名字有额外的好处,这样隐式创建了具名网格区域,该名称可以用于项目定位

css
1
2
3
4
5
.grid{
display: grid;
grid-template-rows: [outer-start] 1fr [inner-start] 1fr [inner-end] 1fr [outer-end];
grid-temlate-columns: [outer-start] 1fr [inner-start] 1fr [inner-end] 1fr [outer-end];
}

上例中,行和列都有名为 inner-startinner-end 的网格线,它们隐式地给网格区域分配了名称(inner)

css
1
2
3
item1{
grid-area: inner;
}
隐式命名的网格区域
隐式命名的网格区域
隐式命名的网格区域

隐式命名的网格线

隐式命名网格线和隐式命名的网格区域的工作原理恰好相反

css
1
2
3
4
5
6
7
8
.grid{
display: grid;
grid-template-areas: "header header"
"content sidebar"
"footer footer";
grid-template-rows: 80px 1fr 40px;
grid-template-columns: 1fr 200px;
}

定义网格区域时隐式命名了网格线的名称,这些网格线的名称是基于区域名加上 -start-end 后缀组成的

隐式命名的网格线
隐式命名的网格线
隐式命名的网格线
css
1
2
3
4
5
6
item1{
grid-row-start: header-start;
grid-row-end: content-start;
grid-columns-start: footer-start;
grid-columns-end: sidebar-end;
}
隐式命名的网格线
隐式命名的网格线
隐式命名的网格线

层叠网格项目

通过项目定位可以使多个项目层叠在一起,属性 z-index 可以改变层叠项目的层次

css
1
2
3
4
5
6
7
8
9
10
11
12
13
14
.item1,
.item2{
grid-row-start: 1;
grid-column-end: span 2;
}

.item1{
grid-column-start: 1;
z-index: 1;
}

.item2{
grid-column-start: 2;
}

上例中,项目 12行定位于第一条网格线,并跨越两列,两个项目都是用网格线编号进行定位,项目 1 起始于第一条列网格线,项目 2 起始于第二条网格线,这使得两个项目在第一行中间列发生了层叠

缺省情况下,项目 2 将层叠于项目 1 之上,然而,给项目 1 设置属性 z-index: 1 就使得项目 1 层叠于项目 2 之上

层叠网格项目
层叠网格项目
层叠网格项目
css
1
2
3
4
5
6
7
.overlay{
grid-row-start: header-start;
grid-row-end: content-end;
grid-column-start: content-start;
grid-column-end: sidebar-start;
z-index: 1;
}

利用 grid-template-areas 定义中的隐式网格线名称,定位了一个网格项目 overlay 并将层叠于上层

层叠网格项目
层叠网格项目
层叠网格项目

网格项目的对齐方式

网格项目可以按行或列的轴线方向实现多种对齐方式

属性 justify-itemsjustify-self 以行轴为参照对齐项目,属性 align-itemsalign-self 以列轴为参照对齐项目

属性 justify-itemsalign-items 是网格容器的属性,支持如下值

  • auto
  • normal
  • start
  • end
  • center
  • stretch
  • baseline
  • first baseline
  • last baseline
css
1
2
3
4
5
6
7
8
9
10
11
12
13
14
.grid{
grid-template-rows: 80px 80px;
grid-template-columns: 1fr 1fr;
grid-template-areas: "content content"
"content content";
}

.item{
grid-area: content;
}

.grid{
justify-items: start;
}

在行的轴线起点处对齐

行的轴线起点处对齐
行的轴线起点处对齐
行的轴线起点处对齐
css
1
2
3
.grid{
justify-items: center;
}

在行的轴线中心处对齐

行的轴线中心对齐
行的轴线中心对齐
行的轴线中心对齐
css
1
2
3
.grid{
justify-items: stretch;
}

在行的轴线方向延伸并填满整个区域,stretch 是缺省值

铺满整个区域
铺满整个区域
铺满整个区域
css
1
2
3
.grid{
align-items: start;
}

在列的轴线起点处对齐

列轴线起点对齐
列轴线起点对齐
列轴线起点对齐
css
1
2
3
.grid{
align-items: center;
}
列轴线中心对齐
列轴线中心对齐
列轴线中心对齐
css
1
2
3
.grid{
align-items: end;
}

在列的轴线终点处对齐

列轴线终点处对齐
列轴线终点处对齐
列轴线终点处对齐
css
1
2
3
.grid{
align-items: stretch;
}

在列的轴线方向延伸并填满整个区域

列轴线方向铺满
列轴线方向铺满
列轴线方向铺满
css
1
2
3
4
.grid{
justify-items: center;
align-items: center;
}

项目定位于行轴和列轴线的中间位置

行列轴线中间
行列轴线中间
行列轴线中间

网格项目可以使用属性 align-selfjustify-self 定义自己的对齐方式,并支持如下属性值

  • auto
  • normal
  • start
  • end
  • center
  • stretch
  • baseline
  • first baseline
  • last baseline
css
1
2
3
4
5
6
7
8
9
10
11
.item1{
justify-self: start;
}

.item2{
justify-self: center;
}

.item3{
justify-self: end;
}

属性 justify-self 在行的轴线方向定义对齐方式

行轴线对齐方式
行轴线对齐方式
行轴线对齐方式
css
1
2
3
4
5
6
7
8
9
10
11
.item1{
align-self: start;
}

.item2{
align-self: center;
}

.item3{
align-self: end;
}

属性 align-self 在列的轴线方向定义对齐方式

列轴线对齐方式
列轴线对齐方式
列轴线对齐方式
css
1
2
3
4
.item1{
justify-self: center;
align-self: center;
}

定位于行轴线和列轴线的中间位置

行轴线和列轴线的中间位置
行轴线和列轴线的中间位置
行轴线和列轴线的中间位置

网格轨道的对齐方式

在网格容器中,网格轨道沿轴线方向有多种对齐方式

属性 align-content 用于定义列的网格轨道沿着行轴线对齐的方式,而属性 justify-content 用于定义行的网格轨道沿着列的轴线的对齐方式,并分别支持如下属性

  • normal
  • start
  • end
  • center
  • stretch
  • space-around
  • space-between
  • space-evenly
  • baseline
  • first baseline
  • last baseline
css
1
2
3
4
5
6
7
8
.grid{
width: 100%;
height: 300px;
grid-template-columns: repeat(4, 45px);
grid-template-rows: repeat(4, 45px);
grid-gap: 0.5rem;
justify-content: start;
}

列的轨道在行的轴线起点处对齐,start 是缺省值

列网格轨道的对齐方式
列网格轨道的对齐方式
列网格轨道的对齐方式
css
1
2
3
.grid{
justify-content: end;
}

列的轨道在行的轴线终点处对齐

列网格轨道的对齐方式
列网格轨道的对齐方式
列网格轨道的对齐方式
css
1
2
3
.grid{
justify-content: center;
}

列的轨道在行的轴线中间对齐

列网格轨道的对齐方式
列网格轨道的对齐方式
列网格轨道的对齐方式
css
1
2
3
.grid{
justify-content: space-around;
}

在每一列的两侧平均分配额外空间

列网格轨道的对齐方式
列网格轨道的对齐方式
列网格轨道的对齐方式
css
1
2
3
.grid{
justify-content: space-between;
}

在列与列之间平均分配额外的空间

列网格轨道的对齐方式
列网格轨道的对齐方式
列网格轨道的对齐方式
css
1
2
3
.grid{
justify-content: space-evenly;
}

在列与列之间及列与边界之间平均分配额外的空间

列网格轨道的对齐方式
列网格轨道的对齐方式
列网格轨道的对齐方式
css
1
2
3
.grid{
align-content: start;
}

行的轨道在列的轴线起点处对齐,属性 start 是缺省值

行网格轨道的对齐方式
行网格轨道的对齐方式
行网格轨道的对齐方式
css
1
2
3
.grid{
align-content: end;
}

行的轨道在列的轴线终点处对齐

行网格轨道的对齐方式
行网格轨道的对齐方式
行网格轨道的对齐方式
css
1
2
3
.grid{
align-content: center;
}

行的轨道在列的轴线中点处对齐

行网格轨道的对齐方式
行网格轨道的对齐方式
行网格轨道的对齐方式
css
1
2
3
.grid{
align-content: space-around;
}

每一行的两侧平均分配额外空间

行网格轨道的对齐方式
行网格轨道的对齐方式
行网格轨道的对齐方式
css
1
2
3
.grid{
align-content: space-between;
}

在行与行之间平均分配额外空间

行网格轨道的对齐方式
行网格轨道的对齐方式
行网格轨道的对齐方式
css
1
2
3
.grid{
align-content: space-evenly;
}

在行与行之间及行与边界之间平均分配额外空间

行网格轨道的对齐方式
行网格轨道的对齐方式
行网格轨道的对齐方式