# Grid 网格布局从入门到实践 TIP
上一章我们学习了 Flex 弹性布局,但我们学习完后,就会发现 Flex 弹性布局更适合做一维布局,一行或者一列。
如果我们想要轻松实现多行多列的这种二维布局,就可以用到我们接下来要讲到的 Grid 网格布局。
# 一、Grid 网格布局的基础概念 TIP
在学习 Grid 网格布局前,首先我们来了解下 Grid 网格布局相关的一些基本概念
什么是网格布局 什么是 grid 容器(container)和项目(item) 什么是行、列和单元格 什么是网格线 什么是网格轨道(Grid tracks) 什么是网格区域(Grid areas) 什么是网格间距(Gutters) 什么是网格内容 # 1、什么是网格布局 TIP
Grid 布局则是将容器划分成"行"和"列",产生单元格,然后指定“项目”所在的单元格,可以看作是二维布局。 Grid 布局远比 Flex 布局强大
Flex 更适合处理一维布局,单行或单列 Grid 更适合处理二维布局,多行多列
# 2、什么是 grid 容器和项目 TIP
采用网格布局的区域,称为 “容器”(container)。容器内的直接子元素,称为 “项目”(item) 通过给元素添加display:grid 或 display: inline-grid;来指定元素为 Grid 网格布局
display:grid; 元素自身以块级元素显示 display: inline-grid; 元素自身以行内块元素显示 任何元素都可以指定为 Grid 网格布局
.grid-container {
/* 采用 grid 网格布局 */
display: grid;
/* display:inline-grid; */
background-color: skyblue;
}
注:
display 不同值的表现效果
grid inline-grid 以上代码中 class 名为grid-container的 div 就是 Grid 容器,class 名为grid-item的 div 就是 Grid 项目
# 3、什么是行、列和单元格 TIP
容器里面的水平区域称为"行"(row),垂直区域称为"列"(column)。 行和列交叉形成区域,称为"单元格"(cell)。 正常情况下,n行和m列会产生n x m个单元格。 如下图的容器被划分为 3 行 3 列,总共被划分出3 * 3 = 9个单元格
# 4、什么是网格线 TIP
划分网格的线,称为“网格线”(grid line) 水平网格线划分出行,垂直网格线划分出列。 正常情况下,n行有n + 1根水平网格线,m列有m + 1根垂直网格线 如下图,Grid 容器划分成3行3列的网格,那就有4根水平网格线和4根垂直网格线
# 5、什么是网格轨道(Grid tracks) TIP
网格轨道是两条网格线之间的空间,如下图标出的水平方向和垂直方向上的轨道
# 6、什么是网格区域(Grid areas) TIP
网格区域是由网格中一个或者多个单元格组成的一个矩形区域。有点类似于表格中的合并,单个单元格或多个单元格合并后形成的区域。 也就是意味着,我们把 Grid 容器划分成对应的网格单元格后,我们可以对这些网格单元格做合并操作。 下图中 Grid 容器划分成 3 行 3 列的网格,形成了 9 个单元格,包含 6 个网格区域
# 7、什么是网格间距(Gutters) TIP
网格间距分为行间距和列间距 行与行的间隔,被称为行间距,列与列的间隔,被称为列间距。具体如下图所示
# 8、什么是网格内容区域 TIP
我们知道 Grid 容器的每一个子元素,被称为 Grid 项目。所有 Grid 项目看成一个整体,这个整体我们称为网格内容。
注:
学习了 Grid 网格布局相关的基础概念后,接下来我们就来学习 Grid 容器和 Grid 项目相关的属性,这些属性控制着 Grid 网格的布局效果。
# 二、Grid 容器属性 TIP
当元素设为网格布局以后,容器子元素(项目)的float、display: inline-block、display: table-cell、vertical-align和column-*等设置都将失效。 接下来我们来学习 Grid 容器相关的属性,具体如下表格中列出的 属性名 说明 grid-template-columns 定义列和每一列的列宽 grid-template-rows 定义行和每一行的行高 row-gap 设置行与行的间隔(行间距) column-gap 设置列与列的间隔(列间距) gap 是column-gap和row-gap的合并简写形式 grid-template-areas 网格布局允许指定"区域"(area),一个区域由单个或多个单元格组成。grid-template-areas属性用于定义区域。 grid-auto-flow 设置容器的子元素排列顺序,默认是 "先行后列" grid-auto-columns 设置隐式网格的列宽 grid-auto-rows 设置隐式网格的行高 justify-items 单元格中内容在单元格中水平对齐方式 align-items 单元格中内容在单元格中垂直对齐方式 place-items place-items属性是align-items属性和justify-items属性的合并简写形式。 justify-content 设置整个内容区域在容器里面的水平位置 align-content 设置整个内容区域在容器里面的垂直位置 place-content place-content属性是align-content属性和justify-content`属性的合并简写形式 grid-template grid-template属性是grid-template-columns、grid-template-rows和grid-template-areas这三个属性的合并简写形式。 # 1、grid-template-columns 和 grid-template-rows 属性 TIP
容器指定了网格布局以后,接着就要划分行和列 grid-template-columns属性定义列和列宽 grid-template-rows属性定义行和行高 以上两个属性值,可以是以下 4 种之一
绝对长度 ,如 200px 百分比%值,相对 Grid 容器宽和高而言。如:20% fr 项目所占容器的份数,如:1fr auto 项目列宽和行高自动计算 # 1.1、绝对长度单位 px TIP
指定一个三行三列的网格,每一列列宽为100px,每一行行高为100px
.grid-container {
/* 网格布局 */
display: inline-grid;
/* 定义行,3行的行高都是100px */
grid-template-rows: 100px 100px 100px;
/* 定义列,3列的宽都是100px */
grid-template-columns: 100px 100px 100px;
margin: 100px;
}
# 1.2、百分比%单位 TIP
百分比%,相对 Grid 容器宽和高而言
.grid-container {
/* 网格布局 */
width: 400px;
height: 300px;
border: 3px solid red;
display: inline-grid;
/*
定义了3行,及每一行行高
第一行高 20% * 300px=60px
第二行高 50% * 300px=150px
第三行高 30% * 300px=90px
*/
grid-template-rows: 20% 50% 30%;
/*
定义了3列,及每一列列宽
第一列宽 20% * 400px=80px
第二列宽 50% * 400px=200px
第三列宽 30% * 400px=120px
*/
grid-template-columns: 20% 50% 30%;
margin: 100px;
}
# 1.3、fr 关键字 TIP
为了方便表示比例关系,网格布局提供了fr关键字(fraction 的缩写,意为"片段")。 如果所有列或行都用 fr 单位
每一列宽 = 容器宽 * (当前列 fr 值 / 所有列 fr 值总和) 每一行高 = 容器高 *(当前行 fr 值 / 所有行 fr 值总和)
.grid-container {
/* 网格布局 */
width: 600px;
display: inline-grid;
/* 定义2行,每一行高为100px */
grid-template-rows: 100px 100px;
/*
定义3列,3列分别占容器总宽的 份数 1份 2份 3份
第1列宽 =600px * 1/(1+2+3)=100px
第2列宽 =600px * 2/(1+2+3)=200px
第3列宽 =600px * 3/(1+2+3)=300px
*/
grid-template-columns: 1fr 2fr 3fr;
margin: 100px;
}
fr可以与绝对长度的单位结合使用,此时,fr 单位的行或列,表示的是平分剩余空间高或宽
.grid-container {
/* 网格布局 */
width: 600px;
display: inline-grid;
/* 定义2行,每一行高为100px */
grid-template-rows: 100px 100px;
/*
定义3列
第1列宽 200px
第2列宽=(600px-200px)*2/(2+3)=160px
第3列宽=(600px-200px)*3/(2+3)=240px
*/
grid-template-columns: 200px 2fr 3fr;
margin: 100px;
}
# 1.4、auto 关键字 TIP
auto 表示当对应单元格的列宽或行高会自动计算,但单元格的列宽和行高始终都会 >= 放置在当前单元格中元素宽和高
语法:
grid-template-columns: 100px auto 100px;
.grid-container {
border: 2px solid red;
/* 网格布局 */
display: grid;
grid-template-rows: 100px;
grid-template-columns: 200px auto 200px;
}
.grid-item:nth-child(1) {
background-color: skyblue;
}
.grid-item:nth-child(2) {
background-color: pink;
/* width: 500px; */
}
.grid-item:nth-child(3) {
background-color: khaki;
}
当放置在中间单元格中的 div 元素没有设置宽时,单元格宽自动计算,占满所有剩余宽。
TIP
当放置在中间单元格中 div 的宽为 500px 时,单元格宽 >= 500px .grid-item:nth-child(2) {
width: 500px;
}
# 1.5、repeat() 函数 TIP
有时候,重复写同样的值非常麻烦,尤其网格很多时。这时,可以使用repeat()函数,简化重复的值。 repeat()接受两个参数,第一个参数是重复的次数,第二个参数是所要重复的值。 /* 定义行,3行的行高都是100px */
grid-template-rows: repeat(3, 100px);
/* 定义列,3列的宽都是100px */
grid-template-columns: repeat(3, 100px);
grid-template-columns: 100px repeat(2, 200px);
/* 等同于下面写法 */
grid-template-columns: 100px 200px 200px;
repeat()用于重复种模式也是可以 /* 定义了6行,第1,4行的高为50px 第2,5行的高为100px,第3,6行的高为80px */
grid-template-rows: repeat(2, 50px 100px 80px);
/* 等同于下面写法 */
grid-template-rows: 50px 100px 80px 50px 100px 80px;
grid-template-columns: 100px repeat(2, 1fr 2fr);
/* 等同于下面写法 */
grid-template-columns: 100px 1fr 2fr 1fr 2fr;
案例
.grid-container {
/* 网格布局 */
width: 400px;
display: inline-grid;
/* 定义2行,每一行高为100px */
grid-template-rows: repeat(2, 100px);
/*
定义4列
第1,3列宽为50px
第2,4列宽为100px
*/
grid-template-columns: repeat(2, 50px 100px);
margin: 100px;
}
# 1.6、auto-fill 关键字 TIP
有时,单元格的大小是固定的,但是容器的大小不确定,如果希望每一行(或每一列)容纳尽可能多的单元格,这时可以使用auto-fill关键字表示自动填充。
语法:
/*
如果 grid 容器宽为 480px,则生成4列 (480 / 100 =4.8 取整数)
如果 grid 容器宽为 500px,则生成 5列 (500 / 100=5 取整数)
*/
grid-template-columns: repeat(auto-fill, 100px);
案例
.grid-container {
/* 网格布局 */
/* width: 580px; */
height: 300px;
border: 2px solid red;
display: grid;
/* 定义2行,第一行高为100px */
grid-template-rows: repeat(2, 100px);
/*
列为自动填充 最终列数=容器宽 / 100 得到的整数部分
最终列数=580/100=5.8 所以最终为5列
*/
grid-template-columns: repeat(auto-fill, 100px);
/* margin: 100px; */
}
/* 奇数*/
.grid-item:nth-child(odd) {
background-color: khaki;
}
/* 偶数*/
.grid-item:nth-child(even) {
background-color: skyblue;
}
注:
以上效果存在一个很大的问题,当某行的单元格总宽加起来小于容器宽时,就会在最右侧留下一片空白。接下来学到的minmax 函数可以解决这个问题。
# 1.7、minmax() TIP
minmax()函数产生一个长度范围,表示长度就在这个范围之中。它接受两个参数,分别为最小值和最大值。
语法:
/*
minmax(100px , 1fr) 表示最小宽为300px,最大为1fr
*/
grid-template-columns: 1fr 1fr minmax(300px, 1fr);
.grid-container {
/* 网格布局 */
display: grid;
/*
创建3列
minmax(300px,1fr)表示最小宽300px,最大宽1fr
当三列平分容器宽>=300时,三列宽相等
当三列平分容器宽<300时,第三列宽=300,另外两列宽=(容器宽-300)/2
*/
grid-template-columns: 1fr 1fr minmax(300px, 1fr);
}
.grid-item:nth-child(1) {
background-color: skyblue;
}
.grid-item:nth-child(2) {
background-color: pink;
}
.grid-item:nth-child(3) {
background-color: khaki;
}
响应式布局
自动计算每一行要显示的元素个数,且不会出现右侧有空白的问题
.grid-container {
/* 最大宽1200px,
当宽小于1200px时,以当前宽显示
当宽超过1200px 时,则按1200px处理
*/
max-width: 1000px;
height: 300px;
margin: 0px auto;
display: grid;
/* 定义2行,第一行高为100px */
grid-template-rows: repeat(2, 100px);
/*
列为自动填充 最终列数=容器宽 / 100 得到的整数部分
最终列数=580/100=5.8 所以最终为5列
*/
grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
gap: 10px; /* 行列间距 */
}
/* 奇数*/
.grid-item:nth-child(odd) {
background-color: khaki;
}
/* 偶数*/
.grid-item:nth-child(even) {
background-color: skyblue;
}
# 1.8、指定网格线的名称 TIP
grid-template-columns属性和grid-template-rows属性里面,还可以使用方括号,指定每一根网格线的名字,方便以后的引用。
.grid-container {
/* 网格布局 */
display: grid;
width: 800px;
margin: 100px auto;
/* 定义行 及网格线名称 */
grid-template-rows: [a1] 200px [a2];
/* 定义列 及网格线名称 */
grid-template-columns: [b1] 150px [b2] 200px [b3] auto [b4];
}
.grid-item:nth-child(1) {
background-color: skyblue;
}
.grid-item:nth-child(2) {
background-color: pink;
}
.grid-item:nth-child(3) {
background-color: khaki;
}
# 2、row-gap、column-gap、gap 属性 TIP
在早期三个属性的写法分别为:grid-row-gap、grid-column-gap、grid-gap。 根据最新标准,三个属性前的 grid-前缀已经删除。
属性名 说明 row-gap 设置行与行的间隔(行间距) column-gap 设置列与列的间隔(列间距) gap 是row-gap和column-gap的合并简写形式 属性值单位为 绝对单位 px 或 百分比% 如果单位是百分比,则百分比相对的是网格容器的百分比 gap 后如果只写一个值,表示列间距和行间距一样大小 /*
gap:10px 20px;是 row-gap:10px 与 column-gap:20px;的简写
*/
gap: 10px 20px;
.grid-container {
/* 网格布局 */
display: grid;
grid-template-rows: repeat(2, 100px);
grid-template-columns: repeat(3, 100px);
margin: 30px;
/* 行间距10px 列间距20px */
gap: 10px 20px;
}
.grid-item:nth-child(n) {
background-color: skyblue;
}
.grid-item:nth-child(2n) {
background-color: pink;
}
# 3、grid-template-areas 属性 TIP
grid-template-areas 属性用于指定网格区域,一个区域由单个或多个单元格组成。 这个属性需要配合项目属性grid-area一起来使用 grid-area属性用于指定 Grid 项目放在哪一个区域。 grid-area后的值为区域名 /* 定义3行,每行高为100px */
grid-template-rows: repeat(3, 100px);
/* 定义3列,第列宽为100px */
grid-template-columns: repeat(3, 100px);
/* 每个单元格定义为一个区域,每个区域名分别为 a 到i */
grid-template-areas:
"a b c"
"d e f"
"g h i";
将上面多个单元格合并成一个区域的写法如下:
grid-template-areas:
"a a b"
"a a b"
"c c c";
上面代码将 9 个单元格分成 a,b,c 三个区域
案例应用
.grid-container {
/* 网格布局 */
display: inline-grid;
/* 定义3行,每行高为100px */
grid-template-rows: repeat(3, 100px);
/* 定义3列,每列宽为100px */
grid-template-columns: repeat(3, 100px);
/* 定义了三个区域,区域名分别为 a,b,c */
grid-template-areas:
"a a b"
"a a b"
"c c c";
margin: 100px;
}
/* 每个区域中文字效果 */
.grid-item {
text-align: center;
line-height: 100px;
font-size: 30px;
color: red;
}
.grid-item:nth-child(1) {
/* 将项目放在区域a中 */
grid-area: a;
background-color: skyblue;
}
.grid-item:nth-child(2) {
/* 将项目放在区域b中 */
grid-area: b;
background-color: pink;
}
.grid-item:nth-child(3) {
/* 将项目放在区域c中 */
grid-area: c;
background-color: khaki;
}
如果某些区域不需要利用,则使用点(.)表示 grid-template-areas:
"a . . b"
"c . . d"
"e . . f";
.grid-container {
/* 网格布局 */
display: inline-grid;
/* 定义3行,每行高为100px */
grid-template-rows: repeat(3, 100px);
/* 定义4列,每列宽为100px */
grid-template-columns: repeat(4, 100px);
/* 定义了6个区域,区域名分别为 a,b,c,d,e,f*/
grid-template-areas:
"a . . b"
"c . . d"
"e . . f";
margin: 100px;
}
/* 每个区域中文字效果 */
.grid-item {
text-align: center;
line-height: 100px;
font-size: 30px;
color: red;
}
.grid-item:nth-child(1) {
/* 将项目放在区域a中 */
grid-area: a;
}
.grid-item:nth-child(2)
/* 将项目放在区域b中 */ {
grid-area: b;
}
.grid-item:nth-child(3) {
/* 将项目放在区域c中 */
grid-area: c;
}
.grid-item:nth-child(4) {
/* 将项目放在区域d中 */
grid-area: d;
}
.grid-item:nth-child(5) {
/* 将项目放在区域e中 */
grid-area: e;
}
.grid-item:nth-child(6) {
/* 将项目放在区域f中 */
grid-area: f;
}
注意:
区域的命名会影响到网格线。每个区域的起始网格线,会自动命名为区域名-start,终止网格线自动命名为区域名-end。
# 4、grid-auto-flow 属性 TIP
grid-auto-flow 属性决定了项目在容器中的排列顺序。是 “先行后列”,还是 “先列后行”
语法:
/* 先行后列 */
grid-auto-flow: row;
属性值 说明 row 默认值,即 "先行后列",即项目默认从左往右 先填满第一行,再开始放第二行,依次下。 column "先列后行",即项目先从上往下填满第一列,再开始放第二列,依次下去 row dense 某些项目指定位置以后,剩下的项目怎么自动放置。表示 "先行后列",并且尽可能紧密填满,尽量不出现空格。 column dense 某些项目指定位置以后,剩下的项目怎么自动放置。表示 "先列后行",并且尽量填满空格 案例
.grid-container {
/* 网格布局 */
display: inline-grid;
/* 定义3行,每行高为100px */
grid-template-rows: repeat(3, 100px);
/* 定义4列,第列宽为100px */
grid-template-columns: repeat(3, 100px);
/* 项目放置顺序,先列后行 */
grid-auto-flow: column;
margin: 100px;
}
/* 每个区域中文字效果 */
.grid-item {
text-align: center;
line-height: 100px;
font-size: 30px;
color: red;
}
row 效果 column 效果 提示
row dense 与 column dense的效果,我们放在讲 Grid 项目属性grid-column时再来讲解
# 5、grid-auto-columns 和 grid-auto-rows 属性 TIP
在学习这两个属性前,我们先来了解两个概念
什么是显示网格?
使用grid-template-columns和grid-template-rows指定尺寸创建出来行和列形成的网格。
什么是隐藏网格?
不是grid-template-columns或grid-template-rows指定尺寸创建出来行和列形成的网格,而是自动布局算法创建的额外的行或列形成的网格。
grid-auto-columns :隐式创建的网格纵向轨道(track)的宽度。即设置隐式网格的宽度 grid-auto-rows:用于指定隐式创建的行轨道大小。即设置隐式网格的高度 grid-auto-columns与grid-auto-rows的写法与grid-template-columns和grid-template-rows完全相同。 如果不指定grid-auto-columns与grid-auto-rows这两个属性,浏览器完全根据单元格内容的大小,决定新增网格的列宽或 行高。 案例
.grid-container {
width: 300px;
background-color: skyblue;
/* 网格布局 */
display: inline-grid;
/* 定义2行,每行高为100px */
grid-template-rows: repeat(2, 100px);
/* 定义3列,列宽自动 */
grid-template-columns: repeat(3, 100px);
margin: 100px;
}
.grid-item {
padding: 10px;
font-size: 30px;
color: red;
}
.grid-item:nth-child(n) {
background-color: pink;
}
.grid-item:nth-child(2n) {
background-color: khaki;
}
上面案例没有指定隐式网格的行高,则单元格 7-9 的高度为其内容的高度。
# 5.1、grid-auto-rows 设置隐式网格高
.grid-container {
width: 300px;
background-color: skyblue;
/* 网格布局 */
display: inline-grid;
/* 定义2行,每行高为100px */
grid-template-rows: repeat(2, 100px);
/* 定义3列,列宽自动 */
grid-template-columns: repeat(3, 100px);
/* 隐式网格的高度 */
grid-auto-rows: 200px;
margin: 100px;
}
.grid-item {
padding: 10px;
font-size: 30px;
color: red;
}
.grid-item:nth-child(n) {
background-color: pink;
}
.grid-item:nth-child(2n) {
background-color: khaki;
}
# 5.2、grid-auto-columns 设置隐式网格宽
.grid-container {
width: 300px;
background-color: skyblue;
/* 网格布局 */
display: inline-grid;
/* 定义2行,每行高为100px */
grid-template-rows: repeat(2, 100px);
/* 定义3列,列宽自动 */
grid-template-columns: repeat(3, 100px);
grid-auto-flow: column;
/* grid-auto-rows: 200px; */
/* 设置隐式网格的列宽 */
grid-auto-columns: 200px;
margin: 100px;
}
.grid-item {
padding: 10px;
font-size: 30px;
color: red;
}
.grid-item:nth-child(n) {
background-color: pink;
}
.grid-item:nth-child(2n) {
background-color: khaki;
}
注意:
grid-auto-rows属性和grid-auto-columns属性两者同时设置,只会有一个生效。
# 6、justify-items 属性 TIP
justify-items属性设置单元格内容的水平位置
语法:
justify-items: center;
属性值 说明 stretch (默认值)拉伸,占满单元格的整个宽度(grid 项未设置宽度时才能看到效果) start 与单元格最左边对齐 end 与单元格最右边对齐 center 单元格内水平对齐
.grid-container {
/* 网格布局 */
display: inline-grid;
/* 定义3行,每行高为100px */
grid-template-rows: repeat(3, 100px);
/* 定义3列,第列宽为100px */
grid-template-columns: repeat(3, 100px);
margin: 100px;
/* 单元格里面内容对齐方式 */
justify-items: center;
}
/* 每个区域中文字效果 */
.grid-item {
font-size: 30px;
color: red;
}
.grid-item:nth-child(n) {
background-color: skyblue;
}
.grid-item:nth-child(2n) {
background-color: khaki;
}
strecth start end center # 7、align-items 属性 TIP
align-items属性设置单元格内容的垂直对齐方式
语法:
align-item: stretch;
属性值 说明 stretch (默认值)拉伸,占满单元格的整个高度 start 与单元格最上边对齐 end 与单元格最下边对齐 center 单元格内垂直居中对齐
.grid-container {
/* 网格布局 */
display: inline-grid;
/* 定义3行,每行高为100px */
grid-template-rows: repeat(3, 100px);
/* 定义3列,第列宽为100px */
grid-template-columns: repeat(3, 100px);
margin: 100px;
/* 单元格里面内容垂直对齐方式 */
align-items: stretch;
}
/* 每个区域中文字效果 */
.grid-item {
font-size: 30px;
color: red;
}
.grid-item:nth-child(n) {
background-color: skyblue;
}
.grid-item:nth-child(2n) {
background-color: khaki;
}
stretch start end center # 8、 place-items 属性 TIP
place-items属性是align-items属性和justify-items属性的合并简写形式。
语法:
/*
与单元格上面对齐,水平居中显示
*/
place-items: start center;
如果省略第二个值,则相当于第二值与第一个值相等 start center center # 9、justify-content 属性 TIP
justify-content属性设置整个内容区域在容器里面的水平位置
语法:
justify-content: start;
属性名 说明 start 默认值,对齐容器的左边框 end 对齐容器的右边框 center 容器内部水平居中。 stretch 单元格大小没有指定时,拉伸宽占据整个网格容器。 space-around 每个项目两侧的间隔相等。所以,项目之间的间隔比项目与容器边框的间隔大一倍。 space-between 项目与项目的间隔相等,项目与容器边框之间没有间隔。 space-evenly 项目与项目的间隔相等,项目与容器边框之间也是同样长度的间隔。 案例
.grid-container {
width: 300px;
height: 200px;
background-color: skyblue;
/* 网格布局 */
display: inline-grid;
/* 定义3行,每行高为50px */
grid-template-rows: repeat(3, 50px);
/* 定义3列,列宽自动 */
grid-template-columns: repeat(3, auto);
margin: 100px;
/* 内容区域在容器中的水平对齐方式 */
justify-content: start;
}
.grid-item {
padding: 10px;
font-size: 30px;
color: red;
}
.grid-item:nth-child(n) {
background-color: pink;
}
.grid-item:nth-child(2n) {
background-color: khaki;
}
start end center stretch space-around space-between space-evenly # 10、align-content 属性 TIP
align-content属性是整个内容区域的垂直位置。
属性名 说明 start 默认值,对齐容器的起始边框 end 对齐容器的结束边框 center 容器内容垂直居中。 stretch 单元格高度没有指定时,单元高度会被拉伸占据整个网格容器。 space-around 每个项目两侧的间隔相等。所以,项目之间的间隔比项目与容器边框的间隔大一倍。 space-between 项目与项目的间隔相等,项目与容器边框之间没有间隔。 space-evenly 项目与项目的间隔相等,项目与容器边框之间也是同样长度的间隔。 start end center stretch space-around space-between space-evenly # 11、place-content 属性 TIP
place-content属性是align-content 属性和justify-content属性的合并简写形式
语法:
place-content: align-content justify-content;
.grid-container {
width: 300px;
height: 200px;
background-color: skyblue;
/* 网格布局 */
display: inline-grid;
/* 定义3行,每行高为50px */
grid-template-rows: repeat(3, 50px);
/* 定义3列,列宽自动 */
grid-template-columns: repeat(3, auto);
margin: 100px;
/* 内容区域在容器中的垂直和水平对齐方式 */
place-content: space-between space-between;
}
.grid-item {
padding: 10px;
font-size: 30px;
color: red;
}
.grid-item:nth-child(n) {
background-color: pink;
}
.grid-item:nth-child(2n) {
background-color: khaki;
}
# 12、grid-template 和 grid 属性 TIP
grid-template属性是grid-template-columns、grid-template-rows和grid-template-areas这三个属性的合并简写形式。
/*
grid-template:grid-template-rows / grid-template-columns
以下css样式,
定义了2行, 行高分别为100px 和200px
定义了2列,列宽分别为 50px 100px
并没有划分区域
*/
grid-template: 100px 200px / 50px 100px;
定义行列,同时划分区域
/*
定义行列和区域
3行 行高分别为 50px 100px 50px
3列 列宽分别为 100px 100px 100px
*/
grid-template:
"a a b" 50px
"a a b" 100px
"c c c" 50px / 100px 100px 100px;
案例
.grid-container {
width: 300px;
background-color: skyblue;
/* 网格布局 */
display: inline-grid;
/*
定义行列和区域
3行 行高分别为 50px 100px 50px
3列 列宽分别为 100px 100px 100px
*/
grid-template:
"a a b" 50px
"a a b" 100px
"c c c" 50px / 100px 100px 100px;
margin: 100px;
}
.grid-item {
padding: 10px;
font-size: 30px;
color: red;
}
.grid-item:nth-child(1) {
background-color: pink;
/* 指定所占区域 */
grid-area: a;
}
.grid-item:nth-child(2) {
background-color: khaki;
/* 指定所占区域 */
grid-area: b;
}
.grid-item:nth-child(3) {
background-color: skyblue;
/* 指定所占区域 */
grid-area: c;
}
注:
grid属性是grid-template-rows、grid-template-columns、grid-template-areas、 grid-auto-rows、grid-auto-columns、grid-auto-flow这六个属性的合并简写形式。
因为过于复杂,实际并不会用这种方式,具体的大家可以参考 官方教程做了解 (opens new window) 👆
# 三、Grid 项目的属性 TIP
接下来我们来学习 Grid 项目相关的属性,具体如下表格中列出的
属性 说明 grid-column-start 项目左边框所在的垂直网格线 grid-column-end 项目右边框所在的垂直网格线 grid-row-start 项目上边框所在的水平网格线 grid-row-end 项目下边框所在的水平网格线 grid-column grid-column属性是grid-column-start和grid-column-end的合并简写形式 grid-row grid-row属性是grid-row-start属性和grid-row-end的合并简写形式。 grid-area 属性指定项目放在哪一个区域。grid-area属性还可用作grid-row-start、grid-column-start、grid-row-end、grid-column-end的合并简写形式,直接指定项目的位置。 justify-self 设置单元格内容的水平位置 align-self 设置单元格内容的垂直位置 place-self 是 align-self 属性 和 justify-self 属性的合并简写形式,如果省略第二个值,place-self 属性会认为这两个值相等。 # 1、grid-column-start , grid-column-end , grid-row-start , grid-row-end 属性 TIP
我们可以通过指定 gird 项目四个边框分别定位在哪根网格线上,来确定 grid 项目的位置。
属性 说明 grid-column-start 项目左边框所在的垂直网格线 grid-column-end 项目右边框所在的垂直网格线 grid-row-start 项目上边框所在的水平网格线 grid-row-end 项目下边框所在的水平网格线 当项目只指定了以上 4 个属性中的一个,则其它未指定的会采用默认位置,并且一个项目默认只占一个单元格。 项目的默认位置,由 grid-auto-flow 属性决定
如果值为 row,则会 “先行后列” 进行排列 如果值为 column,则会 “先列后行” 进行排列 row dense 表示 “先行后列”,并且尽可能紧密填满,尽量不出现空格。 column dense 表示 "先列后行",并且尽量填满空格 /*
下面代码指定项目的
左边为第2根垂直网格线
右边为第4根垂直网格线
所以项目独跨2列,因为水平网格线没有指定,则会采用默认位置,独占一个单元格。
*/
.grid-item {
grid-column-start: 2;
grid-column-end: 4;
}
案例
.grid-container {
/* 网格布局 */
display: inline-grid;
grid-template: repeat(3, 100px) / repeat(3, 100px);
margin: 100px;
/* 先行后列,并尽量填满不留空隙 */
grid-auto-flow: row dense;
}
.grid-item {
padding: 10px;
font-size: 30px;
color: red;
}
.item {
grid-column-start: 2; /* 列起始网格线 2 */
grid-column-end: 4; /* 列结束网格线 4 */
background-color: pink;
}
grid-auto-flow:row; grid-auto-flow:row dense # 1.1、通过指定第几个网格线来指定项目位置
.grid-container {
/* 网格布局 */
display: inline-grid;
grid-template: repeat(3, 100px) / repeat(3, 100px);
margin: 100px;
}
.grid-item {
padding: 10px;
font-size: 30px;
color: red;
}
.item1 {
grid-column-start: 2;
grid-column-end: 4;
grid-row-start: 2;
grid-row-end: 3;
/* 背景色粉色 */
background-color: pink;
}
.item2 {
grid-column-start: 1;
grid-column-end: 4;
grid-row-start: 1;
/* 背景色天蓝色 */
background-color: skyblue;
}
.item3 {
grid-row-start: 2;
grid-row-end: 4;
/* 背景色黄色 */
background-color: khaki;
}
# 1.2、通过网格线名字来指定项目的位置 TIP
首先需要指定网格线的名字,然后才可以通过网格线名字指定
/* 网格布局 */
display: inline-grid;
grid-template-columns: [a1] 100px [a2] 100px [a3] 100px [a4];
grid-template-rows: [c1] 100px [c2] 100px [c3] 100px [c4];
/* 通过网格线名字来指定 */
grid-column-start: a2;
grid-column-end: a4;
grid-row-start: c2;
grid-row-end: c3;
案例
.grid-container {
/* 网格布局 */
display: inline-grid;
grid-template-columns: [a1] 100px [a2] 100px [a3] 100px [a4];
grid-template-rows: [c1] 100px [c2] 100px [c3] 100px [c4];
margin: 100px;
}
.grid-item {
padding: 10px;
font-size: 30px;
color: red;
}
.item1 {
grid-column-start: a2;
grid-column-end: a4;
grid-row-start: c2;
grid-row-end: c3;
background-color: pink;
}
.item2 {
grid-column-start: a1;
grid-column-end: a4;
grid-row-start: c1;
background-color: skyblue;
}
.item3 {
grid-row-start: c2;
grid-row-end: c4;
background-color: khaki;
}
# 1.3、span 关键字来指定项目跨越几个网格 TIP
前面提到的四个属性的值还可以使用span关键字,表示"跨越",即左右边框(上下边框)之间跨越多少个网格。
语法:
/* 当前项目跨 3行 */
grid-row-start: span 3;
案例
.grid-container {
/* 网格布局 */
display: inline-grid;
grid-template-columns: [a1] 100px [a2] 100px [a3] 100px [a4];
grid-template-rows: [c1] 100px [c2] 100px [c3] 100px [c4];
margin: 100px;
}
.grid-item {
padding: 10px;
font-size: 30px;
color: red;
}
.item1 {
grid-row-start: span 2;
background-color: pink;要
}
.item2 {
background-color: skyblue;
grid-column-start: span 2;
}
.item3 {
background-color: khaki;
grid-row-start: span 2;
grid-column-start: span 2;
}
# 1.4、auto 关键字 TIP
表示属性对网格项目的放置没有任何作用,表示自动放置,自动跨度或默认跨度为 1。
当属性没有设置值时,其默认值就是 auto
grid-column-start: auto;
grid-column-end: 4;
grid-row-start: 1;
grid-row-end: auto;
.grid-container {
/* 网格布局 */
display: inline-grid;
grid-template-columns: repeat(3, 200px);
grid-template-rows: repeat(2, 100px);
margin: 100px;
}
.grid-item {
padding: 10px;
font-size: 18px;
color: red;
}
.item1 {
background-color: pink;
grid-column-start: auto;
grid-column-end: 4;
grid-row-start: 1;
grid-row-end: auto;
}
# 1.5、z-index 属性指定项目的重叠顺序 TIP
如果项目发生重叠,通过 z-index 属性指定项目的重叠顺序。 z-index 的值越大,越在上面。
.grid-container {
/* 网格布局 */
display: inline-grid;
grid-template-columns: [a1] 100px [a2] 100px [a3] 100px [a4];
grid-template-rows: [c1] 100px [c2] 100px [c3] 100px [c4];
margin: 100px;
}
.grid-item {
padding: 10px;
font-size: 30px;
color: red;
}
.item1 {
grid-row-start: 1; /* 起始行网格线 */
grid-row-end: 3; /* 结束行网格线 */
grid-column-start: 1; /* 起始列网格线 */
grid-column-end: 3; /* 结束列网格线 */
background-color: pink;
}
.item2 {
background-color: rgb(135, 206, 235, 0.5);
grid-row-start: 1;
grid-row-end: 3;
grid-column-start: 2;
grid-column-end: 4;
/* 调整重叠的顺序 */
z-index: 3;
}
.item3 {
background-color: khaki;
grid-row-start: 2;
grid-row-end: 4;
grid-column-start: 2;
z-index: 2;
}
# 2、grid-column 、grid-row 属性 TIP
grid-column属性是grid-column-start和grid-column-end的合并简写形式 grid-row属性是grid-row-start属性和grid-row-end的合并简写形式 /*
开始的网格线为第1根垂直网格线
结整的网格线为第3根垂直网格线
等同于
grid-column-start:1;
grid-column-end:3;
*/
grid-column: 1/3;
/*
开始的网格线为第2根水平网格线
开始的网格线为第34根水平网格线
等同于
grid-row-start:2;
grid-row-end:4;
*/
grid-row: 2/4;
/*
开始的网格线为第1根水平网格线
同时跨越3个网格的高度
等同于
grid-row-start:1;
grid-row-end:4;
*/
grid-row: 1 / span 3;
案例
.grid-container {
/* 网格布局 */
display: inline-grid;
grid-template-columns: repeat(3, 100px);
grid-template-rows: repeat(3, 100px);
margin: 100px;
}
.grid-item {
padding: 10px;
font-size: 30px;
color: red;
}
.item1 {
background-color: pink;
grid-row: 1 / span 3;
}
.item2 {
background-color: skyblue;
grid-column: 2 / span 2;
}
.item3 {
background-color: khaki;
grid-column: 2 / span 2;
grid-row: 2 / span 2;
}
# 3、grid-area 属性 TIP
grid-area属性指定项目放在哪一个区域。
这个属性通常配合grid-template-areas属性一起来使用 grid-area属性还可用作grid-row-start、grid-column-start、grid-row-end、grid-column-end的合并简写形式,直接指定项目的位置。 # 3.1、grid-area 第一种用法 TIP
grid-area 属性 配合grid-template-areas属性一起来使用,用来指定项目放在哪一个区域
/* 指定网格区域 */
grid-template-areas:
"a a b"
"a a b"
"c c e";
/* a 表示是区域的名称 */
grid-area: a;
案例
.grid-container {
/* 网格布局 */
display: inline-grid;
grid-template-columns: repeat(3, 100px);
grid-template-rows: repeat(3, 100px);
/* 指定网格区域 */
grid-template-areas:
"a a b"
"a a b"
"c c e";
margin: 100px;
}
.grid-item {
padding: 10px;
font-size: 30px;
color: red;
}
.item1 {
background-color: pink;
grid-area: a; /* 区域a */
}
.item2 {
background-color: skyblue;
grid-area: b; /* 区域a */
}
.item3 {
background-color: khaki;
grid-area: c; /* 区域a */
}
.item4 {
background-color: tomato;
grid-area: e; /* 区域a */
}
# 3.2、grid-area 第二种用法 TIP
grid-area属性还可用作grid-row-start、grid-column-start、grid-row-end、grid-column-end的合并简写形式,直接指定项目的位置。
语法
grid-area:
/*
1:第1根水平网格线
2:第2根垂直网格线
3:第3根水平网格线
4:第4根垂直网格线
*/
grid-area: 1/2/3/4;
案例
.grid-container {
/* 网格布局 */
display: inline-grid;
grid-template-columns: repeat(3, 100px);
grid-template-rows: repeat(3, 100px);
margin: 100px;
}
.grid-item {
padding: 10px;
font-size: 30px;
color: red;
}
.item1 {
background-color: pink;
/*
1:第1根水平网格线
2:第2根垂直网格线
3:第3根水平网格线
4:第4根垂直网格线
*/
grid-area: 1/2/3/4;
}
.item2 {
background-color: skyblue;
}
.item3 {
background-color: khaki;
}
# 3.3、grid-area 的特殊用法(栅格布局) TIP
所谓的栅格布局,你可以简单理解为,要把一个页面或容器(如 div),分成多少份 (通常为 12 份 18 份 或 24 份) 然后设置页面或容器中子元素占对应的份数 以下代码将 grid 容器平均分成 12 列。
.grid-container {
/* 网格布局 */
display: grid;
/* 将容器平均分成12列 */
grid-template-columns: repeat(12, 1fr);
height: 100px;
margin: 10px 0;
}
.grid-item {
padding: 10px;
font-size: 20px;
color: red;
}
.grid-item:nth-child(2n+1) {
background-color: skyblue;
}
.grid-item:nth-child(2n) {
background-color: tomato;
}
.col-1 {
/* 宽为父容器1份宽 */
grid-area: auto/auto/auto/span 1;
}
.col-2 {
/* 宽为父容器2份宽 */
grid-area: auto/auto/auto/span 2;
}
.col-3 {
/* 宽为父容器3份宽 */
grid-area: auto/auto/auto/span 3;
}
.col-4 {
/* 宽为父容器4份宽 */
grid-area: auto/auto/auto/span 4;
}
.col-5 {
/* 宽为父容器5份宽 */
grid-area: auto/auto/auto/span 5;
}
.col-6 {
grid-area: auto/auto/auto/span 6;
}
.col-7 {
grid-area: auto/auto/auto/span 7;
}
.col-8 {
grid-area: auto/auto/auto/span 8;
}
.col-9 {
grid-area: auto/auto/auto/span 9;
}
.col-10 {
grid-area: auto/auto/auto/span 10;
}
.col-11 {
grid-area: auto/auto/auto/span 11;
}
.col-12 {
grid-area: auto/auto/auto/span 12;
}
# 4、justify-self、align-self、place-self 属性 属性名 说明 justify-self 设置单元格内容的水平位置 align-self 设置单元格内容的垂直位置 place-self 是align-self属性和justify-self属性的合并简写形式如果省略第二个值,place-self属性会认为这两个值相等。 justify-self 和 align-self 属性的取值相同,都可以是以下 4 个
属性值 说明 stretch 默认值,拉伸,占满单元格的整宽或高 start (水平居左或垂直居上) end (水平居右或垂直居下) center 水平居中,或垂直居中
.grid-container {
/* 网格布局 */
display: inline-grid;
grid-template-columns: repeat(3, 200px);
grid-template-rows: repeat(2, 100px);
margin: 100px;
}
.grid-item {
padding: 10px;
font-size: 18px;
color: red;
}
.item1 {
background-color: pink;
/* 垂直顶部 */
align-self: start;
}
.item2 {
background-color: skyblue;
/* 垂直居中 */
align-self: center;
}
.item3 {
background-color: khaki;
/* 垂直底部 */
align-self: end;
}
.item4 {
background-color: pink;
/* 水平居左 */
justify-self: start;
}
.item5 {
background-color: skyblue;
/* 水平居中 */
justify-self: center;
}
.item6 {
background-color: khaki;
/* 水平居右 */
justify-self: end;
}
# 四、兼容性查询方法 TIP
深入浅出 兼容性查询方法,了解不同浏览器的私有前缀,以及如何查询 CSS 属性的兼容性。
# 1、不同浏览器的私有前缀 私有前缀 说明 -moz- 火狐等使用 Mozilla 浏览器引擎的浏览器 -webkit- Safari, 谷歌浏览器等使用 Webkit 引擎的浏览器 -o- Opera 浏览器 -ms- IE 浏览器 、Edge 浏览器 对于私有属性的顺序要注意,标准写法要写到最后面,兼容性写法放在前面
私有前缀加在属性名上 /* 兼容性写法 */
-webkit-transform: rotate(-3deg); /* Safari 谷歌 */
-moz-transform: rotate(-3deg); /* 火狐 */
-ms-transform: rotate(-3deg); /* Edge */
-o-transform: rotate(-3deg); /* opera */
/* 标准写法 */
transform: rotate(-3deg);
私有前缀加在属性值上 display: -webkit-flex; /* Safari 谷歌 */
display: -moz-box; /* 火狐 */
display: -ms-flexbox; /* Edge */
display: -webkit-box; /* OLD - iOS 6-, Safari 3.1-6 */
# 2、兼容性查询 TIP
查询不同 CSS 属性的兼容性,可以进入地址:https://caniuse.com/ (opens new window) 👆 查询
# 3、常见需要添加兼容性前缀的属性 TIP
以下为常见的需要加浏览器前缀的 css3 属性和属性值
display: flex/grid:在某些早期版本的浏览器中,可能需要添加-webkit-、-moz-或-ms-前缀以支持 flexbox 或 grid 布局。 box-sizing:虽然现代浏览器普遍支持无前缀的 box-sizing,但早期版本可能需要-webkit-前缀。 border-radius 和 box-shadow:这些属性在早期 WebKit 和 Gecko 内核的浏览器中可能需要添加-webkit-和-moz-前缀。 text-shadow:在某些早期浏览器中,可能需要-webkit-前缀来支持文本阴影效果。 background-size:设置背景图像的尺寸。Webkit 内核的浏览器可能需要添加-webkit-前缀。 linear-gradient 和 radial-gradient :用于创建线性渐变和径向渐变。Webkit 内核和 Gecko 内核的浏览器需要添加对应的前缀。 transition 和 animation:这些属性在支持 CSS 动画和过渡的早期浏览器中可能需要添加-webkit-、-moz-、-o-或-ms-前缀。 transform:用于元素变换的属性,如 rotate、scale、translate 等,也可能需要浏览器前缀。 transform-origin:设置变换的原点。也可能需要添加浏览器前缀。 注意事项
避免过度使用前缀:随着浏览器对标准的支持不断完善,过度使用前缀可能导致样式表变得冗长且难以维护。因此,建议在必要时才添加前缀,并随着浏览器更新的步伐逐渐减少前缀的使用。 使用 Autoprefixer 等工具:这些工具可以自动为 CSS 属性添加必要的前缀,从而减轻手动添加前缀的负担并提高样式的兼容性。 # 五、实战应用 TIP
深入浅出 CSS 网格布局的实战应用,通过案例演示如何使用网格布局实现复杂的页面设计。
# 1、复杂图片展示效果
点击查看完整源代码
.grid-container {
width: 900px;
height: 620px;
display: grid;
/* 创建3行,每行高 200px */
grid-template-rows: repeat(3, 200px);
/* 创建 3列,第1,3列宽为200px,第2列宽自动 */
grid-template-columns: 200px auto 200px;
grid-auto-flow: column; /* 项目排列顺序-先列后行排列 */
gap: 10px 10px; /* 行列间距都为10px */
}
.grid-container .grid-item img {
width: 100%;
height: 100%;
object-fit: cover; /* 等比缩放 正好覆盖容器 */
}
/* 中间大图占据的区域 */
.content {
/* 水平开始网格线 垂直开始网格线 水平结束网格线 垂直结束网格线 */
grid-area: 1/2/4/3; /* 占据的区域 */
}







# 2、复杂图片展示效
点击查看完整源代码
.grid-container {
width: 1000px;
/* height: 620px; */
display: inline-grid;
/* 创建3行,每行高 200px */
grid-template-rows: repeat(3, 80px 200px);
/* 创建 3列,第1,3列宽为200px,第2列宽自动 */
grid-template-columns: 200px auto;
grid-auto-flow: column; /* 项目排列顺序-先列后行排列 */
gap: 0px 20px; /* 行间距为 0px,列间距为 20px */
}
.grid-item.header {
display: flex;
align-items: center;
justify-content: center;
font-size: 30px;
font-weight: bold;
}
.grid-container .grid-item.list {
display: grid;
/*
grid-template-rows: repeat(2, 1fr);
grid-template-columns: repeat(2, 1fr);
*/
/*
使用 minmax(0, 1fr) 替代 1fr,
强制单元格在内容过大时压缩,而不是撑开:
*/
grid-template-rows: repeat(2, minmax(0, 1fr));
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 5px 5px;
}
.grid-container .grid-item img {
width: 100%;
height: 100%;
object-fit: cover;
}
.grid-item.big-img {
/* 水平开始网格线 垂直开始网格线 水平结束网格线 垂直结束网格线 */
grid-area: 1/2/7/3; /* 占据的区域 */
}













# 3、不规则画廊布局
点击查看完整源代码
.grid-container {
width: 820px;
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: 200px 150px 60px 200px;
grid-template-areas:
"a a f"
"c d f"
"b d f"
"b e g";
gap: 10px;
}
.item1 {
grid-area: a;
background-color: red;
}
.item2 {
grid-area: b;
background-color: yellow;
}
.item3 {
grid-area: c;
background-color: green;
}
.item4 {
grid-area: d;
background-color: blue;
}
.item5 {
grid-area: e;
background-color: orange;
}
.item6 {
grid-area: f;
background-color: pink;
}
.item7 {
grid-area: g;
background-color: khaki;
}
.grid-item img {
width: 100%;
height: 100%;
object-fit: cover;
}







# 4、 不规则布局 需要做到,看到以下不规则布局,就了清晰知道其实现原理。不需要一一动手去写。
# 六、专项案例训练(作业) 根据课程进度完成以下针对性案例开发,开发过程要求:
具体开发流程
利用 PS 软件标记好切图 -> 导出至蓝湖(国内企业用的多)中 前端开发人员在蓝湖打开设计稿 ->下载网页开发所需的素材 -> 在蓝湖中量取尺寸 -> 即可开发静态页面 PSD 的源文件设计稿
以下案例对应的 PS 设计稿,已发布到钉钉群作业中。
PS 与蓝湖结合标注、切图开发相关视频教程已上传至钉钉群
作业参考视频
作业参考视频 30 个 HTML+CSS 实战小案例详解 (opens new window)
有任何疑问可以联系添加的助理老师(或博客右侧的晓冉老师)
我们把 CSS/CSS3 基础知识全部学习完之后,会有 3 大项目开发(PC 端,响应式,移动端)会按照企业真实团队协作的方式,用 3 个项目来完整的实践。
切记
学习阶段一定要按照以上的流程学习,提前熟悉工具和整个开发步骤,企业真实项目开发就是这样的流程
# 1、Grid 网格布局(开发 360 图片展示效果)
点击查看完整版视频讲解 # 2、Grid 网格布局(小米商城左侧二级滑动菜单)
点击查看完整版视频讲解