网格布局
网格 grid 是二维布局,它的功能有:
可以用行列来定义网格,可以设置行列的大小,或者让它们根据内容自行调整。
容器的直接子元素会被自动放入网格中。或者放在指定的位子中。
网格中的线条和区域可以被命名来更好地放置物品。
闲置空间在网格轨道( track )之间分配。
物品可以在网格中进行对齐。
相关概念
网格线 Grid lines
网格线横纵分布,从 1 开始编号(按照书写顺序)。
网格轨道 Grid tracks
轨道是两条网格线之间的空间(注意不是单元格)。
网格单元格 Grid cell
网格区域 Grid area
由多个单元格组成的矩形区域。
间隔 Gaps
网格轨道间的间隙。
网格容器 Container
.container {
display: grid;
}
网格物品 Item
<div class="container">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
设置行列
创建一个两行三列、10px 间隙的网格:
.container {
display: grid;
/* 这里三个值对应三列 */
grid-template-columns: 5em 100px 30%;
grid-template-rows: 200px auto;
gap: 10px;
}
打开 DevTools ,选中一个网格,然后在选项卡里找到布局(layout)-> 显示行号,同时勾选上网格覆盖中的目标网格容器,就可以看到网格线编号了。
fr
单位只在网格布局中使用,和弹性盒子中的 flex 权重分配类似
grid-template-xxx
grid-template-xxx
上可以用的关键词及函数:
auto
自行伸展;min-content
尽可能的小;max-content
尽可能的大,可能会导致溢出,因为字符串不会换行;fit-content(x)
大小先随内容伸展,当网格轨道大小超过x
会自动换行;minmax()
可以用这个函数设置轨道的最小最大值,参数可以是关键词;repeat(n, size)
用这个快速创建相同的列;第一个参数是数量,第二个是大小。一行中可以重复用这个函数。
自动放置
如果你不想指定列的数量,可以用 auto-fill
或 auto-fit
关键词作为 repeat
的第一个属性值。
比如,自动填充,每列 200px :
grid-template-columns: repeat(auto-fill, 200px);
又比如,每列自动伸展,且最小值应当为 200px :
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
auto-fit
与 auto-fill
主要区别在于只有单行内容(子元素宽度之和小于容器宽度)的情况下,auto-fit
会自动横向伸展容器,而 auto-fill
会保持最小值。当网格轨迹被完全填充时,这两个关键词是没区别的。
自动放置
Grid 布局默认按行排列,也可以按列排列(该属性和书写模式有关):
grid-auto-flow: column;
将物品放置在指定位置
用 grid-xxx-start
or grid-xxx-end
指定物品横跨的列(行)数。
这里
xxx
为row
或者column
,下同。
比如横跨两列:
.item {
grid-column-end: span 2;
}
值默认为 auto
,即 1 ,或者直接指定列线号。或者用 grid-xxx
合并 start
和 end
,用斜线 /
隔开两值。
这种跨越多行(列)的行为可能会导致空单元格的产生,可以设置容器的 grid-auto-flow
属性来让空单元格自动填充:
grid-auto-flow: row dense;
使用“基于行的定位”( line-based positioning )可以将物品直接覆盖在别的物品上。覆盖顺序会由加入顺序决定,或者用
z-index
属性来设置覆盖顺序,默认为 0 ,大数在上。
未明确网格
在一些情况下,比如:
设置了
grid-template-columns
,但没设置grid-template-rows
,行轨道会自动调正自己的大小。设置了一个超出范围的
grid-column-end
,网格容器会自动创建轨道来使之生效。
这些都被称为未明确网格( Implicit grid )。
在明确定义的网格中,可以用负数表示网格线,表示倒数,但是在未明确网格里是无法这么使用的。不过可以用 grid-auto-xxx
设置未明确轨道的大小。
网格线及区域的命名
给网格线命名(后面可以直接用这些值):
.container {
display: grid;
grid-template-columns:
[main-start aside-start] 1fr
[aside-end content-start] 2fr
[content-end main-end];
}
给区域命名(在容器的子元素):
header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.content { grid-area: content; }
footer { grid-area: footer; }
当所有要用的区域都命名后,可以应用在区域模板里:
.container {
display: grid;
grid-template-columns: repeat(4,1fr);
grid-template-areas:
"header header header header"
"sidebar content content content"
"sidebar footer footer footer";
}
使用区域模板应当:
必须使用 任意数量
.
符号来表示空白;使用重复的名来横跨轨道;
横跨的形状必须是完整矩形。
用 grid-template 简写
grid-template
可以整合 grid-template-areas
grid-template-xxx
的属性值:
grid-template: 100px 1fr / 50px 1fr;
grid-template:
"a a a" 40px
"b c c" 40px
"b c c" 40px / 1fr 1fr 1fr;
grid-template:
[header-top] "a a a" [header-bottom]
[main-top] "b b b" 1fr [main-bottom]
/ auto 1fr auto;
更多例子可以看 grid-template 。
对齐方式
flexbox 的对齐、空白分配属性都可以在 grid 中用:
justify-content
&align-content
justify-self
&align-self
justify-items
&align-items