# 一、概述
grid 与 flex、block、inline-block 等一样都是通过 display 设置的一种布局方式。官方称其为网格布局。
什么是网格呢?
- 网格 是由一组水平线和垂直线相交而成,水平线将平面划分为 “行”,垂直线将平面划分为 “列” ,二者相交形成的封闭空间称之为 “单元格” 。
CSS 网格布局 就是利用 “行” 、 “列” 以及 “单元格”,指定 html 中的盒子及盒子中的子元素在单元格中的相应位置,来达到想要的布局效果。
# 二、兼容性
# 三、网格基础
# 1. 网格容器(父元素)
应用 display: grid
的元素。它是所有网格项的直接父级。在这个例子 container
中是网格容器。
<div class="container">
<div class="item item-1"></div>
<div class="item item-2"></div>
<div class="item item-3"></div>
</div>
# 2. 网格项目(子元素)
网格容器中的 直接子元素 都叫网格项目。这里的 item
元素是网格项目,但 sub-item
不是。
<div class="container">
<div class="item"></div>
<div class="item">
<p class="sub-item"></p>
</div>
<div class="item"></div>
</div>
# 3. 网格线、单元格
网格线:构成网格结构的分割线。垂直的“列网格线”;水平的“行网格线”。
单元格:由“行网格线”和“列网格线”交叉形成的封闭空间就是单元格。

正常情况下: $ 行网格线条数 n * 列网格线条数 m = 单元格个数 $
# 4. 网格轨道(行和列)
行:**两个相邻 **的行网格线之间形成的区域
列:两个相邻 的列网格线之间形成的区域
# 5. 网格区域
由任意几条行网格线和列网格线组成的封闭空间称之为网格区域
如上图黄色部分的网格区域就是由:行网格线 1、行网格线 3、列网格线 1、列网格线 3 ,四条网格线形成的封闭空间
# 四、grid 使用
必须使用
display: grid | inline-grid
将容器元素定义为网格;
当容器被定义为网格之后,我们就可以通过容器属性以及项目属性来实现我们想要的效果啦,那么都有哪些属性呢
# 1. Grid 容器的属性
容器(父元素)属性 | 属性取值 |
---|---|
display | grid 、 inline-grid |
grid-template-columns、grid-template-rows | 固定长度、fr、minmax()、repeat()...... |
grid-template-areas | 同上 |
简写:grid-template | |
------------------------ | ------------- |
grid-row-gap、grid-column-gap、grid-gap | |
grid-auto-flow | |
justify-items、align-items、place-items | |
justify-content ,align-content,place-content | |
grid-auto-columns, grid-auto-rows | |
简写:grid |
# 2. Grid 项的属性
项(子元素)属性 | 属性取值 |
---|---|
grid-column-start、grid-column-end、grid-row-start、grid-row-end | 当时开发上岛咖啡评审的派克服四大发明水电费 |
grid-column、grid-row | |
grid-area | |
justify-self、align-self、 place-self |
# 3. 属性的取值
# 3.1 固定长度、fr、minmax()、repeat()、Masonry、Subgrid
# 五、容器属性
设置在父元素上的属性
# 1. display 属性
定义:指定一个容器采用网格布局
取值:
grid:生成块级网格 代码展示地址 (opens new window)
Inline-grid:生成行内网格
注意,设为网格布局以后,容器子元素(项目)的
float
、display: inline-block
、display: table-cell
、vertical-align
和column-*
等设置都将失效。--摘自 (opens new window)
# 2. grid-template-columns、grid-template-rows
定义:定义行高、列宽。
grid-template-columns
属性定义每一列的列宽;grid-template-rows
属性定义每一行的行高;
取值:固定长度、百分比、fr、minmax()、repeat()
# 2.1 固定长度
我们常用的 px、rem、%、em......
- 设置 行高的情况如下:
项目 1、2、3 设置了固定高度 100px,其他项目的高度由自己的内容高度决定
设置 列宽的情况如下:
设置列宽的同时,会把所有项目按照设置的列数依次排列
根据上述规则:设置一个九宫格的代码如下
.container {
display: grid;
grid-template-columns: 100px 100px 100px;
grid-template-rows: 100px 100px 100px;
}
除了我们常用的固定单位外,grid 布局另外提供了新的取值方式:定义的关键字、函数
# 2.2 fr
fraction 的缩写,意为"片段",代表网格容器中可用空间的一部分
上图代表,可用空间被分割为 4 份,其中项目 1、3 各占用了一部分,项目 2 占用了 2 部分。代码展示 (opens new window)
- fr 与固定长度相结合
fr
是根据与其他长度值结合时的剩余空间计算的。
# 2.3 minmax()
表示宽、高在定义的长度范围内
该
minmax(最小值,最大值)
函数接受 2 个参数:“最小值,最大值” 中间以逗号分隔。
从上面两图对比:红色部分为容器的总宽 500px,代码展示 (opens new window)
图一:去掉固定的宽度,auto 会占用剩余的所有空间;
图二:设置了 minmax(0, 100px) 后,项目 1 最大就只能是 100px,所以并不会占满容器的剩余部分
# 2.4 repeat()
定义重复的单元格宽、高
该
repeat(重复次数,值)
函数接受 2 个参数:“重复后一个值的次数,值” 中间以逗号分隔。
- 值:可以是 1 个、可以是多个
重复一个值
重复多个值 代码展示 (opens new window)
# 3. grid-template-areas
定义:定义网格区域。一个区域由单个或多个单元格组成。
- (需要与项目属性 grid-areas 配合使用)代码展示 (opens new window)
取值:
名称集应该用单引号或双引号包裹起来,并且每个名称用空格分隔。每组名称定义一行,每个名称定义一列。
none
:表示没有定义网格区域.
:表示定义一个空的区域
.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';
}
上面代码先划分出 9 个单元格,然后将其定名为a
到i
的九个区域,分别对应这九个单元格。
多个单元格合并成一个区域的写法如下。
grid-template-areas:
'a a a'
'b b b'
'c c c';
上面代码将 9 个单元格分成a
、b
、c
三个区域。
下面是一个布局实例。
.container {
display: grid;
grid-template-columns: 50px 50px 50px 50px;
grid-template-rows: auto;
grid-template-areas:
'header header header header'
'main main . sidebar'
'footer footer footer footer';
}
.item-a {
grid-area: header;
}
.item-b {
grid-area: main;
}
.item-c {
grid-area: sidebar;
}
.item-d {
grid-area: footer;
}
这会创建一个四列宽、三行高的网格。整个顶行将由 标题 区域组成。中间行将由两个 主要 区域、一个空单元格和一个 侧边栏 区域组成。最后一行是 页脚。
声明中的每一行都需要具有相同数量的单元格。
如果某些区域不需要利用,则使用"点"(.
)表示。只要“点”之间没有空格,它们就代表一个单元格。
注意,区域的命名会影响到网格线。每个区域的起始网格线,会自动命名为
区域名-start
,终止网格线自动命名为区域名-end
。比如,区域名为
header
,则起始位置的水平网格线和垂直网格线叫做header-start
,终止位置的水平网格线和垂直网格线叫做header-end
。这意味着某些网格线可能有多个名称,例如上例中最左边的网格线,它将具有三个名称:
header-start
、main-start
和footer-start
。
# 4. grid-template
定义:
- 在单个声明中设置
grid-template-rows
、grid-template-columns
和grid-template-areas
的简写。
取值:
grid-template: 区域 行 / 列;代码展示 (opens new window)
none
:将所有三个属性设置为其初始值- 如下:
grid-template: 'head head head' 100px 'slide . main' 100px 'slide . main' 100px 'foot foot foot' 100px / auto 100px auto;
注意:这里的行高、列宽只能设置固定数值及 auto ,不能使用 repeat()、minmax()等函数类型
grid-template-xxxx 格式属性结束分割
# 5. grid-row-gap、grid-column-gap、grid-gap
定义:定义行间距、列间距。
grid-row-gap
:定义行与行的间距;grid-column-gap
:定义列与列的间距;grid-gap
:是grid-row-gap
与grid-column-gap
的合并简写;语法如下- grid-gap: 行间距 列间距;
- grid-gap: 间距;(只有一个属性值时表示行间距与列间距相等)
取值:同上
上述效果等价于:
grid-gap: 20px 50px;
/*
* 第一个参数为行间距,第二个参数为列间距;
* 当行间距和列间距相等时,可只写一个参数;
*/
根据最新标准,上面三个属性名的
grid-
前缀已经删除,grid-column-gap
和grid-row-gap
写成column-gap
和row-gap
,grid-gap
写成gap
。
- Gap 仅在 列/行**之间**创建 ,而不是在外边缘上,如下:
.container {
grid-template-columns: 100px 50px 100px;
grid-template-rows: 80px auto 80px;
column-gap: 10px;
row-gap: 15px;
}
# 6. justify-content、align-content、place-content
定义:整个内容区域在容器里面的水平、垂直位置。(容器的对齐方式)
justify-content
:整个容器水平位置(左中右);align-content
:整个容器垂直位置(上中下);place-content
:是justify-content
与align-content
的合并简写;语法如下- place-content: 水平位置 垂直位置;
- place-content: 位置;(只有一个属性值时表示水平位置与垂直位置相同);
取值:
start
:对齐容器的起始边框。.container { justify-content: start; }
end
:对齐容器的结束边框。.container { justify-content: end; }
center
:容器居中对齐。.container { justify-content: center; }
stretch
:拉伸占据整个网格容器。.container { justify-content: stretch; }
space-around
:每个项目两侧的间隔相等。所以,项目之间的间隔比项目与容器边框的间隔大一倍。.container { justify-content: space-around; }
space-between
:两端对齐:项目与项目的间隔相等,项目与容器边框之间没有间隔。.container { justify-content: space-between; }
space-evenly
: 项目与项目的间隔相等,项目与容器边框之间也是同样长度的间隔。.container { justify-content: space-evenly; }
align-content 与 justify-content 取值相同,只不过方向不同
# 7. justify-items、align-items、place-items
定义:整个项目内容在项目里面的水平、垂直位置。(单元格中的对齐方式)
justify-items
:单元格中的内容水平位置(左中右);align-items
:单元格中的内容垂直位置(上中下);place-items
:是justify-items
与align-items
的合并简写;语法如下- place-items: 水平位置 垂直位置;
- place-items: 位置;(只有一个属性值时表示水平位置与垂直位置相同);
取值:
start
:对齐单元格的起始边缘。.container { justify-items: start; }
.container { align-items: start; }
end
:对齐单元格的结束边缘。justify-items: end;
align-items: end;
center
:单元格内部居中。justify: center;
align-items: center;
stretch
:拉伸,占满单元格的整个宽度(默认值)。justify: stretch; || align-items: stretch;
# 8. grid-auto-flow
定义:
- 划分网格以后,容器的子元素会按照顺序,自动放置在每一个网格。默认的放置顺序是"先行后列",即先填满第一行,再开始放入第二行,即下图数字的顺序。
取值:
row
:先行后列排序,根据需要添加新行(默认)column
:先列后行排序,根据需求添加新列dense
:如果稍后出现较小的项目,则尝试在网格中更早地填充,- (请注意, dense 只会更改项目的视觉顺序,并可能导致它们出现乱序,这对可访问性不利。)
划分网格以后,容器的子元素会按照顺序,自动放置在每一个网格。默认的放置顺序是"先行后列",即先填满第一行,再开始放入第二行,即下图数字的顺序。
# 9. grid-auto-columns、 grid-auto-rows
# 10. 简写:
- grid 属性
# 10.
# 11.
# 六、项目属性
# 1. grid-column-start、grid-column-end、grid-row-start、grid-row-end
# 2. grid-column、grid-row
# 3. grid-area
配合容器属性 grid-template-area 使用
# 4. justify-self、align-self、place-self
# 七、与其他布局的区别
- 与表格布局的区别
- 与 flex 的区别
# 八、参考文献
CSS Grid 网格布局教程 (opens new window)