CSS 之 Grid 布局
一、初识Grid布局
网格布局(Grid)是强大的CSS布局方案,它将网页划分为一个个的网格,通过任意组合这些网格来实现不同需求的布局方式。
上图这种布局,Grid可以轻松的实现(代码量少)
Grid布局与Flex布局的相似处:
都是容器 + 项目,都是可以指定项目在容器内部的位置。
Grid布局与Flex布局的不同处:
Flex布局是轴线布局,只能指定项目针对轴线的位置;Grid布局则是将容器分成行和列,生成单元格,然后指定项目的单元格,Grid布局更灵活更强大。
二、基本概念
1、容器与项目
采用Grid布局的区域(标签),成为“容器”(container),容器内部采用的网格定位的子元素,称为“项目”(item)。需要特别注意的是只有容器的子元素才能视为“项目”,孙子元素不能视为容器的项目。Grid布局只对项目生效。
2、行、列、单元格、网格线
1)行:容器里面的水平区域称为“行”(row);
2)列:垂直区域称为“列”(column);
3)单元格:行和列交叉区域称为“单元格”(cell);
单元格计算:正常情况下,n行和m列,会产生 n * m 个单元格
4)网格线:划分网格的线称为“网格线”(grid line);
水平网格线划分出行,垂直网格线划分出列。
网格线计算:正常情况下,n行有 n + 1 根水平网格线,m列有 m + 1 根垂直网格线
上图标记了对应的行、列、单元格、网格线
三、容器属性
1、display
指定一个标签为网格布局的容器
div { display: grid| line-grid; }
注意⚠️:设置为网格布局后,容器项目(item)的float、dispaly: inline-block、display:table-cell、vertical-align和column-* 等设置都会失效
2、grid-template-columns/grid-template-rows属性
容器指定了Grid布局之后,我们就要对行和列进行划分。grid-template-columns 属性定义每一列的列宽,grid-template-rows 属性定义了每一行的行高。
属性值:
1)固定值
.container { display: grid; grid-template-columns: 200px 100px 100px; grid-template-rows: 100px 200px 100px; line-height: 100px; }
效果图:
2)百分比
3)repeat()
当网格很多的时候,需要重复写同样的值,不方便,可以使用repeat()函数,简化重复的值。上面的代码可以用repeat()改写如下:页面效果相同
.container { display: grid; grid-template-columns: 200px repeat(2,100px); grid-template-rows: 100px 200px 100px; line-height: 100px; }
repeat函数接受两个参数,第一个参数是重复的次数(重复次数设置2次),第二个参数是所要重复的值(重复值可以设置多个 100px 200px 300px(一共是6列2*3))。
a、auto-fill 关键字:repeat函数还可以使用关键字 auto-fill
有时候单元格的大小是固定的,但是容器的大小不确定。如果希望每一行|每一列容纳尽可能多的单元格,这时可以使用auto-fill关键字表示自动填充。
.container { display: grid; grid-template-columns: repeat(auto-fill, 100px); line-height: 100px; }
效果图:
b、fr关键字:
为了方便表示比例关系,网格布局提供了fr关键字。如果两列的宽度分别是1fr和2fr,就表示后者是前者的两倍。
.container { display: grid; grid-template-columns: 1fr 2fr; line-height: 100px; }
效果图:
fr可以与绝对长度的单位结合使用,这时会非常方便
.container { display: grid; grid-template-columns:50px 1fr 2fr; line-height: 100px; }
效果图:
c、minmax() :
minmax函数产生一个长度范围,表示长度就在这个范围之中。它接受两个参数,分别为最小值和最大值。
d、auto关键字
auto关键字表示由浏览器自己决定长度。
.container { display: grid; grid-template-columns:100px auto 200px; line-height: 100px; }
效果图:
上面的代码实现了左右两列宽度固定,中间自适应
e、网格线的名称
grid-template-columns 属性和grid-template-rows 属性,可以使用方括号指定每一根网格线的名字,方便以后的引用。
.container { display: grid; grid-template-columns:[c1] 100px [c2] auto [c3] 200px [c4]; grid-template-rows:[r1] 100px [r2] 100px [r3] 100px [r4]; line-height: 100px; }
上面代码定义了3*3网格的八根网格线的名字。网格布局允许同一根线有多个名字,比如[r1-1 r1-2]
。
3、row-gap/column-gap/gap属性
row-gap属性设置行与行之间的间隔;column-gap属性设置列与列之间的间隔
.container { display: grid; grid-template-columns:[c1] 100px [c2] auto [c3] 200px [c4]; grid-template-rows:[r1] 100px [r2] 100px [r3] 100px [r4]; line-height: 100px; row-gap: 10px; column-gap: 30px; }
效果图:
gap属性是row-gap属性与column-gap属性的合并简写形式(只设置一个值时,row、column值相同)。
.container { display: grid; grid-template-columns:[c1] 100px [c2] auto [c3] 200px [c4]; grid-template-rows:[r1] 100px [r2] 100px [r3] 100px [r4]; line-height: 100px; gap: 10px 30px;//与下面两句代码等价 /* row-gap: 10px; column-gap: 30px; */ }
4、grid-template-areas 属性
网格布局允许指定“区域”(area),一个区域由多个或单个单元格组成
.container { display: grid; grid-template-columns:[c1] 100px [c2] auto [c3] 200px [c4]; grid-template-rows:[r1] 100px [r2] 100px [r3] 100px [r4]; line-height: 100px; grid-template-areas: 'a b c' 'd e f' 'g h i'; }
上面代码将网格划分了9个单元格,然后将这些单元格按a到i依次命名,即9个区域有自己的名字。
一个区域由多个单元格组成的情况:
.container { display: grid; grid-template-columns:[c1] 100px [c2] auto [c3] 200px [c4]; grid-template-rows:[r1] 100px [r2] 100px [r3] 100px [r4]; line-height: 100px; grid-template-areas: 'a a a' 'b b b' 'c c c'; }
上面代码将9个单元格分成了以 a、b、c为名字的三个区域。
如果某些单元格不需要划分区域,那么这些单元格以(.)表示
grid-template-areas: 'a . a' 'b b b' 'c . c';
注意⚠️:区域的命名会影响到网格线。每个区域的起始网格线,会自动命名为 区域名-start
,终止网格线自动命名为 区域名-end
。
5、grid-auto-flow 属性
设置子元素在容器中排列方式是“先行后列” row;还是“先列后行”column。
.container { display: grid; grid-template-columns:[c1] 100px [c2] auto [c3] 200px [c4]; grid-template-rows:[r1] 100px [r2] 100px [r3] 100px [r4]; line-height: 100px; grid-template-areas: 'a a a' 'b b b' 'c c c'; grid-auto-flow: column; }
效果图:
.container { display: grid; grid-template-columns:[c1] 100px [c2] auto [c3] 200px [c4]; grid-template-rows:[r1] 100px [r2] 100px [r3] 100px [r4]; line-height: 100px; grid-template-areas: 'a a a' 'b b b' 'c c c'; grid-auto-flow: row; }
效果图:
grid-auto-flow
属性除了设置成row
和column
,还可以设成row dense
和column dense
。这两个值主要用于,某些项目指定位置以后,剩下的项目怎么自动放置。
6、justify-items/align-items/place-items 属性
justify-items 属性设置单元格内容的水平位置;align-items 属性设置单元格内容的垂直位置 。
justify-items: start | end | center | stretch(默认值,拉伸,占满整个单元格的宽度);
align-items: start | end | center | stretch(默认值,拉伸,占满整个单元格的宽度);
place-items 属性是justify-items和align-items属性的合并简写形式
place-items: <align-items> <justify-items>;
如果只设置一个值,那么两个值设置为相等值
7、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为例
justify-content:satrt;//对齐容器的起始边框
效果图
justify-content: center;//容器内部居中
效果图
justify-content: end;//对齐容器的结束边框
效果图
justify-content: stretch;项目大小没有指定时,拉伸占据整个网格容器
justify-content: space-around;//每个项目两侧的间隔相等。所以项目之间的间隔比项目与容器边框的间隔大一倍
效果图