grid布局
Flex布局是轴线布局,只能指定“项目”针对轴线的位置,可以看做是一维布局;
Grid布局是将容器划分成“行“和”列“,产生单元格,然后指定”项目所在“单元格,可以看成是二维布局。
一、基本概念
1.1、容器和项目
采用网格布局的区域,称为“容器”(container),容器内部采用网格定位的子元素称为“项目”(item)。
<div class="container">
<div class="item"><p>1</p></div>
<div class="item"><p>2</p></div>
<div class="item"><p>3</p></div>
</div>
上述代码中,最外层div.container元素为容器,内层div.item元素是为项目。项目只能是容器的顶层子元素,不包含项目的子元素,如<p>元素,Grid布局只对项目生效。
1.2、行和列
容器里面的水平区域称为“行”(row),垂直区域称为“列”(column)。
1.3、单元格
行和列交叉区域,称为“单元格”(cell)。
正常情况下,n行和m列会产生n x m 个单元格,比如3行3列产生9个单元格。
1.4、网格线
划分网格的线,称为“网格线”(grid line)。水平网格线划分出行,垂直网格线划分出列。
正常情况下,n行有n + 1根水平网格线,m行有m + 1根垂直网格线。
4 x 4的网格,共5根水平网格线和5根垂直网格线:
二、容器属性
Grid布局的属性分为两类,一类定义在容器上面,称为容器属性;另一类定义在项目上面,称为项目属性。
2.1、display属性
display: grid 指定一个容器采用网格布局(display: inline-grid,将容器变成行内元素)。
注:设为网格布局以后,容器子元素(项目)的float、display:inline-block | table-cell、vertical-align 和column-*等属性将失效。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
body {padding: 30px}
.container {
display: grid;
grid-template-columns: 80px 80px 80px;
grid-template-rows: 80px 80px 80px;
width: max-content;
margin: 10px 0;
background: linear-gradient(135deg, #f9bcc6, #73a3ef);
}
.item {
text-align: center;
line-height: 80px;
color: #fff;
font-size: 20px;
border: 1px solid #fff;
}
span {font-size: 20px;}
</style>
</head>
<body>
<span>display</span>
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
<div class="item">9</div>
</div>
<span>grid</span>
</body>
</html>
2.2、grid-template-columns、grid-template-rows属性
容器指定了网格布局以后,接着要划分行和列。
grid-template-columns:定义每一列的列宽, grid-template-rows:定义每一行的行高。
列宽行高如果使用的是百分比值,则容器需要添加具体宽高值。
.container {
display: grid;
grid-template-columns: 80px 80px 80px;
grid-template-rows: 80px 80px 80px;
width: max-content;
margin: 10px 0;
background: linear-gradient(135deg, #f9bcc6, #73a3ef);
/*除了使用绝对单位,也可以使用百分比, 这时候需要指定容器宽高*/
grid-template-columns: 33.33% 33.33% 33.33%;
grid-template-rows: 33.33% 33.33% 33.33%;
width: 240px;
height: 240px;
}
1)repeat()函数
在网格很多,重复写相同值的时候,可以使用repeat()函数简化重复的值。
repeat():接受俩参数,第一个是重复的次数,第二个是重复的值或重复某种模式。
.container {
grid-template-columns: repeat(3, 80px);
grid-template-rows: repeat(3, 80px);
grid-template-columns: repeat(3, 33.33%);
grid-template-rows: repeat(3, 33.33%);
}
<!DOCTYPE html>
<html lang="en">
<head>
<style>
body {padding: 30px}
.container {
display: inline-grid;
/*grid-template-columns: repeat(3, 80px);*/
grid-template-columns: repeat(2, 60px 80px 100px);
grid-template-rows: repeat(3, 80px);
width: max-content;
height: max-content;
margin: 10px 0;
border: 1px solid #000;
background: linear-gradient(135deg, #f9bcc6, #73a3ef);
}
.item {
text-align: center;
line-height: 80px;
color: #fff;
font-size: 20px;
border: 1px solid #fff;
}
</style>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
<div class="item">9</div>
</div>
</body>
</html>
说明:
上述图可以说明,当容器width和height未设置具体值时,由grid-template-columns和grid-template-rows决定;如果设置具体值如200px,则超出容器的项目不显示。
容器的列数可以等于repeat()函数参数的重复次数 x 重复值项数(只有一项) 或 重复次数 x 模式中列数。
图一:3 x 1(80px) = 1 x 3 ( 80px 80px 80px)
图二:2 x 3 (60px 80px 100px) = 6列,这里虽然把第二行变成了列,但由于grid-template-rows: repeat(3, 80px),故容器的高依然为3个行高。
图三:当把第二行变成第一行后,改变容器项目的总行高,才能改变容器整体高度。
2)auto-fill 关键字
在单元格大小固定、容器大小不确定情况下,如果希望每一行或每一列尽可能容纳更多单元格时,可以使用auto-fill关键字表示自动填充。
.container {
display: grid;
grid-template-columns: repeat(auto-fill, 100px);
grid-template-rows: repeat(3, 100px);
padding: 5px;
background: linear-gradient(135deg, #f9bcc6, #73a3ef);
}
3)fr 关键字
网格布局提供了fr关键字(fraction,片段)。很好的表达了比例关系。如下第二列为第一列的两倍,第三列为第一列的三倍。
fr 可以与绝对长度单位结合使用(grid-template-columns: 120px 1fr 2fr)
.container {
display: grid;
grid-template-columns: 1fr 2fr;
padding: 5px;
background: linear-gradient(135deg, #f9bcc6, #73a3ef);
}
4)minmax( minValue, maxValue )
该函数产生一个长度范围,表示长度就在这个范围之中,接受两个参数,分别表示最小值和最大值。
.container {
display: grid;
grid-template-columns: 1fr 1fr minmax(100px, 1fr);
padding: 5px;
background: linear-gradient(135deg, #f9bcc6, #73a3ef);
}
5)auto 关键字
表示该列列宽由浏览器决定,占据剩余宽度,当该列某单元格设置宽度大于该列分得的宽度时,该列宽同某单元格宽度相等,也就是基本上等于该列单元格中最大的宽度。
.container {
display: grid;
grid-template-columns: 100px auto 100px;
padding: 5px;
background: linear-gradient(135deg, #f9bcc6, #73a3ef);
}
6)网格线名称
grid-template-columns 属性和 grid-template-rows 属性里面,可以使用方括号指定每一根网格线名字,方便以后使用。
如下,c1~c4为水平网格线,r1~r4为垂直网格线,网格线可以有多个名称,[c1] —> [c1 lineFirst]
.container {
display: grid;
grid-template-columns: [c1] 100px [c2] 100px [c3] auto [c4];
grid-template-rows: [r1] 100px [r2] 100px [r3] auto [r4];
padding: 5px;
background: linear-gradient(135deg, #f9bcc6, #73a3ef);
}
7)布局实例
grid-template-columns属性对于网页布局非常有用,两栏布局只需要一行代码。
2.3、grid-row-gap 、grid-column-gap、grid-grap属性
grip-row-gap:设置行与行的间隔(行间距);
grip-column-gap:设置列与列的间隔(列间距);
grip-gap:是grip-row-gap和grip-column-gap的合并简写形式,grip-gap: <grip-row-gap> <grid-column-gap>。如果grip省略了第二个值,则默认第二个值等于第一个值。
根据最新标准,以上三个属性名的 grid- 前缀已经被删除,可写成:row-gap、column-gap、gap。
2.4、grid-template-areas属性
网格布局允许指定“区域”(area),一个区域由单个或多个单元格组成。
以下代码先划分9个单元格,然后将其命名为a到i的9个区域,分别对应9个单元格:
.container {
display: grid;
grid-template-columns: 100px 100px 100px;
grid-template-rows: 100px 100px 100px;
grid-template-areas: 'a b c'
'd e f'
'g h i';
}
多个单元格合并一个区域的写法,将9个单元格分成a、b、c三个区域:
.container { grid-template-areas: 'a a a' 'b b b' 'c c c';
}
布局实例,顶部是页眉区域header,底部时页脚区域footer,中间部分则分为main和sidebar:
.container { grid-template-areas: 'header header header' 'main main main' 'footer footer footer';
}
如果某些区域不需要利用,则使用"点“(.)表示,中间一列为点,表示没有用到该单元格,或者该单元格不属于任何区域:
.container { grid-template-areas: 'a . a' 'b . b' 'c . c';
}
注:区域的命名会影响到网格线。每个区域的起始网格线自动命名为 区域名-start,终止网格线自动命名为 区域名-end。
比如,区域名为header,则起始位置的水平网格线、垂直网格线叫做 header-start,终止位置的水平网格线、垂直网格线叫做 header-end。
2.5、grid-auto-flow 属性
划分网格以后,容器的子元素会按照顺序,自动放置在每一个网格。默认放置顺序是“先行后列”,即先填满第一行,再开始放入第二行。
这个顺序由grid-auto-flow属性决定,默认值是row,即“先行后列”,也可以设成column,变成“先列后行”。
row dense属性值表示“先行后列”、column dense属性值表示“先列后行”,并且尽可能紧密填满,尽量不要出现空格(grid-column-start:1 应该表示改子项目从第一列开始排,第三列前结束,则占两个单元格)。
2.6、justify-items属性、align-items属性、place-items属性
justify-items:start | center | end | stretch; 设置单元格内容水平位置(左中右);
align-items:start | center | end | stretch; 设置单元格内容垂直位置(上中下);
place-items: <align-items> <justify-items>合并简写,place-items: start start,如果省略第二个值,则默认和第一个值相等。
start:对齐单元格起始边缘;
center:单元格内部居中;
end:对齐单元格结束边缘;
stretch:拉伸,占满整个单元格宽度(默认值);
2.7、justify-content属性、align-content属性、place-content属性
justify-content:整个内容区域在容器里面的水平位置(左中右);
align-content:整个内容区域在容器里面的垂直位置(上中下);
place-content:<justify-content> <align-content> 合并简写,place-content: end end,如果省略第二个值,则默认和第一个值相等。
start:对齐容器起始边框;
center:容器内部居中;
end:对齐容器结束边框;
stretch:项目大小没有指定时,拉伸占满整个网格容器;
space-around:每个项目两侧间隔相等。所以,项目中间间隔比项目是项目与容器边框间隔的两倍;
space-between:项目与项目间隔相等,项目与容器边框之间没有间隔;
space-evenly:项目与项目间隔和项目与容器边框间隔相等;
2.8、grid-auto-columns属性、grid-auto-rows属性
当项目被指定位置,并出现在现有网格外部时,浏览器会自动生成多余网格,以便放置项目,比如3行3列的网格存在第四列第四行时:
grid-auto-columns:多余列网格的列宽;
grid-auto-rows:多余行网格的行高;
写法和grid-template-columns和grid-template-rows同。
2.9、grid-template属性、grid属性
grid-template: grid-template-columns grid-template-rows grid-template-areas;
grid: grid-template-rows grid-template-columns grid-template-areas grid-auto-rows grid-auto-columns grid-auto-flow;
三、项目属性
1.1、grid-columns-start属性、grid-columns-end属性、grid-row-start属性、grid-row-end属性
项目的位置可以指定,具体方法是指定项目的四个边框,分别定位在哪根网格线,网格线属性值也可以用名称、关键字span表示。
使用这四个属性,如果产生项目重叠,则使用z-index属性指定项目重叠顺序。
grid-column-start:左边框所在的垂直网格线;
grid-column-end:右边框所在的垂直网格线;
grid-row-start:上边框所在的水平网格线;
grid-row-end:下边框所在的水平网格线;
说明:第一个项目设置左边框是第二根垂直网格线,右边框是第四根垂直网格线。
网格线用名称表示:
span关键字表示:表示跨越,即左右边框或上下边框之间跨越多少个网格。
grid-column-startr: span 2;表项目左边框距离右边框跨越2个网格;
grid-column-end: span 2;表项目右边框距离左边框跨越2个网格;
1.2、grid-column属性、grid-row属性
grid-column:grid-column-start和grid-column-end的合并简写,grid-column: <start-line> / <end-line>;
grid-row:grid-row-start和grid-row-end的合并简写,grid-row: <start-line> / <end-line>;
1.3、grid-area属性
grid-area指定项目放在哪一个区域(同容器属性grid-column-area结合使用)。
grid-area:可用作grid-row-start、grid-column-start、grid-row-end、grid-column-end结合使用。
grid-area: <grid-row-start> / <grid-column-start> / <grid-row-end> / <grid-column-end>
1.4、justify-self属性、align-self属性、place-self属性
justify-self:设置单元格内容水平位置(左中右),同justify-items属性用法一致,但只作用于单个项目。
align-self:设置单元格内容垂直位置(上中下),同align-items属性的用法一致,只作用于单个项目。
place-self:align-self和justify-self属性的合并简写,place-self: <align-self> <justify-self>,如果省略第二个值,则默认同第一个值相等。
start:对齐单元格起始边缘;
center:对齐单元格内部居中;
end:对齐单元格结束边缘;
stretch:拉伸,占满单元格整个宽度(默认值)。