这是我参与11月更文挑战的第二天,活动详情请查看:2021最后一次更文挑战
前言
对上一篇发表的flex布局和grid布局详解 的继续补充。 在项目开始之前在继续说一下,容器相当于一个盒子外面的包装,项目是具体的内容,就是大箱子里面套用小箱子,大箱子就是容器,小箱子就是项目
基本概念
Grid 网格布局,将网页划分为一个个网格,可以任意组合不同的网格,对项目进行不同的排列顺序,flex是一维布局,只能针对项目的轴线设置项目放置的相对位置,而grid布局是将容器划分成行和列,产生的单元格,然后指定项目所在的位置,可以把它看成是一个二维布局。
<div class="container" >
<div class="box"><p>11</p></div>
## <div class="box"><span>11</span></div>
<div class="box"><h6>11</h6></div>
</div>
理解: 最外层的<div>元素就是容器,内层的三个<div>元素就是项目。项目只能是容器的顶层子元素,不包含项目的子元素,比如上面代码的<p>、<span>、<h6>元素就不是项目。
在开始之前,先弄明白一下含义
行和列
前面说过,grid 布局是在设置行和列来设置项目所在容器中的位置和大小。容器里面的水平区域称为"行"(row),垂直区域称为"列"(column)。
网格线
顾名思义,划分网格得线,水平网格线划分出行,垂直网格线划分出列。
容器的属性
grid-template-columns/rows:
grid-template-columns 和 grid-template-rows:分别设置属性的列宽和行高 补充:
display: grid;--声明一个容器
grid-template-columns: repeat(auto-fill,500px); --宽度为500px,在一行内排列下的情况下,自动进行排列(尽可能多的排练)。
grid-template-columns: 300px 100px 200px;---设置3列,第一列列宽为300px,第二列宽为100px;第三列列宽为200px;
grid-template-columns:
repeat(3,500px) == grid-template-columns: 500px 500px 500px;
grid-template-columns: 300px 1fr 2fr;---设置3列,第一列的值为300px,第二列和第三列的值分别占据剩余空间的1/3和2/3的宽度;
grid-template-columns: 1fr 1fr minmax(300px,2fr)—前俩列均分,第三列的最大值300px最小值为前俩列的2倍;
grid-template-columns: 300px auto 300px;---第一列和第三列的宽为300px,中间一列的宽为更具浏览器的大小,自动取合适的大小。
例如:
- grid-template-columns: repeat(3,200px);
<style>
.container{
width: 50%;
display: grid;
background-color: antiquewhite;
box-shadow: 0px 2px 2px 0px rgba(9, 2, 4, 0.1);
}
.box{
width: 100px;
height: 100px;
margin: 15px;
background-color: coral;
}
</style>
<!--设置一行有3列,且每个项目的宽度为200px-->
<h3>grid-template-columns: repeat(3,200px);</h3>
<div class="container" style="grid-template-columns: repeat(3,200px);">
<div class="box">11</div>
<div class="box">22</div>
<div class="box">33</div>
<div class="box">44</div>
</div>
<!--和上面的代码等价-->
<h3>grid-template-columns: 200px 200px 200px;</h3>
<div class="container" style="grid-template-columns: 200px 200px 200px;">
<div class="box">11</div>
<div class="box">22</div>
<div class="box">33</div>
<div class="box">44</div>
</div>
- grid-template-columns: repeat(auto-fill,200px);
<!--在容器中能排列下的情况下京可能的多排列,每个项目的宽度为200px-->
<h3>grid-template-columns: repeat(auto-fill,200px);</h3>
<div class="container" style="grid-template-columns: repeat(auto-fill,200px);">
<div class="box">11</div>
<div class="box">22</div>
<div class="box">33</div>
<div class="box">44</div>
<div class="box">55</div>
<div class="box">66</div>
<div class="box">77</div>
</div>
当屏幕为1100 * 937时这显示俩列,当为1980 * 1060 时显示4列
- grid-template-columns: 100px 1fr 2fr
<!--获取3列,项目的第一列的宽度为100px,将剩余空间分成3等分,第二列宽度为1/3的宽,第三列的宽度为2/3的宽-->
<h3>grid-template-columns: 100px 1fr 2fr</h3>
<div class="container" style="height:100px;grid-template-columns: 100px 1fr 2fr;">
<div style="background-color: coral">11</div>
<div style="background-color: #1b9ed9">22</div>
<div style="background-color: #f350ff">33</div>
</div>
不管屏幕多大,第一列的宽度都为100px,后俩列的宽度分别占1/3和2/3的宽度
- grid-template-columns: 1fr 1fr minmax(300px,2fr)
<!--将容器的宽度分为4份,第一列和第二列宽度为1/4,第三列的宽度为最小为300px,最大占2/4的宽度-->
<h3>grid-template-columns: 1fr 1fr minmax(300px,2fr)</h3>
<div class="container" style="height:100px;grid-template-columns: 1fr 1fr minmax(300px,2fr);">
<div style="background-color: coral">11</div>
<div style="background-color: #1b9ed9">22</div>
<div style="background-color: #f350ff">33</div>
</div>
-grid-template-columns: 100px auto 100px
<!--获取3列,第一列和第三列的宽度为固定值100px,第二列更具屏幕的大小自动计算宽度-->
<h3>grid-template-columns: 100px auto 100px</h3>
<div class="container" style="height:100px;grid-template-columns: 100px auto 100px">
<div style="background-color: coral">11</div>
<div style="background-color: #1b9ed9">22</div>
<div style="background-color: #f350ff">33</div>
</div>
第二部分蓝色区域,当屏幕为1980 * 1060时明显比屏幕为703 * 937 时宽了许多
grid-gap:10px
设置行间隙和列间隙;grid-gap:10px ==grid-row-gap:10px;和grid-column-gap:10px;
<p><strong>设置的间距之对于当前的行列的内部有效</strong></p>
<h3>grid-gap: 20px;</h3>
<div class="container" style="grid-gap: 20px;">
<div class="box">11</div>
<div class="box">22</div>
<div class="box">33</div>
<div class="box">44</div>
</div>
<h3>grid-column-gap: 20px;grid-row-gap: 20px;</h3>
<div class="container" style="grid-column-gap: 20px;grid-row-gap: 20px;">
<div class="box">11</div>
<div class="box">22</div>
<div class="box">33</div>
<div class="box">44</div>
</div>
grid-template-areas
定义区域,一个区域有一个或者多个单元格组成,一般和网格元素的grid-area一起配合使用;
<style>
.container{
width: 50%;
display: grid;
grid-gap: 10px;
grid-template-columns: 120px 120px 120px;
grid-template-areas:
". header header "
"sidebar content content"
"footer footer footer";
/*划分9个单元格,. (点)代表这个区域没有用到*/
background-color: antiquewhite;
color: #444;
}
.sidebar {
grid-area: sidebar;
}
.footer{
grid-area: footer;
}
.content {
grid-area: content;
}
.header {
grid-area: header;
}
.box {
background-color: #1b9ed9;
color: #fff;
border-radius: 5px;
padding: 20px;
font-size: 150%;
}
</style>
<div class="container">
<div class=" box sidebar">sidebar</div>
<div class=" box content">content</div>
<div class=" box footer">footer</div>
<div class=" box header">header</div>
</div>
通过grid-template-areas来指定class的样式的位置,就可以轻松的实现布局,将项目放置在那个位置
grid-auto-flow
自动布局算法,在一行内能排列下的情况下,依照先行后列(默认)的原则依次布局排列。也可以设置先列后行的写法,即:grid-auto-flow: column
- grid-auto-flow: row
<style>
.container{
width: 50%;
display: grid;
grid-template-columns: repeat(auto-fill,150px);
background-color: antiquewhite;
box-shadow: 0px 2px 2px 0px rgba(9, 2, 4, 0.1);
}
.container1{
width: 50%;
display: grid;
grid-template-columns: repeat(auto-fill,300px);
background-color: antiquewhite;
box-shadow: 0px 2px 2px 0px rgba(9, 2, 4, 0.1);
}
.box{
width: 100px;
height: 100px;
margin: 15px;
background-color: coral;
}
</style>
<h3>grid-auto-flow: row;</h3>
<div class="container" style="grid-auto-flow: row;">
<div class="box">11</div>
<div class="box">22</div>
<div class="box">33</div>
<div class="box">44</div>
<div class="box">55</div>
<div class="box">66</div>
<div class="box">77</div>
<div class="box">88</div>
</div>
- grid-auto-flow: row dense; 设置某些项目指定位置之后,其他项目的怎么自动放置。
<h3>grid-auto-flow: row dense;</h3>
<!--设置了grid-auto-flow: row dense; dense 这个属性值之后就会让其容器内尽可能的多排练一些内容,而不会很大的空隙-->
<div class="container1" style="grid-auto-flow: row dense;">
<div class="box">11</div>
<div style="height: 100px;width: 200px;margin:10px;background-color: aqua">22</div>
<div class="box">33</div>
<div style="height: 100px;width: 150px;margin:10px;background-color: brown">44</div>
<div class="box">55</div>
<div class="box">66</div>
<div class="box">77</div>
<div class="box">88</div>
</div>
justify-items、align-items
justify-items 设置单元格(项目)内容的水平(左中右)位置;align-items设置单元格(项目)内容的垂直(上中下)位置;place-items = align-items +justify-items
这俩个属性的写法完全相同,有4个属性值:
start:对齐单元格的起始边缘。
end:对齐单元格的结束边缘。
center:单元格内部居中。
stretch:拉伸,占满单元格的整个宽度(默认值)。
<style>
.container{
width: 50%;
display: grid;
background-color: antiquewhite;
box-shadow: 0px 2px 2px 0px rgba(9, 2, 4, 0.1);
grid-template-columns: repeat(auto-fill,200px);
grid-template-rows: repeat(3,100px);
grid-gap: 15px;
}
.box{
width: 100px;
height: 100px;
background-color: coral;
}
</style>
- justify-items: start
<!--当前项目在单元格中的水平位置-->
<h3>justify-items: start</h3>
<div class="container" style="justify-items: start">
<div class="box">11</div>
<div class="box">22</div>
<div class="box">33</div>
<div class="box">44</div>
<div class="box">55</div>
</div>
- justify-items: center
<h3>justify-items: center</h3>
<div class="container" style="justify-items: center">
<div class="box">11</div>
<div class="box">22</div>
<div class="box">33</div>
<div class="box">44</div>
<div class="box">55</div>
</div>
当前项目在单元格中的位置为水平居中,如下图
- align-items: start
<style>
.container{
width: 50%;
display: grid;
background-color: antiquewhite;
box-shadow: 0px 2px 2px 0px rgba(9, 2, 4, 0.1);
grid-template-columns: repeat(auto-fill,200px);
grid-template-rows: repeat(3,150px);
grid-gap: 15px;
}
.box{
width: 100px;
height: 100px;
background-color: coral;
}
</style>
<h3>align-items: start</h3>
<!--项目在单元格中的垂直位置-->
<div class="container" style="align-items: start">
<div class="box">11</div>
<div class="box">22</div>
<div class="box">33</div>
<div class="box">44</div>
<div class="box">55</div>
</div>
- align-items: center
<h3>align-items: center</h3>
<div class="container" style="align-items: center">
<div class="box">11</div>
<div class="box">22</div>
<div class="box">33</div>
<div class="box">44</div>
<div class="box">55</div>
</div>
当前项目在单元格中的位置为垂直居中,如下图
-
place-items: start end;
place-items:<align-items> <justify-items>
<style>
.container{
width: 50%;
display: grid;
background-color: antiquewhite;
box-shadow: 0px 2px 2px 0px rgba(9, 2, 4, 0.1);
grid-template-columns: repeat(auto-fill,200px);
grid-template-rows: repeat(3,200px);
grid-gap: 15px;
}
.box{
width: 100px;
height: 100px;
background-color: coral;
}
</style>
<h3>place-items: start end-- 在单元格内,box的位置在右上角</h3>
<div class="container" style="place-items: start end">
<div class="box">11</div>
<div class="box">22</div>
<div class="box">33</div>
<div class="box">44</div>
<div class="box">55</div>
</div>
理解:(上图) 垂直对齐方式为顶端对齐,水平方式尾端对齐--所以,所有的盒子相对于单元格来说位置在右上角。
- place-items: center center
<h3>place-items: center center-- 在单元格内,box的位置在中间(上下左右间距相等 )</h3>
<div class="container" style="place-items: center center">
<div class="box">11</div>
<div class="box">22</div>
<div class="box">33</div>
<div class="box">44</div>
<div class="box">55</div>
</div>
justify-content、align-content
justify-content整个内容区域在容器里面的水平位置(左中右);align-content 整个内容区域的垂直位置(上中下)。place-content = align-content +justify-content
上面俩个属性的值都可以取下面的值:
start:对齐容器的起始边框。
end:对齐容器的结束边框。
center:容器内部居中。
stretch:项目大小没有指定时,拉伸占据整个网格容器。
space-around:每个项目两侧的间隔相等。所以,项目之间的间隔比项目与容器边框的间隔大一倍
space-between:项目与项目的间隔相等,项目与容器边框之间没有间隔。
space-evenly:项目与项目的间隔相等,项目与容器边框之间也是同样长度的间隔。
<style>
.container{
width: 50%;
display: grid;
background-color: antiquewhite;
box-shadow: 0px 2px 2px 0px rgba(9, 2, 4, 0.1);
grid-template-columns: repeat(auto-fill,200px);
grid-template-rows: repeat(3,150px);
grid-gap: 10px;
}
.box{
background-color: coral;
}
.box1{
width: 100px;
height: 100px;
background-color: coral;
}
</style>
- justify-content: start
<h3>justify-content: start</h3>
<div class="container" style="justify-content: start">
<div class="box">11</div>
<div class="box">22</div>
<div class="box">33</div>
<div class="box">44</div>
<div class="box">55</div>
</div>
- justify-content: center
<h3>justify-content: center</h3>
<div class="container" style="justify-content: center">
<div class="box">11</div>
<div class="box">22</div>
<div class="box">33</div>
<div class="box">44</div>
<div class="box">55</div>
</div>
- align-content: center
<style>
.container{
height: 500px;
display: grid;
background-color: antiquewhite;
box-shadow: 0px 2px 2px 0px rgba(9, 2, 4, 0.1);
grid-template-columns: repeat(auto-fill,200px);
grid-gap: 10px;
}
.box{
height: 100px;
width: 100px;
background-color: coral;
}
</style>
<h3>align-content: center</h3>
<div class="container" style="align-content: center">
<div class="box">11</div>
<div class="box">22</div>
<div class="box">33</div>
<div class="box">44</div>
<div class="box">55</div>
</div>
- align-content: stretch
<h3>align-content: stretch</h3>
<div class="container" style="height:50%;display:grid;grid-column-gap: 10px;align-content: stretch">
<div class="box">宽和高为100</div>
<div style="background-color: coral">22</div>
<div style="background-color: coral">33</div>
<div style="background-color: coral">44</div>
<div style="background-color: coral">55</div>
</div>
当项目没有指定的大小时,拉伸占据整个个项目的大小。如下图,第一个box 指定大小只显示100px,而其他的box则占满了整个单元格
-place-content: start end
<h3>place-content: start end--右上角</h3>
<div class="container" style="place-content: start end">
<div class="box">11</div>
<div class="box">22</div>
<div class="box">33</div>
<div class="box">44</div>
<div class="box">55</div>
</div>
垂直位置start在整个容器的上方,水平位置end在整个容器的末尾,所以项目的位置在容器位置的右上角的位置
<h3>place-content: end start--左下角</h3>
<div class="container" style="place-content: end start">
<div class="box">11</div>
<div class="box">22</div>
<div class="box">33</div>
<div class="box">44</div>
<div class="box">55</div>
</div>
垂直位置end在整个容器的下方,水平位置start在整个容器的起始,所以项目的位置在容器位置的左下角的位置
grid-auto-columns 和 grid-auto-rows
grid-auto-columns 和 grid-auto-rows 定义隐式网格
- 显式网格:就是使用grid-template-columns 和 grid-template-rows 属性中定义的行和列。
- 隐式网格:当内容超出了设置的行和列时,网格将会在创建隐式的行和列。(如果指定增加的宽和高。浏览器会更具单元格本身的大小来确定网格的行高和列宽)
<style>
.container{
display: grid;
grid-template-columns: 200px 200px;
/* 只设置了两行,但实际的数量会超出两行,超出的行高会以 grid-auto-rows 算 */
grid-template-rows: 100px 100px;
grid-gap: 10px 20px;
background: antiquewhite;
}
.box{
width: 100px;
height: 100px;
background-color: coral;
}
</style>
只设置了两行,但实际的数量会超出两行,超出的行高会以 grid-auto-rows 计算
<h3>显式的创建2行2列的内容</h3>
<div class="container">
<div class="box">11</div>
<div class="box">22</div>
<div class="box">33</div>
<div class="box">44</div>
<div class="box">55--自动根据单元格宽和高创建大小</div>
</div>
<h3>显式的创建2行2列的内容,添加隐式的创建内容</h3>
<div class="container" style="grid-auto-rows: 50px">
<div class="box">11</div>
<div class="box">22</div>
<div class="box">33</div>
<div class="box">44</div>
<div class="box">55--隐式创建行高50</div>
</div>
补充内容
- grid-column-start 属性:左边框所在的垂直网格线
- grid-column-end 属性:右边框所在的垂直网格线
- grid-row-start 属性:上边框所在的水平网格线
- grid-row-end 属性:下边框所在的水平网格线
<style>
.container{
display: grid;
width: 50%;
grid-template-columns: repeat(3, 1fr);
grid-gap: 20px;
grid-auto-rows: minmax(100px, 150px);
}
.box1{
grid-column-start: 1;
grid-column-end: 2;
background: peru;
}
.box2{
grid-column-start: 2;
grid-column-end: 4;
grid-row-start: 1;
grid-row-end: 2;
z-index: 1;
background: blueviolet;
}
.box3 {
grid-column-start: 3;
grid-column-end: 4;
grid-row-start: 1;
grid-row-end: 4;
background: blue;
/*z-index:5;*/
}
.box4 {
grid-column-start: 1;
grid-column-end: 2;
grid-row-start: 2;
grid-row-end: 5;
background: yellow;
}
.box5 {
grid-column-start: 2;
grid-column-end: 2;
grid-row-start: 3;
grid-row-end: 5;
background: coral;
}
</style>
<h3>通过设置网格线,来确定布局</h3>
<div class="container">
<div class="box1">111</div>
<div class="box2">222<p><strong>第二个盒子以第2根垂直网格线开始一直到第4根垂直网格线</strong></p></div>
<div class="box3" style="padding-top: 80%">333<p><strong>第三个盒子以第3根垂直网格线开始一直到第4根垂直网格线</strong></p></div>
<div class="box4">444</div>
<div class="box5">555</div>
</div>
** 第二个box 和第三个box 有公共的部分,可以使用z-index 来设置他们的层级 **
最后
grid 布局到此为止,有不足之处,欢迎大家补充! 获取项目演示的代码