css grid随页面大小_学习 grid 布局:画一个 React 生命周期插图

07891c25d48d59a51f2c0cb1c713d3e7.png

React 的文档里,在介绍生命周期的时候,提供了一个生命周期的插图:

React Lifecycle Methods diagram​projects.wojtekmaj.pl
bfff3497a32adb0180b8d951e1ff0586.png

2b6a619a7aaf6a7e8555a1c3800cb875.png

第一眼看到这个插图,就觉得传统布局不太好实现这个结构,有可能是设定了 position: absolute 之后再调整每一个块的位置。但是打开开发者工具,发现整个布局都是使用 grid 布局实现的,正好还不太懂 grid 布局的具体使用,所以决定模仿它自己实现一遍。最终的效果先不放在这,反正是模仿,应该和上面那张图长得差不多。

grid 布局的基本概念可以在 网格布局的基本概念 学习,最好有点基本了解,本文主要描述实现的流程,对概念的解释有点意识流,应该大家都能看懂,但是细节还是得查资料。

打开 React 插图网页,再打开 Chrome 开发者工具,把鼠标挪到插图上,可以看到

512e8f0be0b735eb0ad6641ee13c74be.png

这些密密麻麻的蓝色块就是网格布局里面的一个块,但是一下子搞这么多东西太复杂了,我们先来画“创建时”、“更新时”、“卸载时”的后面三个块吧:

5e4fb95f1e6955ab46742b98beb45313.png

当然,图片里所有的元素都被定义在网格里,所以我们需要先定义一个网格容器。参数什么的我就完全复制 React 插图页面 CSS 里的值了(想改可以改,这里就是为了模仿的像一点)。

HTML

<!DOCTYPE html>

CSS

.

grid-template-columns & grid-gap

这里面有两个概念需要解释,grid-gap 和 grid-template-columns。

先看 grid-template-columns,一共定义了六列,每一列的宽度分别为 minmax(86px,auto),minmax(144px,auto),minmax(75px,auto),minmax(52px,auto),minmax(75px,auto),minmax(148px,auto)。(minmax 的含义就是这列宽度最小是第一个参数,最大是第二个参数)

grid-gap 的意思就是我们定义了列,那么列之间的距离应该是 20px。当然,grid-gap 同时定义了行和列的 gap,可以看下面的图来理解。

c44e8b62313767346f86900f22e47935.png
grid-template-columns, grid-gap

然后我们现在光定义了一个容器是 display: grid,定义了每一列有多宽,还定义了每行和每列之间应该间距 20px。那么我们怎么在里面画出一个元素呢。

我们在 div.diagram-container 里面放三个元素。

<

然后给这三个 section 设定一下背景颜色。

.

发现这三个块就画出来了。

689e9c75dfa9b674d915aba35edf1ed2.png

grid-area

决定这三个块位置的是他们的 grid-area,grid-area 后面的意思分别是 行起始线编号 / 列起始线编号 / 行终止线编号 / 列终止线编号。我们之前定义了 6 列,就会产生 7 条列的分割线,分别是 1、2、...、7,如下图所示。由于行我们之前没定义,所以我们用到哪,浏览器就会画到哪。

313951cecd97bc55787f73ebcb980f03.png

比如第一个灰色的部分,grid-area: 1 / 2 / span 23 / span 1,就是从第 1 条行线开始,到第 1 + span 23 = 24 条行线截止,从第 2 条列线开始,到第 2 + span 1 = 3 条列线结束。span 这种写法等价于 grid-area: 1 / 2 / 24 / 3。

那么对与第二个灰色的部分,从第 1 条行线开始,第 3 条列线开始,第 24 条行线结束,第 6 条列线结束,它的 grid-area 就是 1 / 3 / span 23 / span 3。第三个灰色的部分其实同理。

然后我们来画一个 getDerivedStateFromProps 块吧,先观察一下它的位置。

a1ada4103faa2c1c5634b02380b19e40.png

行从 6 到 8,列从 2 到 6,写出来就应该是 grid-area: 6 / 2 / span 2 / span 4(也就是 6 / 2 / 8 / 6)。

所以我们在 HTML 中补上这个 getDerivedStateFromProps 块。

<

因为 React 的页面用了 ul 和 li,所以我也就这么写了。需要注意的是,需要把 ul 的 display 设为 contents。

display: contents

只简单介绍下它的效果,详细可以参考

<display-box>​developer.mozilla.org
eb7c82f934bcf41dff3867ed165103b7.png

display: contents 可以理解为把该元素的所有子元素都在 DOM 树中向上提一层,然后不显示该元素。以上面为例,给 ul 设定了 display: contents 之后,展示的效果就和下面一样了(li 默认的样式还会在,树的结构实际并没有改变,只是显示改变了)。

<

然后再给 getDerivedStateFromProps 这个块设定点样式,就能有个样子了。

.

2f1b699bc2a8c816047e703b804aa6a8.png
getDerivedStateFromProps

剩下所有的生命周期方法都能用同样的方式画出来。

接下来考虑一下箭头怎么画。首先箭头有两个部分,一个是线,另一个是箭头。我们可以先产生一个块,线的话可以画成这个块的 border,箭头可以画成这个块的 ::after,然后用绝对布局调整一下箭头的位置。那么先考虑下图这个红色箭头(constructor 下面的)。

aa0f987acefd28b0bee991089a33a228.png

实现方式就是设定一个从行线 5 到行线 6,列线 2 到列线 3 的块,然后把它的 width 设成 0,同时加上左边框,然后用 relative 将它右移 50%。

(虽然这么做是 work 的,但我也没有搞明白,为什么 relative 50% 可以成功。relative 中使用百分比一般都是相对于父元素,按理来说,对于 grid 里面的一个 item,百分比相对的是 container 的大小,但实际的效果却是相对于 grid-area 所声明区域的大小...有点懒得翻标准了。)

所以这个 arrow 的 grid-area 就是 5 / 2 / 6 / 3。

这么写还不够,因为行线 5 到行线 6 围出来的块高度是 0,所以箭头的高度是 0,还需要将它的 margin-top 以及 margin-bottom 设成 -20px,让它的高度在上下两方延长(这也是个奇怪的 trick),填满上下各 20px 的 grid-gap。

所以写出来 arrow 的样式。

.

画箭头三角的过程用到了 clip-path,不了解的同学可以参考:

clip-path​developer.mozilla.org
eb7c82f934bcf41dff3867ed165103b7.png

然后再把箭头放到 HTML 中去。

<

然后我们就有个箭头了。

21dc804e25449bd45aca373fc0a4ac2f.png

会画箭头和块之后就好办多了...剩下的基本都是重复的体力劳动,照猫画虎,或者想自己发挥着调也是可以的。还有很多很多细节比如边框、hover、字体大小、箭头旋转的调节,具体对照 React 原页面做就好了,说的很详细会很啰嗦。

在一步一步把每一个箭头和块画出来,还有调整它们的过程中,对 grid 布局的理解会深入一点(想会用总得写几遍吧)。

放一张最终的效果图,还有一些没有说的实现细节:

980b13269bfb5480b6bb9e444f3ea872.png

虽然不是像素级别的复制,但是大概样子还是差不多的。

详细代码我放在了

07akioni/mock-react-lifecycle-methods-diagram​github.com
583c73475e35a285b8cfb74469029e5c.png

只是这两天的一个练手,欢迎指正和讨论。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值