网格布局
网格是一组相交的水平线和垂直线,它定义了网格的列和行。我们可以将网格元素放置在与这些行和列相关的位置上。
核心概念
- 网格容器:用于实现网格布局的元素
- 网格元素:网格容器的所有直系子元素
- 网格线:用来划分网格轨道的平行线,包括行网格线和列网格线,其编号顺序同文本方向
- 网格轨道:相邻的两条平行的网格线之间的空间,包括行轨道和列轨道
- 网格单元:相邻的列网格线和相邻的行网格线交叉形成的区域,网格单元是网格容器中最小的单位
- 网格区域:网格单元向行或列方向扩展一个或多个单元形成的矩形区域
- 网格间距:网格单元之间横向和纵向的间距,不包括网格单元与网格容器边缘之间的间距
- 隐式网格:如果非固定宽高的网格容器无法容纳额外的网格元素,将按照一定规则创建隐式网格行轨道或列轨道,同时改变该方向上网格容器的尺寸
- 嵌套网格:网格元素作为网格容器称为嵌套网格,嵌套网格与父级无关且无隐式网格
描述轨道
下面使用 <track> 表示一个轨道,使用 <track-list> 表示一组轨道
<track> 的描述格式为 [lineName-start] <track-size> [lineName-end] ,其中:
[lineName]为网格线命名,可以使用多个命名,如[line1-end line2-start][lineName-start]和[lineName-end]为可选的,如果使用,则需要含在方括号内[lineName-start]和[lineName-end]使用 '-start' 和 '-end' 作为后缀时将自动生成同名(去掉后缀)的grid-area<track-size>表示轨道的尺寸,可以:- 使用传统尺寸单位,如
px - 使用
%单位: 相对于网格容器的百分比,如果网格容器的尺寸依赖于网格轨道,则该值视为auto - 使用
fr单位- 该单位将对容器当前方向上的剩余空间进行占比分配,若无剩余空间则依据网格元素内容的最大尺寸
- 当轨道
fr值之和小于 1 时,各轨道依据fr值占据剩余空间的对应的百分比而非依据各轨道自身占比
- 使用
auto单位,该单位将对容器依据网格元素尺寸进行自适应,如果网格元素内容超出,将依据其他网格元素内容剩余空间进行调整(该行为与fr不一致) - 使用
min-content: - 使用
max-content: - 使用
fit-content([<length> | <percentage>]): - 使用
minmax(min, max)函数: 该函数将限制轨道的最大最小尺寸
- 使用传统尺寸单位,如
<track-list> 的描述格式为
- 对每一个轨道进行单独描述,如
<track1> <track2> ... - 使用
repeat(<interger>|auto-fill, <track>)可以对重复的轨道进行简写,使用整数指定重复次数或使用auto-fill关键字让容器自动计算最大可填充列数(轨道尺寸不能指定为fr) - 使用上述两种方式混合使用
例子:
css
.wrapper {
display: grid;
grid-template-columns:
[nav-start] 200px [nav-end main-start] repeat(3, minmax(300px, auto))
[main-end rest-start] 1fr [rest-end];
}网格容器
- 创建容器:通过给元素指定样式
display: grid;或display: inline-grid;创建一个网格容器。 - 定义结构:通过
grid-template-rows和grid-template-columns定义行与列轨道 - 定义布局:通过
grid-template-areas定义命名网格区域布局 - 隐式网格:通过
grid-auto-flow指定隐式网格创建方向,通过grid-auto-rows或grid-auto-columns指定隐式网格轨道创建规则 - 定义间距:通过
grid-gap-rows和grid-gap-columns定义横向和列向的网格元素间距
grid-template-rows
- 说明
- 定义网格容器行轨道
- 格式
grid-template-rows: <track-list>;
- 取值
none: 表示不明确的指定栅格,所有的行和其尺寸由grid-auto-rows属性隐式指定<track-list>: 见 '描述轨道'
grid-template-columns
- 说明
- 定义网格容器列轨道
- 格式
grid-template-columns: <track-list>
- 取值
none: 表示不明确的指定栅格,所有的列和其尺寸由grid-auto-columns属性隐式指定<track-list>: 见 '描述轨道'
grid-template-areas
- 说明
- 定义网格区域的结构
- 示例
css
.container {
display: grid;
grid-template-rows: repeat(3, 1fr);
grid-template-columns: repeat(3, 1fr);
grid-template-areas:
"hd hd hd"
"bd bd bd"
".. ft ..";
}- 取值
nonegrid areas结构
- 格式
- 如示例所示,'hd'、'bd'、'ft' 为网格区域名称,'..' 表示空白区域
- 每一行使用一组网格区域名称放在引号中进行描述,行与行之间使用空格或换行分隔
- 跨越相邻行或列的网格区域名称描述一个网格区块
- 网格区块需要为矩形
- 默认
none
grid-template
- 说明
- 该属性为
grid-template-columns、grid-template-rows、grid-template-areas的复合属性 - 该属性通常用于进行创建简单网格,对于复杂的网格应当将其拆分为单一属性以提升可读性
- 该属性为
- 取值
none: 相当于grid-template-columns: none; grid-template-rows: none; grid-template-areas: none;- 见格式
- 默认
none
- 格式
- 格式 ①:
<grid-template-rows> / <grid-template-columns> - 格式 ②:
<grid-template-areas> <grid-template-rows> / <grid-template-column>
- 格式 ①:
- 注意
- 格式 ① 在 '/' 左右添加
[lineName]时在 vscode 中会报错(猜测为 bug 或部分插件限制),提示应当将其进行拆分为单一属性 - 格式 ② 可以在
<grid-template-areas> <grid-template-rows>前后添加网格线命名,在 vscode 中会报同样的错误,应当将其拆分为单一属性 - 猜测上述 vscode 中的报错为编译器认为属性值过于复杂会提升理解难度,这种写法应当禁止
- 格式 ① 在 '/' 左右添加
- 示例
css
.container {
display: grid;
grid-template: 100px repeat(2, 200px) 100px / 100px 1fr;
grid-template: /* 指定了网格区域名称的情况 */
"hd hd" 100px
"nv bd" 100px
"nv bd" 100px
"ft ft" 100px
/ 100px 1fr;
}grid-auto-flow
- 说明
- 指定网格元素在自动布局中的排列方向
- 语法
[row | column] | [dense]
- 取值
row: 自动布局算法按照逐行填充来排列元素column: 自动布局算法按照逐列填充来排列元素dense: 使用稠密堆积算法,容器试图使用小尺寸元素填充网格中之前留下的空白,可能导致元素次序被打乱row dense: 自动布局为列方向,使用稠密堆积算法column dense: 自动布局为行方向,使用稠密堆积算法
- 默认
row
grid-auto-columns
- 说明
- 指定隐式创建的列轨道尺寸
- 取值
<track-size><track-size-list>
- 注意
- 不支持
repeat模式描述的轨道列表
- 不支持
grid-auto-rows
- 说明
- 指定隐式创建的行轨道尺寸
- 取值
<track-size><track-size-list>
- 注意
- 不支持
repeat模式描述的轨道列表
- 不支持
grid-row-gap
- 说明
- 指定网格行轨道之间的行间隔间距
- 指定轨道间隔间距可能会使内容超出网格容器
- 取值
<length>: 固定的行轨道间隔间距<percentage>: 间距尺寸依据网格容器高度,需要先指定网格容器的height值,否则不生效
- 注意
- 此为行轨道之间的间隔间距,不包括行轨道与网格容器之间的间隔
- 若存在
fr计算的轨道,轨道间距不在剩余空间内 - 取值为百分比时需指定容器高度,该行为与
grid-auto-flow无关
grid-column-gap
- 说明
- 指定网格列轨道之间的列间隔间距
- 指定轨道间隔间距可能会使内容超出网格容器
- 取值
<length>: 固定列轨道间距间距<percentage>: 间距尺寸依据网格容器宽度
- 注意
- 此为列轨道之间的间隔间距,不包括列轨道与网格容器之间的间隔
- 若存在
fr计算的轨道,轨道间距不在剩余空间内
grid-gap
- 说明
- 该属性为
grid-column-gap和grid-row-gap的复合属性
- 该属性为
- 格式
grid-gap: <gap>: 该简写column-gap值同row-gapgrid-gap: <row-gap> <column-gap>
- 取值
<length>: 固定的轨道间隔间距<percentage>: 间距尺寸依据网格容器尺寸,列方向的网格间距需要先指定网格容器的height值,否则不生效
- 注意
- 此为轨道之间的间隔间距,不包括轨道与网格容器之间的间隔
- 若存在
fr计算的轨道,轨道间距不在剩余空间内 <row=gap>取值为百分比时需指定容器高度,该行为与grid-auto-flow无关
align-items
- 说明
- 指定网格元素在列轴上的对齐方式
- 取值
start: 块方向开始位置对齐center: 块方向居中对齐end: 块方向末尾位置对齐stretch: 拉伸
- 注意
- 具有指定宽高的网格元素,默认行为为
start - 没有指定宽高的网格元素,默认行为为
stretch
- 具有指定宽高的网格元素,默认行为为
justify-items
- 说明
- 指定网格元素在行轴上的对齐方式
- 取值
start: 行方向开始位置对齐center: 行方向居中对齐end: 行方向末尾位置对齐stretch: 拉伸
- 注意
- 具有指定宽高的网格元素,默认行为为
start - 没有指定宽高的网格元素,默认行为为
stretch
- 具有指定宽高的网格元素,默认行为为
align-content
- 说明
- 当总网格区域尺寸小于网格容器时,可以设置网格轨道的对齐方式
- 这里要求总网格区域块方向尺寸小于网格容器高度
- 取值
startcenterendstretch: 拉伸space-around: 均匀分布,网格元素间距相等,网格元素与网格容器间距为网格元素间距的一半space-between: 两端对齐,网格元素间距相等space-evenly: 等距分布,网格元素间距,网格元素与网格容器间距相同
- 注意
- 取
stretch时,若网格轨道为固定值则失效
- 取
justify-content
- 说明
- 当总网格区域尺寸小于网格容器时,可以设置网格轨道的对齐方式
- 这里要求总网格区域行方向尺寸小于网格容器宽度
- 取值
startcenterendstretch: 拉伸space-around: 均匀分布,网格元素间距相等,网格元素与网格容器间距为网格元素间距的一半space-between: 两端对齐,网格元素间距相等space-evenly: 等距分布,网格元素间距,网格元素与网格容器间距相同
- 注意
- 取
stretch时,若网格轨道为固定值则失效
- 取
网格元素
网格元素定位可以通过以下方式进行描述
- 基于网格线的描述
- 使用网格线编号(注意:网格线编号是从 1 开始计算的)
- 使用网格线名称
- 基于命名网格区域的描述
- 使用网格区域名称
grid-column-start && grid-row-start
- 说明
- 指定网格元素起始位置
- 未指定网格元素结束位置时默认延当前方向跨越 1 个轨道
- 取值
auto<line-name>: 起始位置为指定的命名列网格线<integer>: 起始位置为指定编号的列网格线,若为负数则从行方向尾部开始计算span <integer>: 指定跨越的轨道数,需要与grid-column-end或grid-row-end结合使用span <line-name>: 指定起始网格线,需指定grid-column-end或grid-row-end才生效
grid-column-end && grid-row-end
- 说明
- 指定网格元素的结束位置
- 未指定网格元素开始位置时默认逆当前方向跨越 1 个轨道
- 取值
auto<line-name>span <integer>span <line-name>
grid-column && grid-row
- 说明
grid-column为grid-column-start与grid-column-end的复合属性grid-row为grid-row-start与grid-row-end的复合属性
- 格式
grid-column: <column-start> / <column-end>grid-row: <row-start> / <row-end>grid-column: <linename>: 相当于grid-column: <linename-start> / <linename-end>的简写grid-row: <linename>: 相当于grid-row: <linename-start> / <linename-end>的简写
grid-area
- 说明
- 该属性为
grid-row-start、grid-column-start、grid-row-end、grid-column-end的简写 - 也可以指定为一个命名网格区域的名称
- 该属性为
align-self
- 说明
- 作用于网格元素
- 效果同
align-items - 设置该属性将优先于
align-items的作用效果
justify-self
- 说明
- 作用于网格元素
- 效果同
justify-items - 设置该属性将优先于
justify-items的作用效果
示例
html
<div layout="grid" class="container">
<div class="header"></div>
<div class="nav"></div>
<div class="main"></div>
<div class="footer"></div>
</div>css
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
[layout="grid"] {
display: grid;
border: 1px solid #000;
}
[layout="grid"] > div {
border: 1px dashed #aaa;
}
@media screen and (min-width: 720px) {
.container {
grid-template-columns: 240px minmax(480px, 1fr);
grid-template-rows: 100px auto 80px;
grid-template-areas: "header header" "nav main" "nav footer";
}
}
@media screen and (max-width: 720px) {
.container {
grid-template-columns: minmax(640px, 1fr);
grid-template-rows: 100px 80px auto 80px;
grid-template-areas: "header" "nav" "main" "footer";
}
}
.header {
grid-area: header;
background: red;
}
.nav {
grid-area: nav;
background: green;
}
.main {
grid-area: main;
background: blue;
height: 600px;
}
.footer {
grid-area: footer;
background: orange;
}