Grid网格布局,有几个概念:
和Flex布局一样也分为父元素、子元素的作用属性。
通过在元素上声明 display:grid
或 display:inline-grid
来创建一个网格容器。声明 display:grid
则该容器是一个块级元素,设置成 display: inline-grid
则容器元素为行内元素。
注意,设为网格布局以后,容器子元素(项目)的
float
、display: inline-block
、display: table-cell
、vertical-align
和column-*
等设置都将失效。
html:
<div class="container">
<div class="item1">1div>
<div class="item2">2div>
<div class="item3">3div>
<div class="item4">4div>
<div class="item5">5div>
<div class="item6">6div>
<div class="item1">7div>
<div class="item2">8div>
<div class="item3">9div>
div>
css
.container {
display: grid;
/* 三行三列的布局,每个单元格的大小 100 *100 */
grid-template-rows: 100px 100px 100px;
grid-template-columns: 100px 100px 100px;
/* 间距*/
grid-gap: 10px;
}
grid-template-rows
:定义每一行的行高grid-template-columns
:定义每一列的宽度上面的代码是个三行三列的网格,然后item间距是10px
单元格大小除了使用绝对单位像素,也可以使用百分比和fr单位,类似Android中的weight权重的概念。
单元格大小不等于每个item的大小,默认是相等的,我们也可以单独为每个设置宽高大小
grid-template-rows: 100px 100px 33.33%;
/* 第二列的宽度会占满剩余的空间 */
grid-template-columns: 100px 1fr 100px;
grid-template-areas
属性是用于合并单元格,需要与子元素grid-area
属性搭配使用,不然是没有效果的。
html:
<div class="container">
<div>1div>
<div>2div>
<div>3div>
div>
css:
.container{
width: 300px;
height: 300px;
background-color: pink;
display: grid;
grid-template-rows: 1fr 1fr 1fr;
grid-template-columns: 1fr 1fr 1fr;
}
是一个三行三列的网格布局,内容子元素只有三个,剩余是空位,效果:
在父元素使用 grid-template-areas
属性定义网格元素的合并规则,然后子元素使用grid-areas
属性指定名称。
.container{
grid-template-rows: 1fr 1fr 1fr;
grid-template-columns: 1fr 1fr 1fr;
grid-template-areas:
"a1 a1 a2"
"a1 a1 a2"
"a3 a3 a3";
}
效果如下,三个元素就充满了整个容器:
上面的样式可以使用grid-template
进行简写,如下:
.container{
/*grid-template-rows: 1fr 1fr 1fr;*/
/*grid-template-columns: 1fr 1fr 1fr;*/
/*grid-template-areas:*/
/* "a1 a1 a2"*/
/* "a1 a1 a2"*/
/* "a3 a3 a3";*/
grid-template:
"a1 a1 a2" 1fr
"a1 a1 a2" 1fr
"a3 a3 a3" 1fr
/ 1fr 1fr 1fr;
}
网络有行与列的间距
grid-row-gap
、row-gap
grid-column-gap
、column-gap
推荐使用row-gap
、column-gap
,同样也适用于flex布局上。
/*grid-row-gap: 10px;
grid-column-gap: 20px;*/
row-gap: 10px;
column-gap: 20px;
/*第一个是行间距 第二个是列间距*/
/*grid-gap: 10px 20px;*/
gap: 10px 20px;
item对齐是指在单元格内的对齐方式,通过justify-items
、align-items
属性实现
/* justify-items 每个item在单元格中的水平方向对齐 */
justify-items: center;
/* align-items 每个item在单元格中的垂直方向对齐 */
align-items: center;
/*简写*/
/*place-items: center center;*/
内容对齐是指单元格在父容器中的对齐方式,要实现内容的对齐效果,提前是所有单元格大小必须小于父容器大小,通过justify-content
、align-content
属性实现
width: 500px;
height: 500px;
display: grid;
grid-template-rows: 100px 100px 100px;
grid-template-columns: 100px 100px 100px;
/*内容对齐:是指单元格在父容器中的对齐方式 , 前提就是所有单元格的总大小必须小于父容器大小*/
justify-content: space-around;
align-content: space-between;
/*简写*/
/*place-content: space-around space-evenly;*/
上面是一个三行三列的网格布局,父容器大小是500 *
500px
,一个的单元格大小是100 * 100px
,所有单元格大小是300
* 300px
,是小于父容器的。
显示网格:是指item在定义单元格范围内,比如一行三列的布局,若item在这布局中就是显示单元格,不在则为隐式单元格。
前提是容器的子元素超过了网络布局定义范围,比如一行三列的布局,正常是三个元素,但隐式单元格就是超过了三个元素。
.container {
width: 300px;
height: 300px;
background-color: pink;
display: grid;
grid-template-columns: 100px 100px 100px;
grid-template-rows: 100px;
/*
显示网格:是指item在定义单元格范围内,比如一行三列的布局,若item在这布局中就是显示单元格,不在则为隐式单元格
*/
}
html
<div class="container">
<div>1div>
<div>2div>
<div>3div>
<div>4div>
<div>5div>
div>
默认隐式单元格会填满父容器的剩余空间,可以通过grid-auto-flow
属性来控制隐式单元格的方式,默认指row
就是垂直方式,上面的就是默认效果,将grid-auto-flow
属性指水平列方向column
,效果:
另外可以使用grid-auto-rows
、grid-auto-columns
的大小。
/*控制隐式单元格的方向,默认是row,垂直方式*/
/*grid-auto-flow: row;*/
/*grid-auto-rows: 100px;*/
/*成对使用*/
grid-auto-flow: column;
grid-auto-columns: 100px;
利用隐式单元格布局,可以很轻松实现高或宽自适应布局,父容器可以随着子元素增加或减少自动改变大小。
下面代码在父容器不设置高度的情况,利用隐式单元格的特性来实现自适应布局。
.container {
width: 300px;
background-color: pink;
display: grid;
grid-template-columns: 100px 100px 100px;
grid-template-rows: 100px;
grid-auto-flow: row;
grid-auto-rows: 100px;
}
<div class="container">
<div>1div>
<div>2div>
<div>3div>
<div>4div>
<div>5div>
<div>1div>
<div>2div>
<div>3div>
<div>4div>
<div>5div>
div>
效果:
1 / 1 / 1 / 1
,另外还单独支持设置 grid-template-areas的名称子元素在没有设置宽高时,默认大小是与单元格是一样的。子项的属性是相对元素而言的,不是单元格。
每个单元格都有序号的,可以在layout布局中查看:
选择显示行号 ,然后勾选网格覆盖,就会显示网格线、列号、行号
默认子元素都是独占一个单元格的,如果要进行合并单元格,除了前面提到的用grid-template-areas
属性与子元素grid-areas
属性实现,还可以通过子元素的grid-column-start
、grid-column-end
、grid-row-start
、grid-row-end
属性来修改元素的起始与结束位置来实现单元格合并。
html:
<div class="container">
<div>1div>
div>
css
.container{
width: 300px;
height: 300px;
background-color: pink;
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr 1fr;
}
.container :nth-of-type(1){
background-color: orange;
grid-column-start: 2;
grid-column-end: 4;
}
如果子元素默认不设置,如上图的效果,现在通过grid-column-start
、grid-column-end
对列的起始与结束位置进行修改后的效果:
同样地也可以对行的起始与结束位置进行修改,通过grid-row-start
、grid-row-end
属性,如下:
grid-column-start: 2;
grid-column-end: 4;
grid-row-start: 1;
grid-row-end: 3;
用grid-area
简写如上代码:
/* grid-area:是grid-row-start、grid-column-start、grid-row-end、grid-column-end的简写,用 / 分割,是有序的 */
grid-area: 1 / 2 / 3 / 4;
grid-column-start
等属性除了可以指定起始与结束位置来达到合并单元格的效果,还可以通过span
属性值进行合并单元格。
/* 如果加上span属性值 就不表示是位置,是一个占有单元格的个数,是从默认位置开始*/
/*grid-column-start: span 3;*/
grid-column-start: 2;
grid-column-end: span 2;
grid-row-end: span 2;
另外
grad-column、grid-row
属性是对上面属性的一种简写。
子元素的对齐:是指单元格的内容在单元格中的对齐方式。通常是子元素大小比单元格更小的情况,效果才会显式的体现出来。
通过justify-self
、align-self
属性实现:
html:
<div class="container">
<div>1div>
div>
css
.container{
width: 300px;
height: 300px;
background-color: pink;
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr 1fr;
}
.container :nth-of-type(1){
background-color: orange;
width: 50px;
height: 50px;
justify-self: center;
align-self: center;
}
效果:
上面例子都是固定单元格的行数与列数以及大小,在实际项目上这种往往是不确定可变的。而repeat()
函数正好可以解决这种问题。
/*grid-template-columns: 100px 100px 100px;*/
/* 等同于上面的写法 ,简写*/
grid-template-columns: repeat(3,100px);
repeat()
函数的第一个数是列或行的个数,或者auto-fill
,第二个是单元格的大小。
auto-fill
:表示列数与行数是不固定的,会网格布局的大小自动调节列数或行数。
如下例子:
html:
<div class="container">
<div>1div>
<div>2div>
<div>3div>
<div>4div>
<div>5div>
<div>6div>
<div>7div>
<div>8div>
<div>9div>
div>
css:
.container {
/*width: 500px;*/
background-color: pink;
display: grid;
/*grid-template-columns: 150px repeat(2,100px);*/
/* auto-fill 根据宽度来自动调节单元格个数,不是固定的*/
grid-template-columns: repeat(auto-fill, 100px);
/*grid-template-rows: 100px;*/
/*定义隐式单元格的属性值*/
grid-auto-flow: row;
grid-auto-rows: 100px;
}
.container div {
background-color: orange;
border: 1px solid gray;
}
上面没有给网格布局设置宽度与高度,以及网格的列数、行数,都是跟随元素和分辨率自动调节网格的列数、行数。
行数rows,是根据隐式单元格的特性来自动调节。
点击查看效果动图
关于repeat函数其他用法:
minmax()
函数是给单元格的设置一个最小值、最大值。
.container {
background-color: pink;
display: grid;
/*中间的单元格的宽度是自适应,最小是100px*/
grid-template-columns: 100px minmax(100px,1fr) 100px;
grid-template-rows: 100px;
}
上面的样式效果,单元格2会随着分辨率大小自动调节宽度,当调节到100px时是不会再缩小的。
minmax()
函数与repeat()
函数一起使用,实现响应式布局
.container {
background-color: pink;
display: grid;
grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
grid-template-rows: 100px;
/* 设置行数为隐式单元格 自适应*/
grid-auto-flow: row;
grid-auto-rows: 100px ;
}
.container div {
background-color: orange;
border: 1px solid gray;
}
单元格列数跟随容器宽度自适应,宽度最小不会小于100px,行数是一个隐式单元格属性,会自动适应容器大小。
点击查看效果动图
可以通过修改子元素的起始与结束位置来实现叠加布局,然后通过子元素的对齐方式来调整具体位置。
html:
a
b
css:
.main{
width: 200px;
height: 200px;
background-color: olive;
display: grid;
grid-template-columns: 100px 100px;
grid-template-rows: 100px 100px;
}
.main div{
background-color: chartreuse;
}
.main .a{
background-color: red;
width: 40px;
height: 20px;
grid-area: 1 / 1 / 2 / 2;
}
.main .b{
width: 40px;
height: 20px;
background-color: royalblue;
justify-self: end;
align-self: end;
grid-area: 1 / 1 / 2 / 2;
}
效果:
默认情况下两个子元素是在独自的单元格内,现在通过grid-area
属性修改起始与结束位置,将两个元素放在了同一个单元格内,然后同子元素的对齐属性定位。