# Grid 网格布局
号称是最强大的的 CSS
布局方案,是目前唯一一种 CSS
二维布局。
# 基本概念:
# 容器和项目
采用网格布局的区域,称为"容器"(container)。容器内部采用网格定位的子元素,称为"项目"(item)。
<div class='container'>
<div class='item1'><p>1</p></div>
<div class='item2'><p>2</p></div>
<div class='item3'><p>3</p></div>
</div>
2
3
4
5
上面代码中,最外层的<div>
元素就是容器,内层的三个<div>
元素就是项目。
注意:项目只能是容器的顶层子元素,不包含项目的子元素,比如上面代码的
<p>
元素就不是项目。Grid 布局只对项目生效。
# 容器属性汇总
属性值 | 子属性 | 说明 |
---|---|---|
display | 无 | 定义网格容器 |
grid-template-columns | 同下 | 划分列并分配宽度 |
grid-template-rows | 有 | 划分行并分配高度 |
repeat() | 重复定义网格(数量相关) | |
auto-fill 关键字 | 在容器范围内自动填充网格(数量相关) | |
minmax() | 定义网格的最大和最小范围(范围相关) | |
auto 关键字 | 表示由浏览器自己决定范围(范围相关) | |
grid-row-gap | 无 | 行间距 |
grid-column-gap | 无 | 列间距 |
grid-row-gap | 无 | 行间距与列间距语法糖 |
grid-template-areas | 无 | 定义区域 |
grid-auto-flow | 无 | 定义排列顺序 |
justify-items | 无 | 定义项目内的水平对齐方式 |
align-items | 无 | 定义项目内的垂直对齐方式 |
justify-content | 无 | 定义容器内的水平对齐方式 |
align-content | 无 | 定义容器内的垂直对齐方式 |
grid-auto-columns | 无 | 定义超出定义内容的新增列范围 |
grid-auto-rows | 无 | 定义超出定义内容的新增行范围 |
grid-template | 无 | grid-template-columns 、grid-template-rows 和grid-template-areas 的语法糖 |
grid | 无 | grid-template 语法糖 +grid-auto-rows 、grid-auto-columns 、grid-auto-flow 组合法糖 |
# 项目属性汇总
属性值 | 说明 |
---|---|
grid-column-start | 项目所在左框网格线位置 |
grid-column-end | 项目所在右框网格线位置 |
grid-row-start | 项目所在上框网格线位置 |
grid-row-end | 项目所在下框网格线位置 |
gird-column | 项目左右框位置语法糖 |
grid-row | 项目上下框位置语法糖 |
justify-self | 定义项目内的水平对齐方式 |
align-self | 定义项目内的垂直对齐方式 |
place-self | 定义项目内的水平与垂直对齐语法糖 |
# 容器属性
Grid 布局的属性分成两类。一类定义在容器上面,称为容器属性;另一类定义在项目上面,称为项目属性。这部分先介绍容器属性。
# display 属性
display: grid
或 display: inline-grid
指定一个容器采用网格布局。
div {
display: grid;
}
2
3
# 划分行和列 grid-template-columns ,grid-template-rows 属性
grid-template-columns
属性定义每一列的列宽,grid-template-rows
属性定义每一行的行高。
.container {
display: grid;
grid-template-columns: 100px 100px 100px;/*定义了三列,宽度分别为 100px 100px 100px*/
/*同时也可以使用百分比 grid-template-columns: 33.33% 33.33% 33.33%;*/
grid-template-rows: 100px 100px 100px;
}
2
3
4
5
6
# repeat()
有时候,重复写同样的值非常麻烦,尤其网格很多时。这时,可以使用repeat()
函数,简化重复的值。上面的代码用repeat()
改写如下。
.container {
display: grid;
grid-template-columns: repeat(3, 100px);
grid-template-rows: repeat(3, 100px);
}
2
3
4
5
# auto-fill 关键字
有时,单元格的大小是固定的,但是容器的大小不确定。如果希望每一行(或每一列)容纳尽可能多的单元格,这时可以使用auto-fill
关键字表示自动填充。
.container {
display: grid;
grid-template-columns: repeat(auto-fill, 100px);
}
2
3
4
fr 关键字
为了方便表示比例关系,网格布局提供了fr
关键字(fraction 的缩写,意为"片段")。如果两列的宽度分别为1fr
和2fr
,就表示后者是前者的两倍。
可以与绝对长度结合,非常方便。如下表示:第一列的宽度为150像素,第二列的宽度是第三列的一半。
.container {
display: grid;
grid-template-columns: 150px 1fr 2fr;
}
2
3
4
# minmax()
minmax()
函数产生一个长度范围,表示长度就在这个范围之中。它接受两个参数,分别为最小值和最大值。
grid-template-columns: 1fr 1fr minmax(100px, 1fr);
上面代码中,minmax(100px, 1fr)
表示列宽不小于100px
,不大于1fr
。
# auto 关键字
auto
关键字表示由浏览器自己决定长度。
grid-template-columns: 100px auto 100px;
上面代码中,第二列的宽度,基本上等于该列单元格的最大宽度,除非单元格内容设置了min-width
,且这个值大于最大宽度。
# 网格线的名称
grid-template-columns
属性和grid-template-rows
属性里面,还可以使用方括号,指定每一根网格线的名字,方便以后的引用。
.container {
display: grid;
grid-template-columns: [c1] 100px [c2] 100px [c3] auto [c4];
grid-template-rows: [r1] 100px [r2] 100px [r3] auto [r4];
}
2
3
4
5
上面代码指定网格布局为3行 x 3列,因此有4根垂直网格线和4根水平网格线。方括号里面依次是这八根线的名字。
网格布局允许同一根线有多个名字,比如[fifth-line row-5]
。
# 布局实例(两栏布局、12网格等)
grid-template-columns
属性对于网页布局非常有用。两栏式布局只需要一行代码。
.wrapper {
display: grid;
grid-template-columns: 70% 30%;
}
2
3
4
传统的十二网格布局,写起来也很容易。
grid-template-columns: repeat(12, 1fr);
# 行间距和列间距 row-grid,column-grid,gap属性
注意:原本属性为:grid-column-gap,grid-column-gap,grid-gap。虽然现在还能使用,但已被废弃。
row-grid
属性设置行与行的间隔(行间距),column-grid
属性设置列与列的间隔(列间距)。
.container {
row-grid: 20px;
column-grid: 20px;
}
2
3
4
gap
属性是grid-column-gap
和grid-row-gap
的合并简写形式,语法如下。
gap: <row-grid> <column-grid>;
# 定义区域 grid-template-areas 属性
网格布局允许指定"区域"(area),一个区域由单个或多个单元格组成。grid-template-areas
属性用于定义区域。
.container {
display: grid;
grid-template-columns: 100px 100px 100px;
grid-template-rows: 100px 100px 100px;
grid-template-areas: 'a b c'
'd e f'
'g h i';
}
2
3
4
5
6
7
8
上面代码先划分出9个单元格,然后将其定名为a
到i
的九个区域,分别对应这九个单元格。
多个单元格合并成一个区域的写法如下。
grid-template-areas: 'a a a'
'b b b'
'c c c';
2
3
上面代码将9个单元格分成a
、b
、c
三个区域。
# 下面是一个布局实例:实现 Layout 布局。
<!--html-->
<body>
<section id="page">
<header>Header</header>
<nav>Navigation</nav>
<main>Main area</main>
<footer>Footer</footer>
</section>
<body>
<style>
#page {
display: grid; /* 1.设置 display 为 grid */
width: 100%;
height: 250px;
grid-template-areas: "head head"
"nav main"
"nav foot"; /* 2.区域划分 当前为 三行 两列 */
grid-template-rows: 50px 1fr 30px; /* 3.各区域 宽高设置 */
grid-template-columns: 150px 1fr;
}
#page > header {
grid-area: head; /* 4. 指定当前元素所在的区域位置,从 grid-template-areas 选取值 */
background-color: #8ca0ff;
}
#page > nav {
grid-area: nav;
background-color: #ffa08c;
}
#page > main {
grid-area: main;
background-color: #ffff64;
}
#page > footer {
grid-area: foot;
background-color: #8cffa0;
}
</style>
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
上面代码中,顶部是页眉区域header
,底部是页脚区域footer
,中间部分则为main
和sidebar
。
如果某些区域不需要利用,则使用"点"(.
)表示。
grid-template-areas: 'a . c'
'd . f'
'g . i';
2
3
上面代码中,中间一列为点,表示没有用到该单元格,或者该单元格不属于任何区域。
# 定义排列顺序 grid-auto-flow 属性
划分网格以后,容器的子元素会按照顺序,自动放置在每一个网格。默认的放置顺序是"先行后列"。
这个顺序由grid-auto-flow
属性决定,默认值是row
,即"先行后列"。也可以将它设成column
,变成"先列后行"。
grid-auto-flow: column;
row dense
和 column dense
表示不仅按照指定顺序排序,还将尽可能的往前填满空格。
grid-auto-flow: column dense;
# 对齐方式 justify-items,align-items,place-items 属性
justify-items
属性设置单元格内容的水平位置(即项目在被定义的单个网格内的位置),align-items
属性设置单元格内容的垂直位置。
.container {
justify-items: start | end | center | stretch;
align-items: start | end | center | stretch;
}
2
3
4
这两个属性的写法完全相同,都可以取下面这些值。
- start:对齐单元格的起始边缘。
- end:对齐单元格的结束边缘。
- center:单元格内部居中。
- stretch:拉伸,占满单元格的整个宽度(默认值)
# 整体对齐方式 justify-content, align-content, place-content 属性
justify-content
属性是整个内容区域在容器里面的水平位置,align-content
属性是整个内容区域的垂直位置。
两者属性完全相同,都可以取下面这些值。
justify-content: center; /* 居中排列 */
justify-content: start; /* 对齐容器的起始边框。默认状态 */
justify-content: end; /* 对齐容器的结束边框。 */
justify-content: stretch; /* 项目大小没有指定时,拉伸占据整个网格容器 */
justify-content: space-between; /* 均匀排列每个元素
首个元素放置于起点,末尾元素放置于终点
项目与容器边框之间没有间隔*/
justify-content: space-around; /* 均匀排列每个元素
每个元素周围分配相同的空间
每个项目两侧的间隔相等。所以,项目之间的间隔比项目与容器边框的间隔大一倍。*/
justify-content: space-evenly; /* 均匀排列每个元素
每个元素之间的间隔相等
项目与容器边框之间也是同样长度的间隔*/
2
3
4
5
6
7
8
9
10
11
12
13
place-content
属性是align-content
属性和justify-content
属性的合并简写形式。
place-content: <align-content> <justify-content>
# 定义新增的行或列 grid-auto-columns,grid-auto-rows 属性
有时候,一些项目的指定位置,在现有网格的外部。比如网格只有3列,但是某一个项目指定在第5行。这时,浏览器会自动生成多余的网格,以便放置项目。
grid-auto-columns
属性和grid-auto-rows
属性用来设置,浏览器自动创建的多余网格的列宽和行高。它们的写法与grid-template-columns
和grid-template-rows
完全相同。如果不指定这两个属性,浏览器完全根据单元格内容的大小,决定新增网格的列宽和行高。
如下:划分好的网格是3行 x 3列,但是,8号项目指定在第4行,9号项目指定在第5行,将超出内容定义的8号和9号项目行高统一为50px(此处原始的行高为100px)。
.container {
display: grid;
grid-template-columns: 100px 100px 100px;
grid-template-rows: 100px 100px 100px;
grid-auto-rows: 50px;
}
...
.item-8 {
background-color: #d0e4a9;
grid-row-start: 4;
grid-column-start: 2;
}
.item-9 {
background-color: #4dc7ec;
grid-row-start: 5;
grid-column-start: 3;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 语法糖 grid-template,grid 属性
grid-template
属性是grid-template-columns
、grid-template-rows
和grid-template-areas
这三个属性的合并简写形式。
grid
属性是grid-template-rows
、grid-template-columns
、grid-template-areas
、 grid-auto-rows
、grid-auto-columns
、grid-auto-flow
这六个属性的合并简写形式。
从易读易写的角度考虑,还是建议不要合并属性
# 项目属性
# 项目位置grid-column-start,grid-column-end,grid-row-start,grid-row-end 属性
项目的位置是可以指定的,具体方法就是指定项目的四个边框,分别定位在哪根网格线。
grid-column-start
属性:左边框所在的垂直网格线grid-column-end
属性:右边框所在的垂直网格线grid-row-start
属性:上边框所在的水平网格线grid-row-end
属性:下边框所在的水平网格线
如:1号项目的左边框是第二根垂直网格线,右边框是第四根垂直网格线。
.item-1 {
grid-column-start: 2;
grid-column-end: 4;
}
2
3
4
# 位置语法糖 grid-column,grid-row 属性
grid-column
属性是grid-column-start
和grid-column-end
的合并简写形式,grid-row
属性是grid-row-start
属性和grid-row-end
的合并简写形式。
.item-1 {
grid-column: 1 / 3;
grid-row: 1 / 2;
}
/* 等同于 */
.item-1 {
grid-column-start: 1;
grid-column-end: 3;
grid-row-start: 1;
grid-row-end: 2;
}
2
3
4
5
6
7
8
9
10
11
# 指定项目的区域 grid-area 属性
将1号项目置于header区域:
.item-1 {
grid-area: header;
}
2
3
grid-area
属性还可用作grid-row-start
、grid-column-start
、grid-row-end
、grid-column-end
的合并简写形式,直接指定项目的位置。
.item {
grid-area: <row-start> / <column-start> / <row-end> / <column-end>;
}
/*如:*/
.item-1 {
grid-area: 1 / 1 / 3 / 3;
}
2
3
4
5
6
7
# justify-self,align-self,place-self 属性
justify-self
属性设置单元格内容的水平位置,跟justify-items
属性的用法完全一致,但只作用于单个项目。
align-self
属性设置单元格内容的垂直位置,跟align-items
属性的用法完全一致,也是只作用于单个项目。
.item {
justify-self: start | end | center | stretch;
align-self: start | end | center | stretch;
}
2
3
4
- start:对齐单元格的起始边缘。
- end:对齐单元格的结束边缘。
- center:单元格内部居中。
- stretch:拉伸,占满单元格的整个宽度(默认值)。
place-self
属性是align-self
属性和justify-self
属性的合并简写形式。
place-self: <align-self> <justify-self>;