参考博客:《CSS Grid 网格布局教程》
使用场景
网格布局使用场景:九宫格图片展示、日历布局、自定义键盘布局
主要概念
容器(最外成元素)
容器可以是块级的,也可以是行级的
display: grid // 块级
display: inline-grid; // 行内元素
容器主要定义网格布局有几行几列以产生多少个单元格(这些单元格成为项目),例如3行3列则产生9个单元格
定义行列
// 产生3行3列,每行的高度100px,每列的宽度100px
.container {
display: grid;
grid-template-columns: 100px 100px 100px;
grid-template-rows: 100px 100px 100px;
}
// 可以只设置第一行的列数,后面多余的元素会根据第一行的样式进行布局
// 也可以使用百分比
.container {
display: grid;
grid-template-columns: 33.33% 33.33% 33.33%;
grid-template-rows: 33.33% 33.33% 33.33%;
}
// 简化写法
// repect()函数:第一个参数是重复的次数,第二个参数是所要重复的值
.container {
display: grid;
grid-template-columns: repeat(3, 100px);
grid-template-rows: repeat(3, 100px);
}
.container {
display: grid;
grid-template-columns: repeat(3, 33.33%);
grid-template-rows: repeat(3, 33.33%);
}
// 按比例生成
.container {
display: grid;
grid-template-columns: repeat(3, 1fr); // 项目根据容器的宽度等分成三份
grid-template-rows: repeat(3, 33.33%);
}
// 以下两种写法等价
grid-template-columns: repeat(2, 100px 20px 80px);
grid-template-columns: 100px 20px 80px 100px 20px 80px;
示例:生成两行两列布局
.artist-list {
margin: 14px 0 32px 0;
display: grid;
grid-template-columns: 168px 168px; // 设置两列
grid-template-rows: 76px 76px; // 设置两行
grid-column-gap: 9px;
grid-row-gap: 12px;
}
<div class="artist-list">
<div
class="artist-item"
v-for="n in 4"
:key="n">
<div class="artist-left">
<span class="artist-name">077<i class="icon-badge"></i></span>
<span class="text-follow">2341人关注</span>
</div>
</div>
</div>
存在的问题:当不满四个元素时(只有两个元素),生成的格子仍然占据这空间,如果在元素不固定的情况下会影响整体布局,例如朋友圈的九宫格照片栏,很多时候生成的格子并不是固定的
解决方法:只设置一行并设置列数(超出部分的元素会根据第一行的规定进行布局)
.artist-list {
margin: 14px 0 32px 0;
display: grid;
grid-template-columns: 168px 168px; // 设置两列
grid-template-rows: 76px; // 只设置一行
grid-column-gap: 9px;
grid-row-gap: 12px;
}
auto-fill、fr、minmax()
网格线的名称
定义每个轴线的名称。项目(也就是子元素),是可以设置起始行数、终点行数、起始列数、终点列数的。设置时,可以指定行列数(数值),或者行列名称
// 定义列名称:c1、c2、c3、c4,列名称:r1、r2、r3、r4
.container {
display: grid;
grid-template-columns: [c1] 100px [c2] 100px [c3] auto [c4];
grid-template-rows: [r1] 100px [r2] 100px [r3] auto [r4];
}
允许同一根线有多个名字,比如[fifth-line row-5]
网格区域的名称
可以指定某个项目在哪个区域内
// 容器
.container {
display: grid;
grid-template-columns: 100px 100px 100px;
grid-template-rows: 100px 100px 100px;
grid-template-areas: 'a b c'
'd e f'
'g h i';
}
// 项目
.item-1 {
grid-area: e;
}
间隔
grid-row-gap // 行与行的间隔
grid-column-gap // 列与列的间隔
grid-gap // grid-column-gap和grid-row-gap的合并简写形式
.container {
grid-gap: 20px 20px;
}
放置顺序:grid-auto-flow
对齐方式
justify-content // '整个内容区域在容器'的水平位置
align-content // '整个内容区域在容器'的垂直位置
place-content // align-content属性和justify-content属性的合并简写形式
justify-items // '单元格内容'的水平位置
align-items // '单元格内容'的垂直位置
place-items // align-items属性和justify-items属性的合并简写形式
grid-auto-columns、grid-auto-rows
如果有些项目被挤出原来的挤出网格,浏览器自动创建的多余网格的列宽和行高
项目属性
单个项目位置设置
grid-column-start // 左边框所在的垂直网格线
grid-column-end // 右边框所在的垂直网格线
grid-row-start // 上边框所在的水平网格线
grid-row-end // 下边框所在的水平网格线
.item-1 {
grid-column-start: 1;
grid-column-end: 3;
grid-row-start: 1;
grid-row-end: 2;
}
// 简写形式
.item-1 {
grid-column: 1 / 3;
grid-row: 1 / 2;
}
还可以指定为网格线的名字,这就是定义网格线的名称作用
span关键字,表示跨越多少个网格
.item-1 {
grid-column-start: span 2;
}
grid-area属性,指定项目放在哪一个区域
.item-1 {
grid-area: e;
}
grid-area属性还可用作grid-row-start、grid-column-start、grid-row-end、grid-column-end的合并简写形式,直接指定项目的位置
.item {
grid-area: <row-start> / <column-start> / <row-end> / <column-end>;
}
.item-1 {
grid-area: 1 / 1 / 3 / 3;
}
对齐方式
justify-self
align-self
place-self