首先,看一张图,了解一下容器和项目(不难理解,容器就是包在外层的元素,项目就是内部的元素)
我们后面会介绍下图的内容
每个grid布局,都有隐藏的网格线,用来帮助定位的。
说明:想要多少行/列,就填写相应属性的个数。不填写自动分配
我们先画好div,main中包着十个子元素。main此时就是容器(container),十个子元素就是项目(item)。我们给十个子元素加上不同的颜色
<html>
<head></head>
<style>
.main {
width: 600px;
height: 600px;
border: 10px solid skyblue;
}
.item {
font-size: 50px;
color:#FFF;
}
.item1 {
background-color: rgb(164, 233, 231);
}
.item2 {
background-color: rgb(117, 219, 153);
}
.item3 {
background-color: rgb(145, 206, 54);
}
.item4 {
background-color: rgb(190, 166, 218);
}
.item5 {
background-color: rgb(208, 100, 169);
}
.item6 {
background-color: rgb(221, 164, 114);
}
.item7 {
background-color: rgb(68, 87, 174);
}
.item8 {
background-color: rgb(17, 120, 117);
}
.item9 {
background-color: rgb(230, 79, 79);
}
.item10 {
background-color: rgb(68, 58, 204);
}
</style>
<body>
<div class="main">
<div class="item item1">1</div>
<div class="item item2">2</div>
<div class="item item3">3</div>
<div class="item item4">4</div>
<div class="item item5">5</div>
<div class="item item6">6</div>
<div class="item item7">7</div>
<div class="item item8">8</div>
<div class="item item9">9</div>
<div class="item item10">10</div>
</div>
</body>
</html>
此时,我们没有添加任何布局。效果如下,可以看到,子元素都已经挤出了容器中。
给容器添加属性,布局为grid。设置了三列,每列的宽为100px。
.main {
width: 600px;
height: 600px;
display: grid;
border: 10px solid skyblue;
grid-template-columns: 100px 100px 100px;
}
因为我们有四行,然后我们每行都给100px
.main {
width: 600px;
height: 600px;
display: grid;
border: 10px solid skyblue;
grid-template-columns: 100px 100px 100px;
grid-template-rows: 100px 100px 100px 100px;
}
现在我们如果一行/列有三个项目就需要写3次像素值。那么,如果有十个那就需要写十次,所以为了方便。repeat出现了,见词知意,repeat的意思是重复。
那么刚才我们的写法就可以写成: repeat(3,100px)
,接收两个参数,第一个是重复次数,第二个是像素值。
.main {
width: 600px;
height: 600px;
display: grid;
border: 10px solid skyblue;
grid-template-columns: repeat(3,100px);
grid-template-rows: 100px 100px 100px 100px;
}
有时候,单元格的大小是固定的,但是容器的大小是不确定的,比如自适应。这个时候,auto-fill属性就会自动填充。
举个例子
就如腾讯视频的这种卡片(卡片就是单元格并且是固定大小的),当我们缩小屏幕后,容器的宽度改变了,其一行有多少单元格,就会自动分配。
我们来使用一下auto-fill
去掉容器的宽高,添加auto-fill后,可以看到如下图,会根据浏览器窗口的变化而改变布局。
.main {
display: grid;
border: 10px solid skyblue;
grid-template-columns: repeat(auto-fill,100px);
grid-template-rows: 100px 100px 100px 100px;
}
为了方便比例关系,网格布局提供了fr关键字(fraction的缩写,意为“片段”)。类似于flex布局的 flex:1
如下,我们将容器的一行进行三等分,如下的grid-template-columns: repeat(3,1fr)
也就相当于grid-template-columns:1fr 1fr 1fr
.main {
display: grid;
border: 10px solid skyblue;
grid-template-columns: repeat(3,1fr);
grid-template-rows: 100px 100px 100px 100px;
}
如图,可以看到是根据窗口宽度,等分的。
我们缩小一下窗口,又进行了新的宽度分配。
再看一下,我们按 1:2:3的比例分配。
grid-template-columns: 1fr 2fr 3fr;
minmax() 第一个参数是最小值,第二个参数是最大值。
如下最小值为150px 最大值为1fr,当我们缩小浏览器窗口,可以看到第一列的元素还在变小,而第二列的元素固定在了150px。
.main {
display: grid;
border: 10px solid skyblue;
grid-template-columns: 1fr minmax(150px,1fr);
grid-template-rows: 100px 100px 100px 100px;
}
当我们有三列,我们的第一列和第三列是固定的宽度,然后第二列是自适应的宽度,此时我们就可以使用auto
.main {
display: grid;
border: 10px solid skyblue;
grid-template-columns: 100px auto 100px;
grid-template-rows: 100px 100px 100px 100px;
}
可以使用方括号定义网格线名称,方便以后的引用。
如下图,横纵方向都有四行/列,然后就有5条网格线。
针对我们的例子,添加一下。网格线是帮助定位使用的,我们添加后也体现不出效果,我们后面会说到。
.main {
display: grid;
border: 10px solid skyblue;
grid-template-columns: [c1] 100px [c2] 100px [c3] 100px;
grid-template-rows: 100px 100px 100px 100px;
}
下面的三个是之前的属性,已经被废弃了。虽然添加后依旧能实现效果,但是不建议使用。
grid-row-gap
grid-column-gap
/* 上面的两个写在了一起 */
grid-gap
新的属性
row-gap
column-gap
/* 上面的两个写在了一起 */
gap
.main {
display: grid;
border: 10px solid skyblue;
grid-template-columns: [c1] 100px [c2] 100px [c3] 100px;
grid-template-rows: 100px 100px 100px 100px;
row-gap: 20px;
column-gap:30px;
}
一个区域由单个或多个单元格,由你决定。我觉得有点像矩阵(不知道可以这样说吗)。
grid-template-areas: 'a b c'
'd e f'
'xiao hong xie';
grid-template-areas: 'a a a'
'b b b'
'c c c';
如果 区域不需要利用,可以使用.
表示
grid-template-areas: 'a . h'
'b . f'
'c . g';
并且,区域的命名会影响到网格线,每个区域的起始网格线会自动命名为-start,终止网格线自动命名为区域名-end。
划分网格后,容器的子元素会按照顺序,自动的放置在每一个网格,默认的是 先填满第一行,然后再开始第二行。也就是说我们 grid-auto-flow
属性,默认是row。
我们将其属性值改为column
.main {
display: grid;
border: 10px solid skyblue;
grid-template-columns: [c1] 100px [c2] 100px [c3] 100px;
grid-template-rows: 100px 100px 100px 100px;
gap: 20px 30px;
grid-template-areas: 'a b c' 'd e f' 'xiao hong xie';
grid-auto-flow: column;
}
还有一个值 dense,它是结合row或者column使用的。
他的作用: 如下图,1和2都很宽,一行是放不下他们两个的。但是为了更好的使用空间,我们可以让3和1在一行。这就是dense的作用。
我们这里给item1和item2添加了一个grid-column
属性,这里可以先不用管。我们后面会提到这个属性。
.main {
display: grid;
border: 10px solid skyblue;
grid-template-columns: [c1] 100px [c2] 100px [c3] 100px;
grid-template-rows: 100px 100px 100px 100px;
gap: 20px 30px;
grid-template-areas: 'a b c' 'd e f' 'xiao hong xie';
grid-auto-flow: row dense;
}
.item1 {
background-color: rgb(164, 233, 231);
grid-column: 1/3;
}
.item2 {
background-color: rgb(117, 219, 153);
grid-column: 1/3;
}
注意这里是容器属性的对其方式,在项目(item)中也会有对齐方式。
我们为其添加值:center
.main {
display: grid;
border: 10px solid skyblue;
grid-template-columns: [c1] 100px [c2] 100px [c3] 100px;
grid-template-rows: 100px 100px 100px 100px;
gap: 20px 30px;
grid-template-areas: 'a b c' 'd e f' 'xiao hong xie';
justify-items: center;
}
如图,我们发现变窄了,因为我们并没有给每个子元素添加宽高。然后就按照内容的(字)的宽度进行填充了,只是项目的对齐。
如下图,网格的宽度还是我们给定的100px,只是其内部的内容变小了。
justify-items:stretch
这是默认值,
justify-items:stretch
也就是让元素横向填满单元格align-items:stretch
也就是让元素纵向填满单元格justify-items:start
可以看出是按照单元格的其实位置开始对齐。
justify-items:center
就是我们上面的例子,居中对齐。
justify-items:end
以单元格的结尾位置进行对齐。
内容(content),就是容器(container)中的项目打包在一起(一坨东西)。可以去看我们刚开始的图。
这一坨,默认的是左对齐
如下是我把justify-content
设为center
。这一坨中对齐了
start | end | center | stretch
justify-content:space-between
两端对齐,留白各列之间均分。
justify-content:space-around
两端保留子元素与子元素间距的一半。还有留白,列之间等分。
比如,我只设置了3x3个项目,但是实际有10个项目,这个属性就是用来设置多出来的项目。
.main {
display: grid;
border: 10px solid skyblue;
grid-template-columns: [c1] 100px [c2] 100px [c3] 100px;
grid-template-rows: 100px 100px 100px;
gap: 20px 30px;
}
因为我们并没有对10进行grid-template-rows
的设置,它被浏览器自动分配了。
我们添加 grid-auto-rows
属性,后面出现的单元格会自动分配为50px
grid-auto-rows: 50px;
这里我们涉及到的属性,都是添加到项目上的。
我们让item1以第一个网格线开始,到第三个网格线结束(注意这里是网格线)。
.item1 {
background-color: rgb(164, 233, 231);
grid-column-start: 1;
grid-column-end:3;
}
除了这种使用网格线的方式还有另一种写法:
这里只需要 写 grid-column-start
即可。span 3
说明跨了三个单元格。
.item1 {
background-color: rgb(164, 233, 231);
grid-column-start:span 3;
/* 效果和start一样 */
/* grid-column-end:span 3;*/
}
当然这两个属性也有简写方式grid-column
,这里的 /
可不是除号
grid-column: 1/3
这里和上面同理
指定项目放在哪个区域,与我们上面的 grid-template-areas
关联。
我们在main中grid-template-areas
属性值为grid-template-areas: 'a a a' 'b b b' 'c c c';
.main {
display: grid;
border: 10px solid skyblue;
grid-template-columns: [c1] 100px [c2] 100px [c3] 100px;
grid-template-rows: 100px 100px 100px 100px;
gap: 20px 30px;
grid-template-areas: 'a a a' 'b b b' 'c c c';
}
然后在item1中添加grid-area属性,让其与b区域对应
.item1 {
background-color: rgb(164, 233, 231);
grid-area: b;
}
如图,item1占据了b区域(三个单元格)的位置。
grid-area 可以替代如下四个属性
grid-column-start
grid-column-end
grid-row-start
grid-row-end
四个值分别对应:grid-column-start、 grid-row-start、grid-column-end、grid-row-end
grid-area: 1/1/3/3
这三个属性和容器中的完全一致,区别在于容器中是针对容器内所有项目的,这三个属性只针对自己项目的对齐。
我们给item1添加 justify-self: center;
属性
.item1 {
background-color: rgb(164, 233, 231);
justify-self: center;
}
可以看到只有item1居中对齐了。