CSS进阶之grid网格布局 (三):关于grid布局、grid-container属性、grid-items属性
跳转目录🚀
篇章 | 知识点 |
---|---|
CSS进阶之形变与动画 (一) | transform、垂直居中总结、transition动画、animation动画、vertical-align |
CSS进阶之预处理语言之less (二) | Easy less插件、认识less、注释、计算方式、嵌套、变量的定义导入less文件、从less导出css样式的路径 |
CSS进阶之grid网格布局 (三) | 关于grid布局、grid-container属性、grid-items属性 |
CSS进阶之移动端适配 (四) | 媒体查询、CSS常见单位、深入理解pixel、DPR、PPI、浏览器视口Viewport、移动端适配rem方案、移动端适配vw方案 |
CSS进阶之额外内容补充 (五) | HTML5新增、CSS函数补充、BFC详解 |
1. 认识 grid 网格布局
1.1 什么是 grid 网格布局
- grid网格布局: 我们把用Grid box网格盒子来进行布局的方案称为grid布局(grid layout)
- 网格容器? 将一个网格盒子划分成"行"和"列",产生了一个个的网格,我们可以将网格元素放在与这些行和列相关的位置上,然后定义这些网格的大小、位置、层次等关系,从而实现二维布局
1.2 grid布局与弹性布局的不同
- 维度上的区别
- flex布局维度: flex布局只是规定弹性项目flex item在轴线上的位置,是
一维布局
- grid布局维度 : grid布局可以把容器划分成"行"和"列",产生单元格,然后指定网格项目grid item所在的单元格,是
二维布局
。Grid 布局比 Flex 布局更强大,但是兼容性较差。
- flex布局维度: flex布局只是规定弹性项目flex item在轴线上的位置,是
- 兼容性上的区别
- flex布局的兼容性:
- grid布局的兼容性:
- flex布局的兼容性:
- 布局上的区别:
-
flex布局:
-
grid布局:
2. grid网格布局的理解
2.1 grid布局的重要概念
- 容器和项目:在进行grid布局,我们都先需要先给父级盒子(容器)设置上
display:grid
成为网格容器
,容器的所有顶层子元素称为项目
,这个概念在flex也是适用的。 - display:grid;与display:inline-grid
grid
:指明该容器本身是块级元素,块级元素独占一行。inline-grid
:指明该容器本身是一个行内元素,行内元素可以和其他行内元素共占一行。
- 注意:container是一个网格容器,item为网格元素。而grandson却不是网格元素,所以父容器只能影响儿子容器
2.2 grid布局的模型
- 网格线 grid line:
- 划分网格的线,称为"网格线。网格线会被编号帮我们定位每一个网格项目。
- 如果有m列则有m+1根垂直网格线,有n行则有n+1根水平网格线
- 编号从左到右,从上到下为1,2,3排列;也有从右到左,从下到上的-1,-2,-3排列
- 网格单位 grid cell:网格容器里面一个个网格项目元素就是网格单位,一个网格单元是在一个网格元素中最小的单位,就像表格的单元格一样。如图中的1,2,3,4,5……9的格子
- 网格轨道 grid track:
grid-template-columns
和grid-template-rows
属性就是来定义网格中的行和列。一个网格轨道就是网格中两条平行线之间的空间,就好比表格中行或列 - 网格区域 grid area:多个网格线包围的总空间。网格区域可以包含任意数量的网格单元。
2.3 开启网格布局
- 指定一个容器采用网格布局:
display: grid | inline-grid | subgrid
- grid:生成一个块级(block-level)网格容器
- ** inline-grid**:生成一个行级(inline-level)网格容器、
- subgrid:如果你的 grid container 本身就是一个 grid item(即,嵌套网格),你可以使用这个属性来表示你想从它的父节点获取它的行/列的大小,而不是指定它自己的大小。
3. grid-container属性
3.1 grid-template-columns/rows 网络轨道的宽高(列宽和行高)
grid-template-columns
:定义每一列的列宽grid-template-rows
:定义每一行的行高
-
如何定义行列:
- 直接定义行列数、列宽行高:
/* 定义了三列 每一行50px */grid-template-columns: 50px 50px 50px;/* 定义了三行 每一行50px */grid-template-rows: 50px 50px 50px;
- 定义网格线的名称(按需求而定):大小前面使用数组可以定义网格线的名称,可以有很多个名称,多个名称用空格隔开。
/* 定义了三列 每一行50px */grid-template-columns: [column1] 50px [column2]50px [column3]50px [column-end];/* 定义了三行 每一行50px */grid-template-rows: [row1]50px [row3]50px [row3]50px [row-end];
3.1.1 取值类型拓展:百分比、fr单位、repeat()函数、auto-fill 关键字、minmax() 函数、auto 关键字
- 百分比:是比较常用的单位,参照与容器的大小
- fr单位:Grid 布局引入了一个另外的长度单位来帮助我们创建灵活的网格轨道,
fr关键字代表网格容器中可用空间的一等份
。下面例子中表示容器分成4份,第一列和第二列各占一份空间,第三列占两份空间。 - repeat()函数:该函数接收
两个参数
,第一个参数为重复次数
,第二个参数为需要重复的值
,使用repeat函数可以简化重复的值, - auto-fill 关键字:单元格大小固定但容器大小不确定时,可以使用
auto-fill关键字
进行自动填充
,让一行或者一列尽可能多的容纳单元格
,常搭配repeat()函数中使用
。 - minmax()函数:minmax()函数产生一个
长度范围
,接收两个参数
,第一个参数为最小值
,第二个为最大值
。 - auto关键字:auto关键字表示由浏览器自己决定长度,下面代码中第一列为容器的30%宽,第二列是50px,第三轮由浏览器自适应。
grid-template-columns: 25% 25% 25% 25%;
grid-template-columns: 1fr 1fr 2fr;
grid-template-columns: repeat(5, 1fr);//第一个参数可以是具体值也可以是auto-fill关键字,后面可以写绝对单位,百分比,fr,minmax()函数
grid-template-columns: repeat(auto-fill, 100px);
grid-template-columns: 200px 20% minmax(100px,1fr);
grid-template-columns: 200px auto 200px;
grid-template-columns: repeat(3, 50px [col-start]);//携带网格线名字
grid-template-columns: repeat(2, 100px 20px 80px);//重复某种模式
grid-template-columns: 30% 50px auto;
3.2 row-gap,column-gap,gap 网格间距(行间距和列间距)
注意 :根据最新标准,grid-row-gap、grid-column-gap、grid-gap三个属性名的grid-前缀已经删除,现在可以写为row-gap、column-gap、gap
- column-gap:设置网格的列间距
- row-gap:设置网格的行间距
- gap:两个属性的简写属性 当有两个值时分别表示 行间距row-gap,列间距column-gap;一个值表示同时设置行列间距
.box {/* grid布局 */display: grid;/* 设置列数 */grid-template-columns: repeat(4, 1fr);grid-auto-rows: minmax(100px, 1fr);/* 设置网格间距 *//* 行间距 */row-gap: 20px;/* 列间距 */column-gap: 10px;/* 简写属性 */gap: 30px 50px;/* 容器 */width: 1000px;/* height: 500px; */margin: 100px auto;/* grid-gap是grid-row-gap和grid-column-gap的综合写法,但是此类设置不推荐使用 *//* grid-row-gap: 10px;grid-column-gap: 10px;grid-gap: 10px; *//* row-gap: 10px;column-gap: 10px; *//* gap: 行间距 列间距; 如果取值一致就设置一个值*/}
3.3 grid-template-areas和grid-area 网格合并
- grid-template-areas:该属性一般与grid-area一起使用,
grid-template-areas
属性在容器上
制定各个区域并命名 - grid-area:
grid-area
属性指定项目
放在哪一个区域内。
.box {/* 开启了grid布局 */display: grid;/* 设置列数 */grid-template-columns: repeat(4,1fr);/* 设置行数 */grid-template-rows: repeat(2,1fr);grid-template-areas: "a1 a1 a2 a2""a1 a1 a3 a4";gap: 10px;width: 1008px;height: 210px;border: 3px solid #333;margin: 0 auto;}.box div:nth-child(1) {grid-area: a1;background-color: #305496;}.box div:nth-child(2) {grid-area: a2;background-color: #f4b084;}.box div:nth-child(3) {grid-area: a3;background-color: #70ad47;}.box div:nth-child(4) {grid-area: a4;background-color: #ffff00;}
3.3 grid-template 简写属性
- grid-template:grid-template-columns属性,grid-template-rows属性 和 grid-template-areas属性的简写;
.box {width: 1000px;margin: 0 auto;display: grid;/* grid-template-columns: repeat(4, 1fr);grid-template-rows: repeat(2, 100px);grid-template-areas:"a1 a1 a2 a2""a1 a1 a3 a4";*//* 综合写法 */grid-template:"a1 a1 a2 a2" 100px"a1 a1 a3 a4" 100px/ 1fr 1fr 1fr 1fr;}
3.4 grid-auto-flow 网格排列顺序
- grid-auto-flow:该属性决定容器中的项目按照什么顺序排列,
默认值为row
,即先行后列
,先填满第一行,再开始放入第二行- 默认值为 row
- 值为column:
- 默认值为 row
- 当r单独设置了item后所占空间被排列到下一行或列而产生多余空间,可以使用
row dense/column dense
,表示尽可能填满表格-
以grid-auto-flow:column;为例
-
值修改为
column dense
,如果是row同理改为row dense
.box {/* grid布局 */display: grid;/* 设置列数 */grid-template-rows: repeat(4, minmax(100px, 1fr));grid-auto-columns: minmax(100px, 1fr);/*网格排列顺序 *//* 默认值 *//* grid-auto-flow: column; */grid-auto-flow: column dense;/* 设置网格间距 *//* 行间距 */row-gap: 20px;/* 列间距 */column-gap: 10px;/* 简写属性 *//* gap: 30px 50px; *//* 容器 */width: 1000px;/* height: 500px; */margin: 100px auto;}.three {grid-row: 2/span 2;}
-
3.5 .justify-items&align-items&place-items网格内容对齐方式
3.5.1 justify-items 水平对齐
- justify-items:该属性设置单元格内容左中右的水平位置
- 取值的区别
-
stretch(默认值):拉伸,占满整个单元格的宽度
-
start: 对齐单元格的起始边缘
-
end:对齐单元格的结束边缘
-
center:单元格内部居中
-
3.5.2 align-items 垂直对齐
- align-items:该属性设置单元格内容上中下的垂直位置
- 取值的区别:align-items为垂直方向,效果同理只是改为垂直方向,此处不再赘述
.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;
}
3.5.3 place-items 简写属性
- place-items:前两个属性合在一起的简写属性,当有两个值时表示分别设置 align-items 和 justify-items 属性;如果有一个值,则同时设置两个属性。
3.6 justify-content&align-content&place-content 内容区域在容器中的对齐方式
3.6.1 justify-content 水平对齐
- justify-content:该属性是整个内容区域在容器里左中右的水平位置
- 取值的区别:
-
start:对齐容器的起始边框
-
end:对齐容器的结束边框
-
center:容器的内部居中
-
space-around:每个项目的两侧间隔相等,项目之间的间隔比项目与容器边框的间隔大一倍
-
space-between:项目之间的间隔相等,项目与容器边框之间没有间隔
-
space-evenly:项目与项目的间隔相等,项目与容器边框之间也是同样长度的间隔
-
3.6.2 align-content 垂直对齐
- align-content:该属性是整个内容区域在容器里上中下的垂直位置位置
- 取值的区别: align-content为垂直方向,效果同理只是改为垂直方向,此处不再赘述
3.6.3 place-content 简写属性
- place-content:前两个属性合在一起的简写属性,当有两个值时表示分别设置 align-content和 justify-content属性;如果有一个值,则同时设置两个属性。
3.7 grid-auto-columns&grid-auto-rows 隐式网格轨道的宽高(列宽和行高)
注意:在讲 grid-auto-columns 属性和 grid-auto-rows 属性之前,先来看看隐式和显示
网格的概念
- 显示网格:
- 显式网格就是你在
grid-template-columns 和 grid-template-rows 属性中定义的行和列。
显式网格的行高和列宽
可以根据grid-template-columns 和 grid-template-rows属性设置
- 显式网格就是你在
- 隐式网格:
- 如果你在网格定义之外又放了一些东西,或者因为
内容的数量而需要的更多网格轨道
的时候,网格将会在隐式网格中创建行和列
. 隐式网格的行高和列宽
可以根据 grid-auto-columns 属性和 grid-auto-rows 属性设置。- 如果
不指定这两个属性
,浏览器完全根据单元格内容的大小
,决定新增网格的列宽和行高
- 如果你在网格定义之外又放了一些东西,或者因为
- grid-auto-columns&grid-auto-rows的取值:具体值或minmax()函数等
.wrapper {display: grid;grid-template-columns: 200px 100px;grid-template-rows: 100px 100px;grid-gap: 10px 20px;grid-auto-rows: 50px;
}
-
小米案例Grid布局练习
* {margin: 0;padding: 0;}a {text-decoration: none;}ul,li {list-style: none;}.w {width: 1226px;margin: 0 auto;}.banner {height: 460px;background: url(./uploads/banner01.webp) no-repeat center center;background-size: 1226px 460px;margin-top: 100px;}.banner .prolist {position: relative;box-sizing: border-box;width: 234px;height: 100%;padding: 20px 0;background-color: #9b9997;}/* .banner .prolist li {} */.banner .prolist li .proitem {padding-left: 30px;display: grid;grid-auto-flow: column;grid-template-columns: 1fr auto;box-sizing: border-box;height: 42px;line-height: 42px;color: #fff;font-size: 14px;}.banner .prolist li a i {padding-right: 20px;}.banner .prolist li .proitem:hover {background-color: #ff6700;}/* 细节展示 */.banner .prolist li .detail {display: none;position: absolute;top: 0;left: 234px;/* width: 100px; */height: 460px;background-color: skyblue;border: 1px solid #e0e0e0;box-shadow: 0 8px 16px rgba(0, 0, 0, .18);}.banner .prolist li .detail ul {display: inline-grid;/* 给定列数行数,默认先行后列 *//* grid-template-columns: repeat(3, 1fr); */grid-template-rows: repeat(6, 1fr);/* 我们不知道有多少item需要设置另外属性 */grid-auto-columns: 265px;/* 改变展示的方向 colum先列后行 */grid-auto-flow: column;/* width: 1000px; */background-color: rgb(255, 255, 255);padding-top: 4px;}.banner .prolist li .detail ul li a {display: grid;width: 265px;height: 76px;grid-template-columns: 40px 1fr;grid-template-rows: 1fr;align-items: center;justify-items: start;column-gap: 12px;color: #333;font-size: 14px;padding-left: 20px;/* background-color: aquamarine; */}.banner .prolist li .detail ul li .propic {width: 40px;height: 40px;}.banner .prolist li .detail ul li .propic img {height: 100%;}.banner .prolist li .detail ul li .protitle:hover {color: #ff6700;}/* 鼠标悬浮出现效果 */.banner .prolist li:nth-child(1):hover .detail {display: block;}.banner .prolist li:nth-child(2):hover .detail {display: block;}
<div class="w banner"><!-- 商品分类列表 --><ul class="prolist"><!-- 手机 --><li><a class="proitem" href="#">手机<i class="iconfont icon-arrow-right-bold"></i></a><!-- 展示列 --><div class="detail"><ul><li><a class="goodsitem" href="#"><div class="propic"><img src="./uploads/p1.webp" alt=""></div><p class="protitle">Xiaomi MIX系列</p></a></li><li><a class="goodsitem" href="#"><div class="propic"><img src="./uploads/p2.webp" alt=""></div><p class="protitle">Xiaomi 数字系列</p></a></li><li><a class="goodsitem" href="#"><div class="propic"><img src="./uploads/p3.webp" alt=""></div><p class="protitle">Xiaomi Civi系列</p></a></li><li><a class="goodsitem" href="#"><div class="propic"><img src="./uploads/p4.webp" alt=""></div><p class="protitle">Xiaomi 青春系列</p></a></li><li><a class="goodsitem" href="#"><div class="propic"><img src="./uploads/p5.webp" alt=""></div><p class="protitle">Xiaomi K系列</p></a></li><li><a class="goodsitem" href="#"><div class="propic"><img src="./uploads/p6.webp" alt=""></div><p class="protitle">Xiaomi Note系列</p></a></li><li><a class="goodsitem" href="#"><div class="propic"><img src="./uploads/p7.webp" alt=""></div><p class="protitle">Redmi 数字系列</p></a></li></ul></div></li><!-- 电视 --><li><a class="proitem" href="#">电视<i class="iconfont icon-arrow-right-bold"></i></a><div class="detail "><ul><li><a class="goodsitem" href="#"><div class="propic"><img src="./uploads/t1.webp" alt=""></div><p class="protitle">小米电视6 55" OLED</p></a></li><li><a class="goodsitem" href="#"><div class="propic"><img src="./uploads/t2.webp" alt=""></div><p class="protitle">Redmi X65</p></a></li><li><a class="goodsitem" href="#"><div class="propic"><img src="./uploads/t3.webp" alt=""></div><p class="protitle">Redmi X55</p></a></li><li><a class="goodsitem" href="#"><div class="propic"><img src="./uploads/t4.webp" alt=""></div><p class="protitle">小米电视6 65" OLED</p></a></li><li><a class="goodsitem" href="#"><div class="propic"><img src="./uploads/t5.webp" alt=""></div><p class="protitle">小米电视 大师 77" OLED</p></a></li><li><a class="goodsitem" href="#"><div class="propic"><img src="./uploads/t6.webp" alt=""></div><p class="protitle">小米电视6 至尊版 55英寸</p></a></li><li><a class="goodsitem" href="#"><div class="propic"><img src="./uploads/t7.webp" alt=""></div><p class="protitle">小米电视6 至尊版 65英寸</p></a></li><li><a class="goodsitem" href="#"><div class="propic"><img src="./uploads/t8.webp" alt=""></div><p class="protitle">小米电视 ES43</p></a></li><li><a class="goodsitem" href="#"><div class="propic"><img src="./uploads/t9.webp" alt=""></div><p class="protitle">小米电视 ES55</p></a></li><li><a class="goodsitem" href="#"><div class="propic"><img src="./uploads/t10.webp" alt=""></div><p class="protitle">小米电视 ES65</p></a></li><li><a class="goodsitem" href="#"><div class="propic"><img src="./uploads/t11.webp" alt=""></div><p class="protitle">小米电视 ES75</p></a></li><li><a class="goodsitem" href="#"><div class="propic"><img src="./uploads/t12.webp" alt=""></div><p class="protitle">大师电视 65英寸 OLED</p></a></li><li><a class="goodsitem" href="#"><div class="propic"><img src="./uploads/t13.webp" alt=""></div><p class="protitle">Redmi 智能电视 MAX 98"</p></a></li><li><a class="goodsitem" href="#"><div class="propic"><img src="./uploads/t8.webp" alt=""></div><p class="protitle">小米电视大师86英寸Mini LED</p></a></li></ul></div></li><!-- 家电 --><li><a class="proitem" href="#">家电<i class="iconfont icon-arrow-right-bold"></i></a></li><!-- 笔记本 平板 --><li><a class="proitem" href="#">笔记本 平板<i class="iconfont icon-arrow-right-bold"></i></a></li><!-- 出行 穿戴 --><li><a class="proitem" href="#">出行 穿戴<i class="iconfont icon-arrow-right-bold"></i></a></li><!-- 耳机 音箱 --><li><a class="proitem" href="#">耳机 音箱<i class="iconfont icon-arrow-right-bold"></i></a></li><!-- 健康 儿童 --><li><a class="proitem" href="#">健康 儿童<i class="iconfont icon-arrow-right-bold"></i></a></li><!-- 生活 箱包 --><li><a class="proitem" href="#">生活 箱包<i class="iconfont icon-arrow-right-bold"></i></a></li><!-- 智能 路由器 --><li><a class="proitem" href="#">智能 路由器<i class="iconfont icon-arrow-right-bold"></i></a></li><!-- 电源 配件 --><li><a class="proitem" href="#">电源 配件<i class="iconfont icon-arrow-right-bold"></i></a></li></ul></div>
4. grid-items属性
4.1 grid-row-start&grid-column-start&grid-row-end&grid-column-end 基于网格线布局
-
各属性的作用与含义
- grid-row-start:该属性表示上边框所在的水平网格线
- grid-column-start:该属性表示左边框所在的垂直网格线
- grid-row-end:该属性表示下边框所在的水平网格线
- grid-column-end:该属性表示右边框所在的垂直网格线
-
如何进行网格线布局:
- 数字写法:我们可以通过网格线的序号对网格进行布局,使用上面四个属性设置对应子项所占据区域起始和终止位置,包括水平方向(列方向)和垂直方向(行方向)
.box div:nth-child(1) {background-color: pink;/* 列方向摆放位置从第2条列线开始到第3条列线结束位置摆放 */grid-column-start: 2;grid-column-end: 3;/* 行方向摆放位置从第2条行线开始到第3条行线结束位置摆放 */grid-row-start: 2;grid-row-end: 3;}
- 如果只设置了grid-column-start和grid-column-end不设置grid-row-start和grid-row-end,此时默认的取值是auto,其他子项会依次让后排列;
如果都设置了,后面子项会自动补全空缺进行布局。
.box div:nth-child(1) {background-color: pink;/* 列方向摆放位置从第2条列线开始到第3条列线结束位置摆放 */grid-column-start: 2;grid-column-end: 3;/* 行方向摆放位置从第2条行线开始到第3条行线结束位置摆放 *//* grid-row-start: 2;grid-row-end: 3; */}.box div:nth-child(2) {background-color: red;}
- span关键字网格跨越数量:网格项将跨越指定数量的网格轨道
.item2 {grid-column-start: span 2;}
注意:使用这四个属性如果产生了重叠,则可以使用z-index指定项目的重叠顺序
4.2 grid-column&grid-rows 简写属性
- grid-column:是grid-column-start和grid-column-end合并简写
- grid-rows:是grid-row-start和grid-row-end合并简写
.item2 {grid-column-start: 2;grid-column-end: 4;grid-row-start:1;grid-row-end:3;}等同于.item2 {grid-column: 2 / 4;grid-row:1 / 3;}等同于.item2 {grid-column: 2 / span 2;grid-row:1 / span 2;}
4.3 grid-area 作为简写属性用法
- grid-area:
grid-area
属性是grid-row-start,grid-column-start,grid-row-end,grid-column-end的缩写,顺序不能更改;- 上本提及过的:支持grid-template-areas设置网格名称;
/*grid-area: grid-row-start / grid-column-start / grid-row-end / grid-column-end;*/
/* grid-column-start: 2;grid-column-end: 3;grid-row-start: 2;grid-row-end: 3;
*/
grid-area: 2 / 2 / 3 / 3;
4.4 justify-self&align-self( 单元格内容水平垂直对齐方式
- justify-self:该属性设置单元格内容左中右的水平位置,跟 justify-items 属性的
用法完全一致
,但只作用于单个项目
- align-self:该属性设置单元格内容上中下的垂直位置,align-items属性的
用法完全一致
,也是只作用于单个项目
justify-self:start | end | center | stretch;align-self:start | end | center | stretch;