共计 9449 个字符,预计需要花费 24 分钟才能阅读完成。
网格布局(Grid)是最强大的 CSS 布局方案,比 flex 还要强大。
它将网页划分成一个个网格,可以任意组合不同大小的网格,做出各种各样的布局。
如上面的图,正是 Grid 布局的应用,还有比如 管理系统的主页 dashboard,正是应用了 grid 布局实现的。
Flex 布局是轴线布局,只能指定 ” 项目 ” 针对轴线的位置,可以看作是一维布局。Grid 布局则是将容器划分成 ” 行 ” 和 ” 列 ”,产生单元格,然后指定 ” 项目所在 ” 的单元格,可以看作是二维布局。
一、概念
容器: 采用网格布局的元素
项目:容器的直接子元素 (和孙子元素无关)
行: 容器里面的水平区域
列: 容器里面的垂直区域
单元格: 行和列的交叉区域
网格线: 水平网格线划分出行,垂直网格线划分出列。
正常情况下,n 行有 n + 1 根水平网格线,m 列有 m + 1 根垂直网格线,比如三行就有四根水平网格线。
Grid 属性: 在 grid 布局中,有两类属性,一类是定义在容器上的,一类是定义在项目中的。
二、Grid 布局
给对应元素设置 display:grid 或者 inline-grid
<div class="container">
<span class="item item-1">1</span>
<span class="item item-2">2</span>
<span class="item item-3">3</span>
<span class="item item-4">4</span>
<span class="item item-5">5</span>
<span class="item item-6">6</span>
</div>
.container {display: grid;}
默认情况下,子元素都是块级元素,并且默认只有一列 (即 grid-template-columns: 只有一个值;)
如果将其设置为 display: inline-grid; 则可以看到照样是一列,只是宽度没有 100% 平铺,而是实际宽度。
注意: 设为网格布局以后,容器项目的 float、display:inline-block、display:table-cell、vertical-align 和 column-* 等设置都将失效。
三、容器属性
1、grid-template-columns
定义每一列的列宽。
.container {
display: grid;
grid-template-columns: 100px 100px 100px;
}
有几个值,表明指定了几列,没定义列宽的列会自动跑到下一行,而多余的列会占用空间。
如下图:
1.1 百分数
表示采用父元素宽度的百分比定义当前列的宽度。
.container {
display: grid;
grid-template-columns: 33% 33%;
}
1.2 repeat 函数
表示重复,第一个参数为几次,后面参数表示每次的值是多少
.container {
display: grid;
grid-template-columns: repeat(3, 33.33%);
}
repeat(3, 33.33%); 等于 33.33% 33.33% 33.33%
1.3 auto-fill 关键字
比如,每列是固定的宽度,可是一行究竟放几列呢?不知道,只知道随着屏幕宽度大小,自动补充剩余空间。
1.4 fr 关键字
fr 表示比例关系
.container {
display: grid;
grid-template-columns: 1fr 2fr; // 表示定义两列,这两列为 1 比 2
}
上面 grid-template-columns: 1fr 2fr; 等同于 grid-template-columns: 33.33% 66.66%;
甚至可以这么写
grid-template-columns: 150px 1fr 2fr;
1.5 minmax()
minmax() 函数产生一个长度范围,表示长度就在这个范围之中。它接受两个参数,分别为最小值和最大值。
.container {
display: grid;
grid-template-columns: 1fr 1fr minmax(200px, 1fr);
}
1.6 auto 关键字
表示由浏览器自己决定长度。
.container {
display: grid;
grid-template-columns: 50px auto auto auto;
}
上面 grid-template-columns: 50px auto auto auto; 等同于
grid-template-columns: 50px 1fr 1fr 1fr;
2、grid-template-rows
定义每一行的行高,默认为子元素的行高
.container {
display: grid;
grid-template-rows: 100px 100px 100px;
}
有几个值,表明指定了几行,没定义的行会采用默认的行高 (不会自动跑到下一列),而多余的行,会占用空间
如图,只定义了前三行,后面三行均采用默认值。
1、grid-template-columns 和 grid-template-rows 组合
默认先按 grid-template-columns 计算列数,然后自动计算行数。
当 grid-template-columns 和 grid-template-rows 组合是会出现,不匹配的情况。
比如一共 6 个项目,我定义了 3 列 (
grid-template-columns),那么也就是自动 2 行,但是此时又指定了 3 行 (grid-template-rows),那么此时就是 3 * 3 的网格。
而又有 一共 6 个项目,我定义了 3 列,那么自动就是 2 行,此时又指定 1 行,那么此时不会是 3 1,还是 3 2.
其中 grid-template-columns 和 grid-template-rows 指定的网格,我们可以称为标准网格,
而当实际的项目比定义的标准网格要多时。我们称超出的部分,为扩展网格。
标准网格和扩展网格共同组成了 Grid 布局的网格。
后面我们会通过另外的属性对于扩展网格定义宽高。
3、grid-auto-flow
划分网格以后,容器的子元素会按照顺序,自动放置在每一个网格。默认的放置顺序是 ” 先行后列 ”,即先填满第一行,再开始放入第二行,即下图数字的顺序。
grid-auto-flow 默认值为 row,即 ” 先行后列 ”。如果为 column,则先列后行。
.container {
display: grid;
grid-template-columns: 100px 168px 100px;
grid-template-rows: 137px 100px 100px;
grid-auto-flow: row;
}
.container {
display: grid;
grid-template-columns: 100px 168px 100px;
grid-template-rows: 137px 100px 100px;
grid-auto-flow: column;
}
grid-auto-flow 不管是 row 还是 column,都是后面的列排不下了,那么会换行,此时,前一行后面就会有空白。
而如果设置成 row dense 和 column dense,则前一行的空白会按顺序找出第一个能刚好放下的元素补齐。
.container {
display: grid;
grid-template-columns: 100px 168px 100px;
grid-template-rows: 137px 100px 100px;
grid-auto-flow: row;
}
.item-1{
grid-column-start: 1;
grid-column-end: 3;
}
.item-2{
grid-column-start: 1;
grid-column-end: 3;
}
此时会看到右上方有个空白,因为 item- 3 是紧跟在 item- 2 后面的。
.container {
display: grid;
grid-template-columns: 100px 168px 100px;
grid-template-rows: 137px 100px 100px;
grid-auto-flow: row dense;
}
.item-1{
grid-column-start: 1;
grid-column-end: 3;
}
.item-2{
grid-column-start: 1;
grid-column-end: 3;
}
而如果改成 row dense,则会发现 item- 1 和 item- 2 无法拍到 item- 1 后,换行了,接着按顺序找到了 item- 3 补齐在 item- 1 后面。
所以添加 dense 后,会“尽量填满空格”
4、row-gap
设置行与行的间隔(行间距)
.container {
display: grid;
grid-template-columns: 100px 100px 100px;
grid-template-rows: 100px 100px 100px;
row-gap: 20px;
}
5、column-gap
设置列与列的间隔(列间距)
.container {
display: grid;
grid-template-columns: 100px 100px 100px;
grid-template-rows: 100px 100px 100px;
row-gap: 20px;
column-gap: 20px;
}
row-gap 和 column-gap 可以简写为
gap:<row-gap> <column-gap>
如果 gap 省略了第二个值,浏览器认为第二个值等于第一个值。
.container {
display: grid;
grid-template-columns: 100px 100px 100px;
grid-template-rows: 100px 100px 100px;
gap: 20px 20px;
}
6、grid-template-areas
网格布局允许指定 ” 区域 ”(area)编号,以便在项目中使用。
(对现有布局不会产生影响)
也可以进行合并,即起同样的名字
.container {
display: grid;
grid-template-columns: 100px 168px 100px;
grid-template-rows: 137px 100px 100px;
grid-template-areas:
"header header header"
"main main sidebar"
"footer footer footer";
}
7、justify-items
设置容器下所有单元格内容的水平位置(左中右),网格线不动,基于网格线的位置。它针对的是所有的单元格。
justify-items: start | end | center | stretch(默认);
.container {
display: grid;
grid-template-columns: 100px 168px 100px;
grid-template-rows: 137px 100px 100px;
justify-items: start;
}
由于不是 stretch 后,项目的宽度都是自身的宽
8、align-items
设置容器下所有单元格内容的垂直位置(上中下),网格线不动,基于网格线的位置。它针对的是所有的单元格。
align-items: start | end | center | stretch(默认);
.container {
display: grid;
grid-template-columns: 100px 168px 100px;
grid-template-rows: 137px 100px 100px;
align-items: start;
}
上面的 justify-items 和 align-items 可以合并成一个属性:place-items
place-items: <align-items> <justify-items>;
.container {
display: grid;
grid-template-columns: 100px 168px 100px;
grid-template-rows: 137px 100px 100px;
place-items: start start;
}
9、justify-content
整个内容区域在容器里面的水平位置(左中右),网格线会动,基于的是 grid 的边缘。
justify-content: start | end | center | stretch | space-around | space-between | space-evenly;
space-around 和 space-evenly 区别在与,space-around 指项目和项目之间的距离相等,但是离边缘是项目之间的一半,而 space-evenly 即使再边缘也等于项目之间的距离。
.container {
display: grid;
width: 600px;
height: 400px;
background-color: antiquewhite;
grid-template-columns: 100px 168px 100px;
grid-template-rows: 137px 100px 100px;
justify-content: space-around;
}
.container {
display: grid;
width: 600px;
height: 400px;
background-color: antiquewhite;
grid-template-columns: 100px 168px 100px;
grid-template-rows: 137px 100px 100px;
justify-content: space-evenly;
}
10、align-content
整个内容区域在容器里面的垂直位置(上中下),网格线会动,基于的是 grid 的边缘。
align-content: start | end | center | stretch | space-around | space-between | space-evenly;
.container {
display: grid;
width: 600px;
height: 400px;
background-color: antiquewhite;
grid-template-columns: 100px 168px 100px;
grid-template-rows: 137px 100px 100px;
align-content: space-around;
}
.container {
display: grid;
width: 600px;
height: 400px;
background-color: antiquewhite;
grid-template-columns: 100px 168px 100px;
grid-template-rows: 137px 100px 100px;
align-content: space-evenly;
}
上面 align-content 和 justify-content 可以合并为 place-content。
place-content: <align-content> <justify-content>
.container {
display: grid;
width: 600px;
height: 400px;
background-color: antiquewhite;
grid-template-columns: 100px 168px 100px;
grid-template-rows: 137px 100px 100px;
place-content: space-evenly space-around;
}
11、grid-auto-rows
用来设置,通过 grid-template-columns 和 grid-template-rows 定义的标准网格大小,比实际的 项目数小时,多余的项目,即扩展网格的列和行的大小。
默认情况下多余的列和行,会使用项目中元素的实际内容的大小。
.container {
display: grid;
grid-template-columns: 100px 168px 100px;
grid-template-rows: 137px;
}
定义了一个 3 列,1 行的网格,一共可以放置 3 个项目,而下面是 6 个项目,也就意味后,item- 4 到 item- 6 是在网格之外的。那么就使用自身元素的实际内容大小
<div class="container">
<span class="item item-1">1</span>
<span class="item item-2">2</span>
<span class="item item-3">3</span>
<span class="item item-4">4</span>
<span class="item item-5">5</span>
<span class="item item-6">6</span>
</div>
但是我们可以通过 grid-auto-rows 来显示的指定,多余的部分的行高。它只影响多余的项目,对本来的网格项目不会造成影响。
.container {
display: grid;
grid-template-columns: 100px 168px 100px;
grid-template-rows: 137px;
grid-auto-rows: 50px;
}
12、grid-auto-columns
用来设置,通过 grid-template-columns 和 grid-template-rows 定义的网格大小,比实际的 项目数小时,多余的项目的列和行的大小。
默认情况下多余的列和行,会使用项目中元素的实际内容的大小。
但是和 grid-auto-rows 不同的是,grid-auto-rows 的多余行,会采用自身元素实际的行高,而 grid-auto-columns 的多余列,会填满剩余的空间 (即使是 span 也是,奇怪)
.container {
display: grid;
grid-auto-flow: column;
grid-template-columns: 100px;
grid-template-rows: 100px 100px 100px;
}
定义了一个 1 列,3 行的,一供可以放置 3 个项目。那么第二列就是多余的列。
使用 grid-auto-columns 后。
.container {
display: grid;
grid-auto-flow: column;
grid-template-columns: 100px;
grid-template-rows: 100px 100px 100px;
grid-auto-columns: 20px;
}
四、项目属性
前面的 12 个属性都是定义在容器上的,而下面的这些属性则是定义在容器里面的项目上的。
1、grid-column-*
grid-column-start 定义项目垂直方向的 的起始网格(整数。比如 grid-template-columns 定义了 3 个值,那么 grid-column-start 可以取 1 到 4)
grid-column-end 定义项目垂直方向的 的终止网格(整数。比如 grid-template-columns 定义了 3 个值,那么 grid-column-start 可以取 1 到 4)
.container {
display: grid;
grid-template-columns: 100px 168px 100px;
grid-template-rows: 137px 100px 100px;
}
.item-1{
grid-column-start: 1;
grid-column-end: 3;
}
item- 1 垂直方向从 1 开始,到 3 结束
2、grid-row-*
grid-row-start 定义项目水平方向的 的起始网格(整数。比如 grid-template-rows 定义了 3 个值,那么 grid-column-start 可以取 1 到 4)
grid-row-end 定义项目水平方向的 的终止网格(整数。比如 grid-template-rows 定义了 3 个值,那么 grid-column-start 可以取 1 到 4)
.container {
display: grid;
grid-template-columns: 100px 168px 100px;
grid-template-rows: 137px 100px 100px;
}
.item-1{
grid-column-start: 1;
grid-column-end: 3;
grid-row-start: 2;
grid-row-end: 4;
}
item- 1 垂直方向从 1 开始,到 3 结束,水平方向从 2 开始,到 4 结束
上面的 -start 和 -end 可以改成网格线的名称。
.container {
display: grid;
grid-template-columns: 100px 168px 100px;
grid-template-rows: 137px 100px;
grid-template-areas:
"header header setting"
"main main sidebar"
}
上面第一行定义了两列 header setting,所以他们的网格线分别为 header-start,header-end 和 setting-start,setting-end。其他也一样。
.item-1{
grid-column-start: header-start;
grid-column-end: header-end;
grid-row-start: main-start;
grid-row-end: footer-end;
}
3、grid-area
指定项目放在哪一个区域
.container {
display: grid;
grid-template-columns: 100px 168px 100px;
grid-template-rows: 137px 100px;
grid-template-areas:
"header header setting"
"main main sidebar"
}
.item-1{grid-area: header;}
其实我们发现
grid-area: header;
和下面的效果一模一样
grid-row-start: header;
grid-column-start: header;
grid-row-end: header;
grid-column-end: header;
4、justify-self
设置单元格内容的水平位置(左中右),跟 justify-items 属性的用法完全一致,但只作用于单个项目。
justify-self: start | end | center | stretch;
.container {
display: grid;
grid-template-columns: 100px 168px 100px;
grid-template-rows: 137px 100px;
}
.item-1{justify-self: center;}
5、align-self
设置单元格内容的垂直位置(上中下),跟 align-items 属性的用法完全一致,但只作用于单个项目。
align-self: start | end | center | stretch;
.container {
display: grid;
grid-template-columns: 100px 168px 100px;
grid-template-rows: 137px 100px;
}
.item-1{align-self: center;}
还可用 place-self 属性
place-self: <align-self> <justify-self>;