# 宫格布局
TIP 参考链接: CSS Grid 网格布局教程 (opens new window)
# 概述
宫格布局和flex布局相似,但是宫格布局更复杂,能做出各种各样的布局,flex布局只能针对一个轴的方向进行布局,而宫格却可以进行二维布局,横向和纵向都可以。
宫格布局就像表格一样,有容器和子项目(单元格),里面的属性又可分为行和列、宽和高、单元格、网格线、间距,行列合并,排列方向、对齐方式、位置、布局,这些都有对应的css属性来进行控制和操作。
# 容器属性
# 1、display 属性
display属性定义宫格容器,可以是块元素,也可以定义为行内元素。
div {
display: grid;
}
div {
display: inline-grid;
}
注意,设为网格布局以后,容器子项目的float、display: inline-block、display: table-cell、vertical-align和column-*等设置都将失效。
# 2、行列设置
设置好容器后,我们需要使用 grid-template-columns、grid-template-rows 属性来定义子项目如何按照 nxm 宽高为多少进行排列。
grid-template-columns 定义每一列的宽,grid-template-rows定义每一行的高。
.container {
display: grid;
grid-template-columns: 200px 200px 200px;
grid-template-rows: 100px 100px;
}
上面定义了一个宽为200,高为100的2x3的宫格布局,除了使用绝对单位,还可以使用百分比进行设置。 注意:这两个属性定义的是容器的布局方式,项目也只是指容器里的某块布局,和布局里具体的子元素自身不相关。
这两个属性还有一些其他简写的方法和补充属性
2.1 repeat()
如果定义多个行和列写起来很麻烦,我们可以使用repeat方法省略重复的值。
repeat接受两个参数,第一个参数是重复的次数,第二个参数是所要重复的值。 当然也可以重复某种模式。
.container {
display: grid;
grid-template-columns: repeat(3, 200px);
grid-template-rows: repeat(2, 100px);
}
.container {
display: grid;
grid-template-columns: repeat(2, 100px 200px 200px);
grid-template-rows: repeat(2, 100px);
}
2.2 auto-fill关键字
auto-fill表示自动充满容器布局,如果容器大小不确定,项目大小确定,可以使用此属性来填充布局。
.container {
display: grid;
grid-template-columns: repeat(auto-fill, 100px);
}
2.3fr 关键字
为了方便表示比例关系,网格布局提供了fr关键字(fraction 的缩写,意为"片段")。如果两列的宽度分别为1fr和2fr,就表示后者是前者的两倍。
// 相同宽度的两列
.container {
display: grid;
grid-template-columns: 1fr 1fr;
}
fr可以与绝对长度的单位结合使用。fr会占据容器剩余的空间进行等比例分配,并不会根据前面的具体数值进行分配。
.container {
display: grid;
grid-template-columns: 150px 1fr 2fr;
}
2.5minmax()
minmax(min, max) 表示长度可以在多少之间。
.container {
display: grid;
grid-template-columns: 150px minmax(100px, 200px);
}
// 如果设置fr则会根据容器宽度自动放大缩小
.container {
display: grid;
grid-template-columns: 150px minmax(100px, 1fr);
}
2.5 auto
auto表示占据父容器剩余空间
.container {
display: grid;
grid-template-columns: 150px auto 200px;
}
2.6 网格线名称
grid-template-columns属性和grid-template-rows属性里面,还可以使用方括号,指定每一根网格线的名字,方便以后的引用。
.container {
display: grid;
grid-template-columns: [c1] 100px [c2] 100px [c3] auto [c4];
grid-template-rows: [r1] 100px [r2] 100px [r3] auto [r4];
}
# 3、间距设置
单元格之间的间距可以使用grid-row-gap、grid-column-gap 、grid-gap 这个几个属性来设置。
.container {
display: grid;
grid-template-columns: repeat(3, 200px);
grid-template-rows: repeat(2, 100px);
grid-row-gap: 20px; // 行间距
grid-column-gap: 20px; // 列间距
// 合并写法
grid-gap: 20px 20px; // 行、列
}
# 4、行列合并
网格布局允许指定"区域"(area),一个区域由单个或多个单元格组成。grid-template-areas属性用于定义这些区域如何把单元格进行合并。
先看一个3x3布局如何用grid-template-areas表示,每个单元格都要有对应的名称来表示。a-i 9个区域表示1-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';
}
把多个单元格合成一个区域,只要把名称取一样就表示把对应位置的单元格进行合并了。
.container {
grid-template-areas: 'a a a'
'b b b'
'c c c';
}
// 即可以表示为上中下布局
.container {
grid-template-areas: "header header header"
"main main main"
"footer footer footer";
}
如果某些区域不需要利用,则使用"点"(.)表示。
.container {
grid-template-areas: "a a ."
"b b ."
"c c .";
}
# 5、项目排列方向
像flex布局一样,可以定义轴的方向,宫格布局也可以使用grid-auto-flow属性定义项目的排列方向。默认项目的排列顺序是"先行后列",即先填满第一行,再开始放入第二行。
.container {
grid-auto-flow: row | row-reverse | column | column-reverse;
}
它可能有4个值。
row(默认值):先行后列。
column:先列后行。
row dense:表示"先行后列",并且尽可能紧密填满,尽量不出现空格。
column dense: 表示"先列后行",并且尽量填满空格。
row dense 和 column dense 表示排序方向按照主方向排列后,如果多出剩余的空白区域该如何让其他项目填充。
比如一个宽500的容器,前两个单元格是200,第三个是100,那么正常情况下,第一个后面会空出100的空白区域,第三个会排在第二行第二个单元格后面。
如果使用row dense那么第三个就会填充到第一行的空白区域,后面的依次填充。
# 6、项目对齐方式
我们可以通过justify-content 、align-content、place-content 属性对容器内的所有单元格设置整体对齐方式。
.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;
}
这两个属性的值都一样,一个设置水平方向,一个设置垂直方向。
start(默认值):对齐容器的起始边框。
end:对齐容器的结束边框。
center:容器内部居中。
stretch: 项目大小没有指定时,拉伸占据整个网格容器。
space-around: 每个项目两侧的间隔相等。
space-between: 项目与项目的间隔相等,项目与容器边框之间没有间隔。
space-evenly: 项目与项目的间隔相等,项目与容器边框之间也是同样长度的间隔。
place-content属性是align-content属性和justify-content属性的合并简写形式。
.container {
place-content: space-around space-evenly;
}
# 7、项目内的对齐方式
上面是设置容器内单元格的对齐方式,这个是设置单元格内元素的对齐方式,当然单元格内真正的元素可以设置其内元素的对齐方式。
.container {
justify-items: start | end | center | stretch;
align-items: start | end | center | stretch;
}
这两个属性的值都一样,一个设置水平方向,一个设置垂直方向。
start:对齐单元格的起始边缘。
end:对齐单元格的结束边缘。
center:单元格内部居中。
stretch(默认值): 拉伸,占满单元格的整个宽度。
place-content属性是align-content属性和justify-content属性的合并简写形式。
.container {
place-items: center center;
}
# 8、多余项目的行列设置
如果设置的单元格超出了我们自定义的行列数,或者设置某个单元格在自定义的网格外面,浏览器会自动生成多余的网格来放置,默认的这些多余的单元格浏览器会自动内容大小设置宽高,我们也可以通过grid-auto-columns和grid-auto-rows 来指定这些多余单元格的大小,写法和行列设置一样。
.container {
display: grid;
grid-template-columns: 100px 100px 100px;
grid-template-rows: 100px 100px 100px;
grid-auto-columns: 80px;
grid-auto-rows: 50px;
}
# 9、属性简写
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、指定项目的位置
指定项目的位置具体方法就是指定项目的四个边框,分别定位在哪根网格线,指定到哪就占据到哪个单元格。并不是像flex通过数字来定位。
grid-column-start:左边框所在的垂直网格线
grid-column-end:右边框所在的垂直网格线
grid-row-start:上边框所在的水平网格线
grid-row-end:下边框所在的水平网格线
比如指定1号项目的左边框是第二根垂直网格线,右边框是第四根垂直网格线。则1号项目就会占据2、3两个单元格。
.container {
display: grid;
grid-template-columns: 100px 100px 100px;
grid-template-rows: 100px 100px 100px;
}
.item-1 {
grid-column-start: 2;
grid-column-end: 4;
}
这个指定边距和行合并列合并很像,还可以通过span来直接指定 跨越 多少个单元格。
.item-1 {
grid-column-start: span 2; // 直接占据1、2两个单元格
}
grid-column属性是grid-column-start和grid-column-end的合并简写形式。
grid-row属性是grid-row-start属性和grid-row-end的合并简写形式。
.item {
grid-column: <start-line> / <end-line>;
grid-row: <start-line> / <end-line>;
}
// 可以和span综合一起用。
.item-1 {
grid-column: 1 / 3;
grid-row: 1 / 3;
}
/* 等同于 */
.item-1 {
grid-column: 1 / span 2;
grid-row: 1 / span 2;
}
# 2、指定项目的区域
和指定位置一样,项目也可以单独指定自己所在的区域。grid-area属性指定项目放在哪一个区域。
.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';
}
.item-1 {
grid-area: e;
}
grid-area属性还可用作grid-row-start、grid-column-start、grid-row-end、grid-column-end的合并简写形式,直接指定项目的位置。
.item {
grid-area: <row-start> / <column-start> / <row-end> / <column-end>;
}
.item-1 {
grid-area: 1 / 1 / 3 / 3;
}
# 2、项目的对齐方式
我们可以通过justify-self、align-self 属性设置单元格内容的对齐方式。它和 justify-items、align-items用法一模一样。
.container {
justify-self: start | end | center | stretch;
align-self: start | end | center | stretch;
}
两个属性取值一样
start:对齐单元格的起始边缘。
end:对齐单元格的结束边缘。
center:单元格内部居中。
stretch(默认值): 拉伸,占满单元格的整个宽度。
place-self属性是justify-self属性和align-self 属性的合并简写形式。
.container {
place-self: center center;
}