pic
2020-12-30 07:30
(本文约3000字,预计阅读时间3分钟)
上一篇,我们一起学习了如何使用智能布局功能来实现组件的动态自适应。今天,我们来讲解下组件的动态响应式,这是组件库搭建的重中之重,也是sketch搭建组件库系列的终篇!
什么是动态响应式
响应式估计大家都不陌生,专业点讲就是,系统对不同的媒介(运行web的设备)及视窗(显示网页的浏览器窗口)所产生的适应变化。
做跨设备响应的朋友接触会比较多,从大屏(pc)、中屏(平板)到小屏(移动端),为了适配不同的设备需要产出至少三个断点的设计方案。
而要说市面做全局响应做的比较好的,antD算一个,大家可以去官网感受下蚂蚁是如何实现媒介、视窗的完美响应的。

回归到主题,组件的响应式和页面响应式其实本质都是一样的,都是元素跟随父级的所产生的适应变化。只不过组件的父级可以是一个编组、也可以是页面。
对组件进行响应式处理意义重大。拿前文的这个商品卡片举例,如果我们对其不做任何适配处理,那在进行尺寸拉伸时就会这样:

图片、间距变形失真,整个组件都遭到了破坏,效果非常得挫。
但是如果我们对组件进行一个适配处理,一切都变得非常自然柔顺:

而在sketch中,实现动态响应效果的功能就是Resizing(后面统一翻译为弹性布局)
关于弹性布局
所谓的弹性布局,就是让元素跟随父级编组或者画板的尺寸变化而产生的适应变化。在sketch中对应着右侧面板的Resizing功能。包含Pin to Edge(固定边缘)、Fix Size(固定尺寸)和Preview(预览)。(请忽略中文版截图蹩脚的翻译。。)

不过要注意的是,弹性布局需要拥有一个参照物实现尺寸和位置关系的控制。所以弹性布局面板只有在元素存在父级关系时才会出现,这里的父级包括编组和画板。如果元素没有任何父级关系包裹,仅仅在一个页面中,那并不会出现弹性布局的功能。
拿商品卡片举例,一开始这个卡片存在于一个画板中,这就意味着它是作为一个子级存在于画板父级之下,所以会出现弹性布局功能。

但是,当我们将画板给它撤掉,让它独立得存在于页面中,你会发现弹性布局功能消失了。就是因为此时的商品卡片缺失了父级关系,没有办法使用参照物来控制其尺寸和位置关系。

不过,当我们将其编组后,弹性布局再次出现,就是由于商品卡片再一次获得了父级关系,只是这次的父级由画板变更为编组了。

固定边缘
固定边缘(Pin to Edge),即固定元素到边缘的内间距。
不论怎么拉伸,我自岿然不动。
拿商品标签举例。未固定边缘时,拉伸会直接破坏组件内的间距,显然这不是我们想要的。

我们希望内容与与左侧边缘的内间距保持不变,这该怎么搞呢。
非常简单,进入源组件页面,在右侧弹性布局面板中将内容固定到左侧边缘即可。

回到标签组件,就会发现不论我们怎么拉伸,内容始终是固定在左侧边缘的。

关于固定尺寸
固定尺寸(Fix Size)即固定元素自身的尺寸大小。
拿商品图为例,没有固定尺寸时,拉伸后会失真变形。

我们想要商品图尺寸不随编组或者画板尺寸的改变而改变,所以选择固定图片的宽高。

不论我们怎么拉伸编组,82年的拉菲尺寸依旧保持不变。

关于预览
我们在选定一种属性后可以实时在右侧窗口中预览到效果,以帮助我们判断是不是自己想要的。注意,我们在点选后预览动画只会播放一次。如果想要再次观看效果,需要hover在预览窗口上哦~

不过在很多组件中,固定边缘和固定尺寸往往是相互搭配、多次使用,下面我们通过一些实战来巩固。
手把手实战环节
依旧是我们的这个商品卡片,我们的目标就是让卡片中的所有元素能够适配任意的尺寸,包括不同的宽度和高度。

第一步,确定参照物。
我们确定整个商品卡片这个组件为响应参照物,后续所有的子级元素都要跟随它尺寸的变化而变化。
第二步,确定响应策略。
在这一步,我们确定卡片中所有元素的位置关系和尺寸的响应规则。
首先,我们需要商品标题、商品价格和标签保持下方和左侧的内间距固定,同时它们的尺寸保持固定(已经提前建立了从左至右的自适应规则)所以我们固定左下边缘和宽高。
其中,标签由于是嵌套在商品卡片组件当中的,所以我们需要对标签组件内部做一次弹性布局。固定左侧边缘和宽高即可。

商品图我们希望保持尺寸不跟随改变,所以直接固定其宽高。商品图背景需要始终保持四个方向内间距的一致,因此固定上下左右的边缘。

最后来个弹性布局的总览。

第三步,响应效果测试。
到了激动人心的测试环节了!嗯,看着相当完美。任意尺寸都能轻松hold住。

当然,这一步环节的效果如果不在我们的预期之内,需要返回检查每一个元素的弹性布局在哪里出了问题,比如文字的对齐方式啊,比如父子级的关系啊等等,反复调试~
弹性布局的嵌套
弹性布局是可以嵌套使用的。
比如,我对A使用了弹性布局,那么A的父级B也可以使用弹性布局。一层层嵌套下去,就可以应对那些复杂页面的响应效果。只是嵌套的调试适配较为麻烦,而且很容易在某个环节忽略掉。
这里我借鉴了幺零三大佬所使用的办法,将具备父子级关系的元素一层层得逐级拆解,并在每一层分层进行弹性布局规则制定。
比如这个页面,它包含了较多的层级,如果直接草率上手做弹性布局会很麻烦,而且毫无逻辑的做法也很低效。正确的做法是一步步拆解后分层展开。

为了便于阅读理解,下面每一层的版块和元素抽象成了骨架图。
第一层弹性布局
首先,从一整个版面来看,我们确定整个画板作为响应参照物,而内容区域需要保持不变的安全边距。所以我们直接固定内容区域四个方向的边缘。

第二层弹性布局
接着,我们对内容区域进行拆解。现在我们的弹性布局对象变为拆解后的四个版块,而参照物依旧是整个画板。我们希望搜索框和banner的高度与上方间距保持不变,因此固定高度和上方边缘。商品版块宽高可以自由变化,所以仅固定上方边缘。

第三层弹性布局
最后,我们对各个版块再次拆解,绝大部分被拆解为了最小颗粒。此时的弹性布局子级对象变为了这些更加细分的元素,比如暗提示、图标、大标题、折扣标等等。而响应参照物则变为了元素所依附的父级。比如搜索框是暗提示和图标元素的父级,而banner就是文字、按钮和图片的父级。最后的布局规则如下,具体逻辑不再赘述~

基于这个拆解的步骤,我们可以清晰得在每一层级进行分层弹性布局~
来看下骨架图的响应效果,没啥问题。

再来看下界面的响应效果~可以

最后
sketch搭建组件库系列就此结束了,从组件的搭建、到组件的动态自适应、再到组件的动态响应式,这三个环节缺一不可。不过很多东西我自己也在摸索阶段,所以文章尚且不能面面俱到。后续有任何的疑问或者建议,欢迎随时留言或者私信👏👏
但愿这篇文章对你有所帮助。