grid 入门:用 grid 布局轻松解决 flex 布局不太好做的一个问题
问题
最近一个需求如图:
大概是
- 数据上,react 组件从父组件接收两个数组,分别渲染出左右两列;
Array_1.map(渲染左列表组件)
Array_2.map(渲染右列表组件)
- 左右两列内容都是动态的,要求自适应文字高度,同一行其行高一致;
- 左列文字右对齐,右列文字左对齐;
原来数据是死的,用 flex 布局,左右分别两个 div,由于文字长度固定,不会有问题。
后来数据是动态的,可能造成同一行高度错位的问题。
在不改动数据结构的前提下,尝试用 grid 解决,发现异常轻松。
GRID 轻松解决
grid 布局和 flex 布局挺像,也是 容器 + item 的结构。
对父元素设置
.daddy {
display: grid;
}
就生效了
根据上面的图,我们想要一个两列的网格。这个需求可以通过 grid-template
网格模板轻松设置。
- 列
- 我们需要两列,宽度分别是 60px 180px,直接这么写就好了,及其简单
grid-template-columns: 60px 180px
- 行
- 我们需要行数是自适应的,直接 auto 就可以
grid-template-rows: auto
.daddy {
display: grid;
grid-template-columns: 60px 180px
grid-template-rows: auto;
}
至此,我们得到了一个网格结构。
不过是有问题的,文字内容没有按照预想的顺序排列:
原因在于,我们的数据是类似这样的:
... ...
// 通过 Array_1 渲染出
{
<div className="key">aaa</div>
<div className="key">bbb</div>
<div className="key">ccc</div>
<div className="key">ddd</div>
}
// 通过 Array_2 渲染出
{
<div className="value">AAA</div>
<div className="value">BBB</div>
<div className="value">CCC</div>
<div className="value">DDD</div>
}
... ...
grid 会自动按顺序一行行往下填充网格空格。
我们需要设置 key 是第一列,value 是第二列。
子元素的设置
grid 布局允许我们指定子元素出现在哪一列。
我们希望:key 是第一列。即,key 的范围在下图(从左到右)第一条竖红线 与 第二条竖红线 之间。
用代码表示 grid-column-start: 1;
即 纵向,从第一条红线开始; grid-column-end: 2;
纵向,到第二条红线结束;
即
// key 占第一列
.key {
grid-column-start: 1;
grid-column-end: 2;
}
// value 占第二列
.value {
grid-column-start: 2;
grid-column-end: 3;
}
于是,我们得到了一个新的网格:
key 的确在第一列, value 的确在第二列 … …
空网格的填充方式
问题出在了 grid 对空网格的填充规则上。
用于设置父元素的 grid-auto-flow
的默认值是 row
。即依次填充每行。
结合上面提到的,两个数组分别得到的数据,不难理解为什么会出现这样的情况。
该属性还有
-
column
依次填充每列 -
dense
尝试在网格中填充空洞
我们对父元素设置
.daddy {
... ...
grid-auto-flow: dense;
}
成功~
最后,我们对第一列规定右对齐
.key {
... ...
justify-content: end;
}
完美~
最后代码
.daddy {
display: grid;
grid-template-columns: 60px 180px;
grid-template-rows: auto;
grid-auto-flow: dense;
.key {
grid-column-start: 1;
grid-column-end: 2;
justify-content: end;
}
.value {
grid-column-start: 2;
grid-column-end: 3;
word-wrap: wrap;
word-break: break-word;
}
}
grid 真的十分方便!
上一篇: Android面试知识点汇总(一)
下一篇: Nginx快速入门