CSS中gap并不是新的属性,在CSS3新特性中多列布局为其添加了一个新能力。间隙属性除了运用在CSS栅格之外,CSS3新特性中弹性布局同样可以使用。
简介
Grid 布局是将容器划分成"行"和"列",产生单元格,然后指定"项目所在"的单元格,可以看作是二维布局,也是唯一的二维布局方案,利用grid布局可以很轻松的实现很多的网页布局
gird布局很强大,采用网格布局的区域,称为"容器"(container)。容器内部子元素,称为"项目"(item),即container -> item
注意:Grid 布局只对项目生效,项目只能是容器的一级子元素,不包含项目的子元素
grid相关属性
下面从容器属性和项目属性两大块来记录grid布局中的相关属性
- 显式网格属性: grid-template-rows、grid-template-columns 和 grid-template-areas。
- 隐式网格属性: grid-auto-rows、grid-auto-columns 和 grid-auto-flow。
- 间距属性: grid-column-gap 和 grid-row-gap。
使用网格布局后,项目的float、display: inline-block、display:
table-cell、vertical-align和column-*等设置都将失效。
间隙属性
- gap:定义栅格布局的行与列间隙的尺寸。
- row-gap:定义行间隙的尺寸。
- column-gap:定义列间隙的尺寸。
- grid-gap:定义栅格布局中行与列间隙的尺寸。
- grid-row-gap:定义栅格布局中行间隙的尺寸。
- grid-column-gap:定义栅格布局中列间隙的尺寸。
grid属性:
- grid-template-rows/columns:规定列和行的尺寸。
- grid-template-areas:规定使用特定命名的栅格布局。
- grid-auto-rows/columns:规定列和行的自动尺寸。
- grid-auto-flow:指定在栅格布局中元素怎样自动布局排列。
注意:CSS栅格布局起初是用grid-gap属性来定义的,目前逐渐被gap替代。
Grid 布局的使用方法
块级容器(宽度撑满整行)时,容器独占一行
display: grid;
下图是display: grid的效果:
行内容器(宽度随内容自适应)时
display: inline-grid;
下图是display: inline-grid的效果:
注意:设为网格布局以后,容器子元素(项目)的float、display: inline-block、display:
table-cell、vertical-align和column-*等设置都将失效。
划分列 grid-template-columns
单位包括:
- 绝对值
px
, - 百分比值
%
, - 比例值
fr
,
绝对值 px:在容器内划分出3列,每列宽度为100px
grid-template-columns: 100px 100px 100px;
**百分比值 %:**将容器等分为3列,每列宽度为容器总宽度/3
grid-template-columns: 33.33% 33.33% 33.33%;
**比例值 fr:**将容器划分为2列,第1列的宽度 :第2列的宽度 = 1:2
grid-template-columns: 1fr 2fr;
fr 是fraction 的缩写,意为"片段",可以与绝对长度的单位结合使用
grid-template-columns: 150px 1fr 2fr;
.container {
display: grid;
grid-template-columns: 100px 100px 100px;
grid-template-rows: 100px 100px 100px;
}
上面代码指定了一个三行三列的网格,列宽和行高都是100px
栅格间隙
所有浏览器都支持栅格布局中的间隙。
我们来创建一个包含三列两行的栅格:
.container {
display: grid;
grid-template-columns: 200px 100px 300px;
grid-template-rows: 100px 100px;
gap: 20px;
}
打开调试器可以看到的线条为栅格线,它们分隔栅格的轨道(行和列)栅格线开始像获得厚度一样20px
网络布局实例代码及效果图
网格轨道
- grid-template-columns属性:定义每一列的列宽
- grid-template-rows属性:定义每一行的行高
九宫格:实现列宽和行高都是200px的网格,即200宽高的九宫格
.container {
display: grid;
grid-template-columns: 200px 200px 200px;
grid-template-rows: 200px 200px 200px;
}
属性值
repeat()
接受两个参数,第一个参数是重复的次数,第二个参数是所要重复的值
当我们需要写很多行很多列的时候,一个个敲相同的值会非常麻烦,这时候就可以使用repeat()函数,简化重复值
.container {
display: grid;
grid-template-columns: repeat(3,200px);
grid-template-rows: repeat(3,200px);
}
不止于此,repeat还可以重复某种模式,像这样简写
grid-template-columns: repeat(3,200px 100px);
这句代码意思是定义了6列,分别是200,100,200,100,200,100
grid-template-columns: repeat(2, 100px 20px 80px);
上面代码定义了6列,第一列和第四列的宽度为100px,第二列和第五列为20px,第三列和第六列为80px,效果图如下:
auto-fill
表示自动填充,让一行(或者一列)中尽可能的容纳更多的单元格。
当我们只需要确定列宽或者行高,而不用理有多少列时,就可以使用它了
每一列200px,列数设置为了auto-fill会自动填充,此时缩小浏览器的宽度,项目会因填充不下而另起一行
.container {
display: grid;
grid-template-columns: repeat(auto-fill, 100px);
}
上面代码表示每列宽度100px,然后自动填充,直到容器不能放置更多的列
fr
fr
单位代表网格容器中可用空间的一等份。使用方法如下
grid-template-columns: 200px 1fr 2fr ;
grid-template-rows: repeat(3,200px)
表示第一个列宽设置为 200px
,后面剩余的宽度分为两部分,第二给项目占1/3
,第三个项目占2/3
从图中可以看出第三列始终占据着剩余位置中的2份,列宽始终是第二列的二倍
.container {
display: grid;
grid-template-columns: 1fr 1fr;
}
上面代码表示两个相同宽度的列,效果图:
fr
可以与绝对长度的单位结合使用,这时会非常方便
.container {
display: grid;
grid-template-columns: 150px 1fr 2fr;
}
上面代码表示,第一列的宽度为150像素,第二列的宽度是第三列的一半,效果图如下:
minmax()
minmax()
函数产生一个长度范围,表示长度就在这个范围之中都可以应用到网格项目中。它接受两个参数,分别为最小值和最大值,也就是说最大不会超过最大值,最小不能小过最小值
grid-template-columns: 200px 1fr minmax(400px,1fr);
grid-template-rows: repeat(3,200px)
auto
auto
设置后,将由浏览器自行决定长度,尽可能的会占满剩余空间,除非有其他设置,例如有min-width
之类的,利用这个关键字,我们可以轻易实现三列或者两列布局。
grid-template-columns: 200px auto 200px;
grid-template-rows: repeat(3,200px)
对中间那列设置了auto,实现了中间自适应的三栏布局
网格线
grid布局叫做网格布局,那自然少不了网格线的存在,使用方括号,指定每一根网格线的名字,方便以后的做定位时使用
grid-template-columns: [c1] 200px [c2] auto [c3] 200px [c4];
grid-template-rows: [r1] 200px [r2] auto [r3] 200px [r4];
就像这样定义了一个3*3的网格区域,就需要有4条水平线,4条垂直线
网格间距gap
row-gap属性设置行与行的间隔(行间距),column-gap属性设置列与列的间隔(列间距)。
.container {
grid-template-columns: repeat(3,200px);
grid-template-rows: repeat(3,200px);
row-gap: 10px;
column-gap: 10px;
}
row-gap
、column-gap
一样值,可用gap:10px
代替
grid-auto-flow 属性
划分网格以后,容器的子元素会按照顺序,自动放置在每一个网格。默认的放置顺序是"先行后列",即先填满第一行,再开始放入第二行,即下图数字的顺序。
这个顺序由grid-auto-flow属性决定,默认值是row,即"先行后列"。也可以将它设成column,变成"先列后行"。
grid-auto-flow: column;
注意:盒子的排列顺序变成了先列后行
还有两个特殊的属性值row dense
和column dense
当我调整我们的代码将某一个项目拉长时,会有这一行放不下的情况,就像图片左边这个场景一样,第6个项目因为太长了放不上去,那个位置被空出来了,我们可以尝试使用。
grid-auto-flow: row dense;
结果就会得到右边的情形,7号自动的补了上去,
我们可能想让下面长度合适的填满这个空白,这个时候可以设置 grid-auto-flow: row dense,表示尽可能填满表格
单元格内容排列方式
justify-items
属性设置单元格内容的水平位置(左中右),align-items
属性设置单元格的垂直位置(上中下)
这里只以justify-items
做展示,另一个同理,只是一个水平一个垂直的差别
- start:对齐单元格的起始边缘。
- end:对齐单元格的结束边缘。
- center:单元格内部居中。
- stretch:拉伸,占满单元格的整个宽度(默认值)。
.container {
display: grid;
grid-template-columns: 200px 200px 200px;
grid-template-rows: 200px 200px 200px;
gap: 10px 10px;
justify-items: center;
}
在上面的代码中,表示单元格内部居中
单元格内部居左
justify-items: start;
单元格内部居右
justify-items: end;
对于justify-items
和align-items
属性,可以采用合并的写法
place-items: start end;
内容区域的排列方式
justify-content
属性是定义整个内容区域在容器里面的水平位置(左中右),align-content属性是定义整个内容区域的垂直位置(上中下)
- start :对齐容器的起始边框。
- end :对齐容器的结束边框。
- center :容器内部居中。
justify-content: start;
/*justify-content: center;
justify-content: end;*/
上面代码依次从上到下对应
stretch
:项目大小没有指定时,拉伸占据整个网格容器。
space-around
:每个项目两侧的间隔相等。因此,项目之间的间隔比项目与容器边框的间隔大一倍
space-between
:项目与项目的间隔相等,项目与容器边框之间没有间隔。
space-evenly
:项目与项目的间隔相等,项目与容器边框之间也是同样长度的间隔。
.container {
align-items: start;
}
上面代码表示,单元格的内容头部对齐,效果如下图
justify-content 属性、align-content 属性、place-content 属性
justify-content属性是整个内容区域在容器里面的水平位置(左中右),align-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;
}
这两个属性的写法完全相同,都可以取下面这些值。(下面的图都以justify-content属性为例,align-content属性的图完全一样,只是将水平方向改成垂直方向。)
start - 对齐容器的起始边框
end - 对齐容器的结束边框
center - 容器内部居中
stretch - 项目大小没有指定时,拉伸占据整个网格容器
space-around - 每个项目两侧的间隔相等。所以,项目之间的间隔比项目与容器边框的间隔大一倍
space-between - 项目与项目的间隔相等,项目与容器边框之间没有间隔
space-evenly - 项目与项目的间隔相等,项目与容器边框之间也是同样长度的间隔
place-content属性是align-content属性和justify-content属性的合并简写形式
place-content: <align-content> <justify-content>
如果省略第二个值,浏览器就会假定第二个值等于第一个值
设置多余网格
对于网格有显式网格和隐式网格,显示网格通过grid-template-columns
和 grid-template-rows
属性中定义的行和列,当实际行数或者列数大于设置的行列数时,就会有多余的网格,这些网格的宽高通过grid-auto-columns
和grid-auto-rows
属性来设置
.container {
display: grid;
grid-template-columns: 200px 200px 200px 200px;
grid-template-rows: 200px 200px ;
gap: 10px 10px;
grid-auto-rows: 50px;
}
在上面的代码中设置了4*2的网格,但是我们一共用9个项目,通过grid-auto-rows: 50px
设置了多余网格的高度
项目属性
这部分是关于项目的属性,也就是说这些属性要写到项目自己的身上,不能再写到container身上
指定项目的位置
实现的原理其实是指定项目的四个边框,分别定位在哪根网格线
- grid-column-start属性:左边框所在的垂直网格线
- grid-column-end属性:右边框所在的垂直网格线
- grid-row-start属性:上边框所在的水平网格线
- grid-row-end属性:下边框所在的水平网格线
.container {
display: grid;
grid-template-columns: 200px 200px 200px ;
grid-template-rows: 200px 200px 200px;
gap: 10px 10px;
}
.item-1 {
background-color: #55efc4;
grid-column-start: 2;
grid-column-end: 4;
}
上面的代码中指定了1号项目的左边框从第二条网格线开始,第4条网格线结束,因此将会占据2个网格
也可以使用span
关键字,来实现占2个网格这样的效果,可以将它理解为跨越的意思
grid-column-end: span 2;
表示的意思是:1号项目的左边框距到右边框跨越了2个网格。
对于上面的4个属性可以采用简写的方式,例如
grid-row: 1 / 4;
grid-column: 2 / 3;
这里的/
不是除号的意思,仅是占位的作用。其中的第一行代码,制定了上边框在第1条网格线,下边框在第4条网格线,第二行代码同理。
如果只写一个数字的话,默认跨越1个网格
注意:当我们遇到两个项目占据位置重叠时我们可以采用z-index属性确定上下关系,就像这样
.item-1 {
background-color: #55efc4;
grid-row-start: 1;
grid-row-end: 3;
grid-column-start: 2;
grid-column-end: 4;
}
.item-3 {
grid-row: 1 / 4;
grid-column: 2 / 3;
background-color: #74b9ff;
}
给1号和3号项目添加了属性,指定他们的占据位置,效果如左图
给一号盒子添加了z-index:1后,一号盒子到了上层
grid-area属性
在前面容器属性讲过grid-template-areas属性,当时只是知道了怎么划分区域,现在这个属性就是怎么把项目指定给区域
.container {
display: grid;
grid-template-columns: 200px 200px 200px ;
grid-template-rows: 200px 200px 200px;
grid-template-areas: 'a a a'
'b b c'
'e e c';
gap: 10px 10px;
}
首先我们先利用grid-template-areas
属性在容器上划分区域,上面划分了4块区域,下面我们通过给项目添加grid-area
属性,来给它指定到某个区域当中
.item-1 {
grid-area: c;
background-color: #55efc4;
}
上面的代码中,将1号项目指定到了c区域,也就是右下角2个网格
注意:2个区域之间需要紧挨,不能隔开