10-网格布局

image-20251125100829463

1. 概念

Grid 网格

含义:将网页划分成一个个网格,可以任意组合不同的风格,作出各种各样的布局

相同:Grid布局 与 Flex 布局都可以指定容器内部多个项目的位置。

不同:

  • Flex 布局是轴线布局,只能指定项目针对轴线的位置,可以看作是一维布局。
  • Grid 布局则是将容器划分成行和列,产生单元格,然后指定项目所在的单元格,可以看作是二维布局。

1.1 容器和项目

  • 容器:一个案例中最大的盒子,可以理解为父元素

  • 项目:一个案例中最大盒子里面的内容,可以理解为子元素

示例:

1
2
3
4
5
6
7
8
9
10
11
12
<!-- section为容器、div为项目(项目不包含p标签) -->
<section>
<div>
<p></p>
</div>
<div>
<p></p>
</div>
<div>
<p></p>
</div>
</section>

1.2 行和列

  • :容器里面水平区域

  • :容器里面垂直区域

image-20251204113315308

1.3 单元格

  • 单元格:行和列的交叉区域,成为单元格。

image-20251204113418142

1.4 网格线

  • 网格线:划分网格的线。水平网格线划分行,垂直网格线划分列。

image-20251204113446782

2. 容器属性

2.1 display: grid 网格布局

display: grid; 给父元素添加即可触发网格布局。

display关于网格的取值分2个:

  • grid,块网格,容器从上向下排列
  • inline-grid,行内网格(行内块),容器从左向右排列

2.2 grid-template-☆ 行列划分

grid-template-row 规定行属性

grid-template-column 固定列属性

后面的取值数量代表的是多少行,多少列。

示例:父div元素宽高均为 600px

  1. 绝对大小(根据列数或行数确定值的个数),如 200px 200px 200px
1
2
grid-template-columns: 200px 200px 200px;
grid-template-rows: 200px 200px 200px;

image-20251204120711700

  1. 百分比(根据列数或行数确定值的个数),如 33.33% 33.33% 33.33%
1
2
grid-template-columns: 33.33% 33.33% 33.33%;
grid-template-rows: 33.33% 33.33% 33.33%;

image-20251204120327914

  1. 功能函数:repeat()
1
2
3
4
5
6
7
8
9
repeat(参数1, 参数2)
/*
参数1:重复的次数
参数2:重复的数值或者重复的模式
*/
eg:
grid-template-columns: repeat(3, 33.33%);
等同于
grid-template-columns: 33.33% 33.33% 33.33%;

image-20251204120746591

  1. auto-fill 关键字(自动填充),配合功能函数使用
1
2
/* 当项目宽高固定,容器不固定的情况下,自动填充网格列数 */
grid-template-columns: repeat(auto-fill, 33.33%);

image-20251204120616445

  1. fr关键字(列宽片段)
1
2
3
4
/* 为了方便表示比例关系,网格布局提供了fr关键字(fraction的缩写,片段) */
/* 如果两列的宽度分别为 1fr 和 2fr 就表示后者是前者的2倍 */
grid-template-columns: 1fr 2fr 1fr;
grid-template-rows: 1fr 2fr 1fr;

image-20251204120912603

  1. minmax(x, y) 最小最大 - 用得少
1
2
grid-template-columns: minmax(100px, 200px) 200px 100px; /* 没超父宽,取max */
grid-template-rows: minmax(100px, 200px) 200px 400px; /* 超了父宽,取min */

image-20251204121409482

2.3 gap 行列间距(复合属性★)

gap 行列间距,复合写法(等同于 grid-gap)

row-gap 行间距

column-gap 列间距

1
2
3
grid-row-gap: 20px;     /* 行间距 */
grid-column-gap: 20px; /* 列间距 */
grid-gap: 30px 30px; /* 复合写法 */

说明:新版本已省略 grid- 前缀。

示例:

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.box{
width: 600px;
height: 600px;
border: 5px solid gray;
display: grid;
grid-template-rows: 1fr 2fr 1fr;
grid-template-columns: 1fr 2fr 1fr;

/* gap: 行px 列px; */
gap: 10px 30px;
}

.box div{
border: 1px dashed red;
}
</style>
</head>
<body>
<div class="box">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
<div>9</div>
</div>
</body>
</html>

image-20251204122528212

2.4 grid-template-area 指定区域

grid-template-area 指定容器内的项目区域名称。

grid-area: 名称; 将项目区域名称进行合并(注意:名称不需要引号!)。

1
2
3
4
5
6
7
display: grid;
grid-template-columns: repeat(3, 100px);
grid-template-rows: repeat(3, 100px);
/* 整个网格划分9个区域,每个区域对应单元格设置名称 */
grid-template-areas: 'a b c'
'd e f'
'g h i';

合并的时候使用 grid-area: 网格名字; 进行合并,例如:

1
2
3
4
5
grid-template-areas: 'a a a'
'. . b'
'. c c';
/* 合并a单元格 */
grid-area: a;

示例:

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
42
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.box {
width: 600px;
height: 600px;
border: 5px solid gray;
display: grid;
grid-template-rows: 1fr 2fr 1fr;
grid-template-columns: 1fr 2fr 1fr;

/* 整个网格划分9个区域,每个区域对应单元格设置名称 */
grid-template-areas: 'a a a'
'. . b'
'. c c';
}

.box div:nth-child(1) {
/* 合并名字叫a的单元格,a 不需要加引号 */
grid-area: a;
}
</style>
</head>

<body>
<div class="box">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
</div>
</body>

</html>

效果:

image-20251204124028917

案例:自定义网格布局

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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.box {
width: 600px;
height: 300px;
border: 5px solid gray;
display: grid;
grid-template-rows: repeat(3, auto-fill);
grid-template-columns: repeat(6, auto-fill);

grid-template-areas: 'a a a a b b'
'a a a a c c'
'd d e f c c';
gap: 10px 10px;
}
.box div:nth-child(1){
background: red;
grid-area: a;
}
.box div:nth-child(2){
background: orange;
grid-area: b;
}
.box div:nth-child(3){
background: yellow;
grid-area: c;
}
.box div:nth-child(4){
background: green;
grid-area: d;
}
.box div:nth-child(5){
background: cyan;
}
.box div:nth-child(6){
background: purple;
}
</style>
</head>

<body>
<div class="box">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
</div>
</body>

</html>

效果:

image-20251204124823045

2.5 grid-auto-flow 对齐

grid-auto-flow 指定项目排列的顺序。

  • row,自动按行排列
  • column,自动按列排列
1
2
grid-auto-flow: column | row;
/* row dense 和 column dense 这两个值主要用于某些项目指定位置以后,剩下的项目怎么自动放置 */

示例:

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.box{
width: 500px;
height: 600px;
margin: 0 auto;
border: 1px solid gray;

display: grid;
grid-auto-flow: row;
}
</style>
</head>
<body>
<div class="box">
<div>1 Lorem ipsum dolor, sit amet consectetur adipisicing elit. Cum vero sequi fuga, esse illum enim eveniet obcaecati soluta itaque commodi blanditiis illo fugit autem pariatur eos ratione veritatis labore vel.</div>
<div>2 Lorem ipsum dolor sit amet consectetur adipisicing elit. Dicta quasi laudantium sequi, explicabo, assumenda deserunt doloribus magnam nostrum, obcaecati eligendi itaque adipisci fuga. Deleniti culpa in maxime perspiciatis odit dignissimos!</div>
<div>3 Lorem ipsum dolor sit amet consectetur adipisicing elit. Adipisci fugit voluptates accusamus quam provident minus. Sunt optio assumenda, amet pariatur quaerat quam! Quibusdam impedit itaque laboriosam saepe corporis nulla nisi.</div>
<div>4</div>
<div>5</div>
<div>6</div>
</div>
</body>
</html>

效果:row

image-20251205191606077

效果:column

image-20251205191703572

2.6 单元格项目对齐

单元格项目对齐 复合属性(★),项目相对于容器(即子元素相对于父元素)。

1
2
3
justify-content: start | end | center | stretch | space-around | space-between | space-evenly;
align-content: start | end | center | stretch | space-around | space-between | space-evenly;
place-content: <justify-content> <align-content>; /* 复合写法(★) */

说明:

  • start,对齐容器的起始边框
  • end,对齐容器的结束边框
  • center,容器内部居中
  • stretch,项目大小没有指定时,拉伸占据整个网格容器
  • space-around,每个项目两个间隔相当。所以,项目之间的间隔比项目与容器边框的间隔大一倍。
  • space-between,项目与项目的间隔相等,项目与容器边框之间没有间隔(两侧贴边)。
  • space-evenly,项目与项目的间隔相等,项目与容器边框之间越是同样长度的间隔。

2.7 单元格内容对齐

单元格内容对齐 复合属性(★),内容相对于项目(即内容相对于单元格)。

1
2
3
justify-items: start | end | center | stretch;
align-items: start | end | center | stretch;
place-items: <justify-items> <align-items>; /* 复合写法(★) */

说明:

  • start,对齐单元格的起始边缘
  • end,对齐单元格的结束边缘
  • center,单元格内部居中
  • stretch,拉伸,占满单元格的整个宽度(默认值)

示例:

  1. 项目相对于容器:水平垂直居中
  2. 内容相对于项目:水平垂直居中
  3. 显示元素相对于内容:水平垂直居中
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
42
43
44
45
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.box {
width: 600px;
height: 600px;
border: 5px solid gray;
display: grid;
grid-template-rows: repeat(3, 100px);
grid-template-columns: repeat(3, 100px);

/* 项目相对于容器:水平垂直居中 */
place-content: center center;
/* 内容相对于项目:水平垂直居中 */
place-items: center center;
}
.box div{
width: 50px;
height: 50px;
border: 1px solid red;

/* 显示元素相对于内容:水平垂直居中 */
line-height: 50px;
text-align: center;
}
</style>
</head>
<body>
<div class="box">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
<div>9</div>
</div>
</body>
</html>

效果:

image-20251204130937016

3. 项目属性

3.1 网格线合并(单一属性)

grid-column: x/y; 将列网格线x到y之间的单元格进行合并。

grid-row: x/y; 将行网格线x到y之间的单元格进行合并。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
grid-column-start   /* 左边框所在的垂直网格线 */
grid-column-end /* 右边框所在的垂直网格线 */
grid-row-start /* 上边框所在的水平网格线 */
grid-row-end /* 下边框所在的水平网格线 */

eg:
grid-column-start: 1;
grid-column-end: 2;
grid-row-start: 3;
grid-row-end: 4;

/* 简写【推荐】*/
grid-column: 1/2; /* 网格线1-2之间 */
grid-row: 3/4; /* 网格线3-4之间 */

示例:

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
42
43
44
45
46
47
48
49
50
51
52
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.box {
width: 300px;
height: 300px;
background: gray;
display: grid;
grid-template-rows: repeat(3, 100px);
grid-template-columns: repeat(3, 100px);
}
.box div:nth-child(1){
/* 网格线从哪个开始和结束 */
/* grid-column-start: 1;
grid-column-end: 3; */
background: red;
}
.box div:nth-child(2){
/* 列从网格线2到4,行从网格线1到3 */
/* grid-column-start: 2;
grid-column-end: 4;
grid-row-start: 1;
grid-row-end: 3; */

/* 简写【推荐】 */
grid-column: 2/4;
grid-row: 1/3;
background: green;
}
</style>
</head>

<body>
<div class="box">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
<div>9</div>
</div>
</body>

</html>

效果:

image-20251204161646275

案例:自定义网格布局改造

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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.box {
width: 600px;
height: 300px;
border: 5px solid gray;
display: grid;
grid-template-rows: repeat(3, auto-fill);
grid-template-columns: repeat(6, auto-fill);

grid-template-areas: 'a a a a b b'
'a a a a c c'
'd d e f c c';
gap: 10px 10px;
}
.box div:nth-child(1){
background: red;
/* 合并网格线 */
grid-column: 1/5;
grid-row: 1/3;
}
.box div:nth-child(2){
background: orange;
/* 合并网格线 */
grid-column: 5/7;
}
.box div:nth-child(3){
background: yellow;
/* 合并网格线 */
grid-column: 5/7;
grid-row: 2/4;
}
.box div:nth-child(4){
background: green;
/* 合并网格线 */
grid-column: 1/3;
}
.box div:nth-child(5){
background: cyan;
}
.box div:nth-child(6){
background: purple;
}
</style>
</head>

<body>
<div class="box">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
</div>
</body>

</html>

效果:

image-20251204124823045


10-网格布局
https://janycode.github.io/2017/04/28/04_大前端/02_CSS/10-网格布局/
作者
Jerry(姜源)
发布于
2017年4月28日
许可协议