目录
Grid专为布局而生。Flexbox是沿着两条轴排列分布,定义空间的分配。Grid则是把子结点布到网格中,这个网格可以是预设好的几行几列,也可能是自动生成的隐式的网格,总之头脑中始终要有一个“网格”的意象。Grid的规则属性很多,其中不乏一些是shorthands。我们需要先充分理解Grid模型,才能得心应手。在布局上,它绝对是一柄利器。兼容性前面说了,目前PC端上支持还是比较成熟的,移动端上不建议用。
结构划分以及组成
- 其中Gridline为网格线,Row为行,Column为列,Grid Cell为格子,Grid Area为网格区域 。
代码实现
<div class="wrapper">
<div class="card">1</div>
<div class="card">2</div>
<div class="card">3</div>
</div>
规划网格
.wrapper{
display: grid;
width: 300px;
height: 100px;
grid-template-rows: 1fr 1fr;
grid-template-columns: 1fr 1fr;
}
tags: 单位fr是分数的缩写,有几列就定义几个。这么写看上去有点傻,可以用repeat,改起来更方便。
grid-template-rows: repeat(2, 1fr);
grid-template-columns: repeat(2, 1fr);
当然也有合并的写法:
grid-template: repeat(2, 1fr) / repeat(2, 1fr);
定位格子区域
cell按照template布到网格中之,此时三个盒子的定位分别为:
在Grid里用grid-row和grid-column这两个属性定义。比如cell 3默认定位:
grid-row: 2; // 第二行
grid-column: 1; // 第一列
如果想让cell 3的宽度充满,定义width是无效的。它的身份是Grid Cell,宽度默认就是1个格子的宽度,这里定义的就是1/2的容器宽度。可以定义grid-column的起始位置,所以可以这样:
grid-column: 1 / 3; // 意思是它在列上的定位从第1根网格线到第3根。
还可以用span指定相对跨越的数值,如:
grid-column: 1 / span 2;
隐形网格
在日常开发中肯定存在动态更新节点的情况,如果不定grid-template。定义cell 3的grid-column: 1 / span 2此时,cell 3横跨3条网格线也就是2个格子,于是就会认为有2列。如果改成span 4,就变成4列的网格。由于没有明确定义格子的宽度,默认是平均分布,但当内容变长,相当于列宽会取最大宽度,空间不够就会挤压其它格子,挤压到min-content的宽度(如图)。
可以在容器上定义grid-auto-columns: 1fr 限制它。同样,如果想保持行的高度一致grid-auto-rows: 1fr 。
效果展示
.wrapper{
width: 400px;
display: grid;
grid-auto-columns: 1fr;
grid-auto-rows: 1fr;
grid-gap: 1em;
}
.card {
height: 200px;
display: flex;
justify-content: center;
align-items: center;
font-size: 1.25em;
border: 1px solid #dd9ffd;
border-radius: 1em;
background: #ffdcfe;
}
.card:nth-child(3) {
grid-row: 2;
grid-column: 1 / span 2;
}