什么是网格布局

网格布局能够将网页划分成一个个网格,亦可以组合任意不同的网格。

grid布局是二维布局,而flex布局则是一维布局。grid将容器划分为,产生单元格,通过指定项目所在的单元格。

定义网格布局

定义网格布局很简答,通过display即可设置。

不过与flex布局不同的是,单纯的设置后是无效果的,需要同样为其设置网格布局属性才可以看到效果

容器内部设置为网格布局,容器为块级元素

img

1
2
3
div{
display: grid;
}

容器内部设置为网格布局,容器为行内元素

img

1
2
3
div{
display: inline-grid;
}

网格布局属性

列宽和行高

定义列宽grid-template-columns和行高grid-template-rows用于规定单元格的大小。(类似于widthheight

1
2
3
4
5
6
7
8
.container {
/* 定义网格布局 */
display: grid;
/* 定义三列网格,宽度为200px */
grid-template-columns: 200px 200px 200px;
/* 定义三行网格,高度为60px */
grid-template-rows: 60px 60px 60px;
}

20221015215451000025

  • 传统的十二网格布局:grid-template-columns: repeat(12, 1fr);
  • 两栏布局:grid-template-columns: 70% 30%;

上面定义“高” “宽”时使用的是绝对单位 px ,但是定义模板时可以使用的单位不仅仅是px。以下单位也可以。

repeat函数用于重复值或模式,其接受两个参数:

  • 重复的次数
  • 重复的值(模式也可以)
1
2
3
4
5
.container {
display: grid;
grid-template-columns: repeat(3, 33.33%);
grid-template-rows: repeat(3, 33.33%);
}

定义六列,第一列和第四列的宽度为40px,第二列和第五列为60px,第三列和第六列为80px

1
2
3
4
.container{
/* 以下定义相当于 grid-template-columns: 40px 60px 80px 40px 60px 80px; */
grid-template-columns: repeat(2, 40px 60px 80px);
}

当单元格大小固定,但容器大小不确定时,希望每一行或每一列都尽可能的容纳多个单元格,此时则可以使用关键字auto-fill关键词。

1
2
3
4
5
6
7
8
.container {
/* 定义网格布局 */
display: grid;
/* 定义三列网格,自动填充宽度200px */
grid-template-columns: repeat(auto-fill, 200px);
/* 定义三行网格,自动填充高度为60px */
grid-template-rows: repeat(auto-fill, 60px);
}

20221015221108000026

fr关键字用于表示比例关系,例如grid-template-columns: 1fr 2fr;则表示前者为宽度为1个单位,则后者为前者的两倍:2个单位。

fr单位也可以与绝对单位相配合:grid-template-columns: 150px 1fr 2fr;,此时则表示:第一列为200px,剩余宽度分配成1:2的比例并分配给第二列和第三列。

1
2
3
4
5
6
7
8
.container {
/* 定义网格布局 */
display: grid;
/* 定义三列网格,第一列为200px,剩余宽度分配成1:2的比例并分配给第二列和第三列 */
grid-template-columns: 200px 1fr 2fr;
/* 定义三行网格,高度为60px */
grid-template-rows: repeat(auto-fill, 60px);
}

该函数用于产生一个长度范围,其接受两个参数:

  • 最小值
  • 最大值

grid-template-columns: 1fr 1fr minmax(100px, 1fr);表示第三列宽度最小为100像素,最大为1个单位

auto关键字表示由浏览器分配剩余可用长度。例如:grid-template-columns: 100px auto 100px;表示第一列与第三列宽度为100像素,第二列则占用全部剩余宽度。

间距

row-gap属性设置行与行的间隔(行间距),column-gap属性设置列与列的间隔(列间距)。

1
2
3
4
5
6
7
.container {
display: grid;
grid-template-columns: 200px 200px 200px;
grid-template-rows: repeat(auto-fill, 60px);
row-gap: 20px; /* 20像素行间距 */
column-gap: 30px; /* 30像素列间距 */
}

20221015223753000027

gap属性是column-gaprow-gap的合并简写形式,语法如下

  • gap: <grid-row-gap> <grid-column-gap>;

因此上述样式可调整为:

1
2
3
4
5
6
.container {
display: grid;
grid-template-columns: 200px 200px 200px;
grid-template-rows: repeat(auto-fill, 60px);
gap: 20px 30px; /* 20像素行间距 30像素列间距 */
}

*gap属性曾经有一个grid-前缀,不过后来的标准进行了修改,目的是让他们能够在不同的布局方法中都能起作用。尽管现在这个前缀不会影响语义,但为了代码的健壮性,可以把两个属性都写上。

区域

网格布局允许指定"区域"(area),一个区域由单个或多个单元格组成。

grid-template-areas 属性用于定义区域, grid-area 属性(元素属性)指定项目放在哪一个区域。

20221015225703000028

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
<!DOCTYPE html>
<html lang="en">
<head>
<style>
.grid-item:nth-of-type(1) {
background: red;
grid-area: a;
}
.grid-item:nth-of-type(2) {
background: green;
grid-area: b;
}
.grid-item:nth-of-type(3) {
background: blue;
grid-area: c;
}
.container {
margin: 200px 0 100px 0;
color: #fff;
line-height: 60px;
text-align: center;
font-size: 20px;
display: grid;
grid-template-columns: 200px 200px 200px;
grid-template-rows: repeat(auto-fill, 60px);
grid-template-areas:
'a a a'
'. b b'
'c c c';
}
</style>
</head>
<body>
<div class="container">
<div class="grid-item">1</div>
<div class="grid-item">2</div>
<div class="grid-item">3</div>
<div class="grid-item">4</div>
<div class="grid-item">5</div>
<div class="grid-item">6</div>
<div class="grid-item">7</div>
<div class="grid-item">8</div>
<div class="grid-item">9</div>
</div>
</body>
</html>

点表示这个区域不需要利用。

填充顺序

grid-auto-flow 属性控制着自动布局算法怎样运作,精确指定在网格中被自动布局的元素怎样排列。

默认情况下为:row即先行后列。语法如下:

1
2
3
grid-auto-flow = 
[ row | column ] ||
dense
  • row

    该关键字指定自动布局算法按照通过逐行填充来排列元素,在必要时增加新行。如果既没有指定 row 也没有 column,则默认为 row

  • column

    该关键字指定自动布局算法通过逐列填充来排列元素,在必要时增加新列。

  • dense

    该关键字指定自动布局算法使用一种“稠密”堆积算法,如果后面出现了稍小的元素,则会试图去填充网格中前面留下的空白。这样做会填上稍大元素留下的空白,但同时也可能导致原来出现的次序被打乱。

    如果省略它,使用一种「稀疏」算法,在网格中布局元素时,布局算法只会「向前」移动,永远不会倒回去填补空白。这保证了所有自动布局元素「按照次序」出现,即使可能会留下被后面元素填充的空白。

单元格内容的位置

justify-items属性设置单元格内容的水平位置(左中右)

align-items属性设置单元格内容的垂直位置(上中下)

place-items属性是align-items属性和justify-items属性的合并简写形式。

  • place-items: <align-items> <justify-items>;

justify-itemsalign-items属性的取值和写法完全一样:

1
2
3
4
.container {
justify-items: start | end | center | stretch;
align-items: start | end | center | stretch;
}
  • start:对齐单元格的起始边缘。
  • end:对齐单元格的结束边缘。
  • center:单元格内部居中。
  • stretch:拉伸,占满单元格的整个宽度(默认值)。

例如:justify-items: start;属性表示该单元格内容左对齐。

img

单元格整体的位置

与 单元格内容的位置 类似,只是该属性最用于整个内容区域

justify-content属性是整个内容区域在容器里面的水平位置(左中右)

align-content属性是整个内容区域的垂直位置(上中下)

place-content属性是align-content属性和justify-content属性的合并简写形式

1
2
3
4
.container {
justify-content: start | end | center | stretch | space-around | space-between | space-evenly;
align-content: start | end | center | stretch | space-around | space-between | space-evenly;
}

对齐容器的起始边框

img

对齐容器的结束边框。

img

容器内部居中。

img

项目大小没有指定时,拉伸占据整个网格容器。

img

每个项目两侧的间隔相等。所以,项目之间的间隔比项目与容器边框的间隔大一倍。

img

项目与项目的间隔相等,项目与容器边框之间没有间隔。

img

项目与项目的间隔相等,项目与容器边框之间也是同样长度的间隔。

img

多余单元格的大小

当某些项目的位置在单元格之外,则可通过grid-auto-columns属性和grid-auto-rows属性用来设置。其写法与grid-template-columnsgrid-template-rows完全相同。

如果不指定这两个属性,浏览器完全根据单元格内容的大小,决定新增网格的列宽和行高。

项目属性

项目的位置

  • grid-column-start属性:左边框所在的垂直网格线
  • grid-column-end属性:右边框所在的垂直网格线
  • grid-row-start属性:上边框所在的水平网格线
  • grid-row-end属性:下边框所在的水平网格线

grid-column属性是grid-column-startgrid-column-end的合并简写形式,grid-row属性是grid-row-start属性和grid-row-end的合并简写形式。

1
2
3
4
.item {
grid-column: <start-line> / <end-line>;
grid-row: <start-line> / <end-line>;
}

示例:

1
2
3
4
5
.grid-item:nth-of-type(1) {
background: red;
grid-column-start: 2; /* 指定元素开始在第二条网格线 */
grid-column-end: 4; /* 指定元素结束于第四条网格线 */
}

20221015235236000029

1
2
3
4
5
6
7
.grid-item:nth-of-type(1) {
background: red;
grid-column-start: 1;
grid-column-end: 3;
grid-row-start: 2;
grid-row-end: 4;
}

20221015235431000030

该属性也可使用span关键字,表示跨越。例如grid-column-start: span 2;表示1号项目的左边框距离右边框跨越2个网格。

项目区域

grid-area属性指定项目放在哪一个区域。其属性可以指定区域名,例如上文的区域部分定义区域名称。

1
2
3
.grid-item:nth-of-type(1) {
grid-area: e;
}

grid-area属性还可用作grid-row-startgrid-column-startgrid-row-endgrid-column-end的合并简写形式,直接指定项目的位置。

1
2
3
.item {
grid-area: <row-start> / <column-start> / <row-end> / <column-end>;
}

项目位置

justify-self属性设置单元格内容的水平位置(左中右),跟justify-items属性的用法完全一致,但只作用于单个项目。

align-self属性设置单元格内容的垂直位置(上中下),跟align-items属性的用法完全一致,也是只作用于单个项目。

place-self属性是align-self属性和justify-self属性的合并简写形式。

  • place-self: <align-self> <justify-self>;
1
2
3
4
.item {
justify-self: start | end | center | stretch;
align-self: start | end | center | stretch;
}
  • start:对齐单元格的起始边缘。
  • end:对齐单元格的结束边缘。
  • center:单元格内部居中。
  • stretch:拉伸,占满单元格的整个宽度(默认值)。

文章参考