应用设计的 Figma 入门指南

软件开发的本质是对于想法和需求的不断澄清和最终实现的过程,在这个过程中会逐步调整需求和实现,以及考虑各种场景和边界条件。通过将应用设计和实际实现进行区分,可以让需求在前期尽可能的缩减设计-反馈路径循环周期,快速和准确的澄清需求,避免过早实现以导致应用交互模型和目标用户的心理模型差异过大而造成失败。

112 亿美元估值的“网页应用” Figma 能够帮助实现这一分离并促进前期需求的澄清并提高开发效率:通过基于组件的简单、可复用、可分享的早期设计稿、带有动画和各式设备预览的应用原型以及团队讨论和反馈支持。

Why App Design?

团队工作,有专职负责 UI 和 UX 用户交互的设计师。

个人项目,可以快速得到想法(草纸,Low Fidelity Design)和视觉(Figma, Sketch etc, Hign Fidelity Design)反馈。

Ps. 对于 Web 或者 Flutter 而言,App Design 可以压缩为想法 -> 应用,因为反馈实在是太快了,在 Web 的开发者工具中随意调整 CSS 就能即可看到变化,并且完成代码。在 Flutter 中热更新能在毫秒级别做出视觉反馈,并且带有之前操作的状态。但是这两者的代价是高昂的运行时成本:尽管 Flutter 运行时做了 AOT。因此想法反馈足够。

Ps. 对于 iOS/Android 原生开发而言,预览的速度没那么快,且很少能维持或者完全不能维持完整的状态。因此,外观调整起来不是很方便,因此其更加依赖外部视觉反馈。

尽管上述两种开发模式依赖的重点不同,在极端情况下可以忽略不太重要的步骤,但这样做是有代价的:为了预览而编写的代码通常缺乏可复用性(堆在一起),且外观强耦合某台设备(写死尺寸、静态布局)。而如果将 App 设计(想法和外观)的动作抽离出来,那么开发时可以着重提升代码复用度(复用组件、逻辑),且有时间对于不同设备尺寸、模式、色调、字体大小进行灵活处理,最后,通过单元测试保护逻辑,以保证在后续开发的功能增添、重构过程中不会将现有逻辑破坏,以使得 App 更加健壮。

另外,虽然设计和开发属于两个团队的工作,但需要彼此间的密切沟通,设计必须了解一个外观是否可以或者方便用何种现有组件或自定义组件实现,换言之,这些组件的样式以及其变体和潜力。最好的状态是,一个人即懂设计又是开发,这不是说继续中华田园敏捷那一套,脑海中设计,直接硬编码走起,而是说,一个人分饰不同的角色(Part1 Design,Part2 UI/UX,Part3 FullStack)。当然,一般情况下可能的是:开发或者产品拿着 Sketch/手绘的线框图和设计交流,要求高精度交互图和方案,而设计和实现这些方案的开发(前端、客户端)交流如何快速实现交互。

软件开发本质是对于想法的不断澄清和最终实现的过程,在这个过程中会逐步调整需求和实现,以及考虑各种场景和边界条件。对于这一目标,将任务划分成小块,将小块划分到不同的子任务是合理并且有效的解决方案,这里的子任务可以分为:设计、客户端编码、服务端编码。每个子任务需要考虑的内容并不相同,对于设计而言,外观和交互第一,而对于客户端编码而言,不同平台、设备环境、能力和性能、代码可复用则是考虑的要素,而对于服务端编码而言,API 的调用交互、性能限制、代码可复用度,逻辑正确性则是重中之重。因此,这里强调的是计划,没有计划的开发可能看起来快,但缺乏可维护性,并且在一个阶段很容易顾此失彼:比如客户端开发顾着调整外观而忽视了设备兼容和代码可维护,服务端开发只想着提供 API 但不考虑边界条件,没有单元测试。

最后,计划可能流于形式。在某些公司中,TR 文档的本意是规范特性开发计划,并且澄清特性能力和边界,其本意是好的,但对于开发更重要的是类图、调用图、数据库 Schema、单元测试和其代码覆盖率,如果不分青红皂白的要求写 Word 格式的 TR 文档,用文字形式描述特性、实现和其限制,那么这对开发而言是苦差事,且在修改代码的时候文档就很容易过时,导致文档的用途大大缩减。优秀的公司懂得规范的原理而不是追求其形式,代码中的注释:用途、属于的特性注解,类图、调用图的自动链接更新以及边界、Swagger 等 API 注释,代码的单元测试以及自动 CI/CD 的覆盖率计算和自动化测试,才是真正践行计划,而非让计划流于形式的关键所在。

How to Design?

intimate and familiar, and be delightful

iOS 最开始模仿现实物体的 UI 界面、高光效果

组件

Figma 左侧是层次,右侧是属性,上面是工具,中间是画布。属性界面选中原型,可设置各个组件之间的移动关系以及动画,点击右上角播放可预览,登录手机 App 可在手机端进行预览。

Ctrl 滚轮缩放界面
Alt + 移动复制元素
选中元素,按住 Alt 能查看其布局
Ctrl + G 分组合并
移动时按下 Shift 能够规定方向

可以用下图的方式为某个 Frame 添加图像填充或者渐变:

注意,对于超出 Frame 边界的元素,可先将其拖出边界,然后再拖进来,就会被裁剪而不是覆盖 Frame 了。

对于不想编辑的分组,可使用层次栏的小眼睛和锁定来处理,避免工作区杂乱:

Shift + A Auto Layout 自动布局某个分组中的多个元素,如下所示,可选布局的内部组件方向、组件间距、主轴和侧轴外边距,更多项目中可设置布局方式是 Space between 居中还是 Packed(表现为三个蓝色的点是分隔的还是紧邻的),此外这里九宫格还能调节对齐方式(Packed 有 9 个可选,Space Between 有三个可选),如果我们想要一个文本居中的按钮,选中这个组设置 Packed 居中对齐即可。添加了 AutoLayout 的 Group 会变成一个 Frame,便于添加点击事件。

使用约束面板约束元素位置,注意这里除了上下左右中,还可以约束左&右(需要下拉框选择)

比如下面的两个按钮,大按钮有边框,因此选择了左右下约束,而小文字则没有边框,选择左右对齐不合理(文字不能拉伸),所以选择居中和底部对齐。

以及占位符的全部约束:

Figma 内置的形状搭配填充、边框的不同属性,以及约束和 AutoLayout 已经能够表述大部分常见的界面元素了。对于复杂元素,可使用顶部的 Selection 进行合并、裁剪等。

low-fidelity Design

在跨职能团队中,线框图有利于让产品、开发和设计在一开始就参与讨论,考虑各种不同的实现方式。其要足够简单、通用并用于定义核心体验,聚焦于功能而非形式以保持快速迭代,最小化样式和自定义行为以防止重复返工导致的时间和精力浪费。

iteration ▸ prototyping ▸ feedback

- 是否需要过滤?根据什么过滤?
- 年份?时长?
- 是否需要详情页?
- 按照什么排序?
- 列表页应该展示什么信息最能满足需要?

Figma 支持将可复用的元素创建为组件,一般为组件单独放置一个 Frame,修改组件样式将直接影响所有“引用”组件的位置。此外,每个“引用” 不仅能够保持和组件完全相同,还可以进行定制化,之后统一修改组件样式的时候,这些自定义的样式会覆盖原来组件样式,就像类的继承一样。

high-fidelity Design

Figma 布局列表中带十字交叉的紫色元素为组件,空心紫色元素为组件的引用 —— 首次创建 Ctrl + Alt + K 的为组件本身,组件的移动还是组件,组件的复制都是引用。选中组件引用,可导航到组件本身,可替换为其他组件。

可以将多个组件合并为一个变量,此时可通过区分变量的属性 Properties 进行下拉替换,而不用每次都替换一个组件:

从别的素材中复制粘贴组件:iOS 组件 | Material Icons | Unsplash Plugin

特性:滚动时固定

特性:Mask

特性:裁切内容

特性:导出设计元素

排版

排版和颜色不仅仅是装饰,对产品的整体印象和可访问性都有着深远的影响,其可以帮助应用建立品牌形象,标识独特的身份。排版和颜色充分展示了设计的力量:通过一些小细节就能够对整个产品的用户感知觉与印象(产品交互模型与用户已有知识与记忆互相交织的心理产物)造成深刻的影响。

尽管有 MD for You 和 Apple HIG,但遵循这些指南并不会让应用开发者有完整的设计思考:关于为什么要这样那样设计的决策背后的原因的第一手经验。

简而言之,字体设计是一门以清晰易读的方式排列字母,向读者传达意图的艺术。字体设计影响视觉吸引力,并在读者中引发特定的情绪,给人留下对 App 的第一印象。其中可供设计师操作的一些排版属性有:

- 字体和样式 Font & Typeface:字体(衬线 or 非衬线,卡通,草书 etc)、字重、斜体
- 字重
- 字间距
- 行基线
- 行高(影响可读性、段落归属感)
- 段落间距(搭配行高使用)

为了进行排版,需要制定一系列彼此协作的不同外观但相同脉络的样式,以扮演不同的视觉角色。在此基础上,设计师需要利用这些样式实现功能互相区分但整体协调统一的观赏体验。

注意这里的一些原则:首先基于一个标准字号作为基础,然后向上向下扩展,这里以 1.3 作为倍数近似,注意边距一般用 8 的倍数,可被各种设备整除。

当设置好字体梯度后,为设计所需的不同字体角色分配大小、粗细、微调大小写等,之后将其应用为 TextStyle。相同样式可用于不同用途,而不是共享 Text Style - 32,这种语义标签方便后期修改(类似于 CSS 语义)。

一般而言,Component -> View 处理之后,再处理排版问题,将排版应用为 Text Style,之后修改 Component 的 Text 为 Text Style,其会自动应用于各个 View,即 Text Style -> Component -> View。

色彩

色彩和排版一样,在日常生活以及设计中扮演着重要角色,色彩引起某些情绪,并且在大脑中引起深刻的心理反应。正确使用色彩可以为 App 提供某些重要交互的准确的设计师意图的视觉反馈,比如突出错误、提供确认等。颜色也是建立品牌认知的重要方式,比如游戏主机三巨头:红、蓝、绿,CPU 显卡三巨头:红、蓝、绿。科技行业:蓝,饮食行业:红,黄。农业和果园:绿。

基于色彩理论(指导设计师有效选择色彩的一系列规则),可以通过三原色:红黄蓝来构建其他颜色,这样的第二色有:蓝黄 = 绿、红黄 = 橘、蓝红 = 紫。基于第一色和第二色的混合,可得到另外六种第三色,合起来就构成了色彩环(12 种颜色)。

色彩环上不同的颜色构成了 Hue 色调。对于每种颜色而言,都有一些属性,比如 Saturation 饱和度,饱和度是色彩的强度,高饱和度活泼且意图强烈,低饱和度更柔弱和微妙。自然界中并不存在色彩,色彩是环境光照射在物体上反射的剩余的光,因此我们看到的色彩和环境密切相关。与环境相关的色彩属性有:Value 亮度,从最亮 - 白色到最暗 - 黑色。Shade 阴影指的是纯色加入黑色的程度,其等价于一半的 Value。Tint 彩度 指的是纯色加入白色的程度,其等价于另一半的 Value。

在应用多种色彩的时候,设计上需要达到的目标很简单:凸显差异而又整体保持统一。从最基本的分类上来说,从色轮上下劈开,左侧为暖色,右侧为冷色,冷暖是一种对比。色轮上相近的颜色对比比较弱,看起来不是很清晰,WCAG 2 推荐对于普通文本使用 4.5:1 的对比度,对于大文本、图形和用户交互组件使用 3:1 的对比度。除去易阅读的需要外,在选中多种颜色的时候,高对比度表现了强烈的差异,而低对比度则表现了强烈的一致性,这些都是需要考虑的因素。

设计师通常选用一些颜色,称之为 Color Schemes 配色方案,其主要目的在于保证多种色彩的和谐统一,并且提供统一的品牌视觉。有很多不同的配色方案类型,比如单色(单色)、相邻色系(近似单色)、对抗色系(两色)、拆分互补(三色)、三角色系(三色)、矩形色系(四色)。

尽管调色盘是设计系统 - 色彩的主要方针,但有几点更重要的需要考虑:其一,对于应用而言,其他元素(大范围的用户内容)可能自带颜色,因此不必凸显应用自身的颜色:黑白灰即可(或者饱和度极高的颜色以至于用户轻易可以找到组件并导航)。其二,色彩系统是为了品牌服务的,要优先突出品牌特征,之后再考虑色彩平衡。其三,可读性最重要,哪怕色彩不平衡也要保证可读性。

Color Styles 和 Text Styles 类似,创建颜色填充到某个元素,然后将其添加到 Color Styles,和 Text Styles 不同,添加到 Color Styles 中的元素可以直接删掉(也可以不删),其不会影响 Color Styles 中的颜色。

基于色彩样式,我们构建出了 Text Style & Color Style -> Component -> View 的层次结构,这意味着上游的修改将直接应用于下游。对于实际实现:Web or iOS、Android 而言,也可以方便的基于颜色和文本样式实现界面,之后需要修改风格时,从设计到实现调整起来都很方便(vs. 写死的颜色适配暗色模式的痛苦)。

设计系统

什么是设计系统?简而言之,设计系统就是用来设计 App 的能够复用和彼此组合的组件的一系列标准。 遵循这种标准,对于消费者而言,不同产品可以具有相同的设计语言,强化品牌概念。对于设计者而言,基于设计系统的工作可以移除外观和表现的不一致性,通过重用色彩和排版,以及基于色彩和排版的组件、组件的复用来减少设计周期,构建稳定、一致的用户体验。对于开发者而言,设计系统可提供无缝的实现集成,避免样式实现时的硬编码以及后期维护、调整的困难,有利于多种屏幕大小、介质、设备和平台保持用户体验的一致性。

交互原型、动画和过渡

Figma 提供了强大的交互式原型设计,包括超出屏幕边界的滚动,而且可以为各个元素添加单击等事件,然后通过动画和过渡跳转到另一个 Frame 的其他位置等。交互式原型使得用户可以在产品的早期获得快速反馈,以避免完成开发后因为需求差异导致的难以负担的沉没成本。

Figma 的预览不限于客户端/Web,而且可以在移动端针对任意 Frame 或整体 Flow 进行预览,以更接近实际的用户体验。

优秀的过渡有助于建立视觉层次,告诉用户不同屏幕显示之间的关系:列表主屏幕和详细信息子屏幕,弹窗快速设置等。此外,细微的动画有助于表达动作的情绪,提供更多信息:比如按钮按下的缩小,手指移除后的回弹,输入错误密码时密码框的摇晃。

页面过渡时的栈入栈出动画 & 按钮点击后“假装”更新状态并滚动到相同页面同样位置的方法。

Figma 还提供了 Smart Animate 的功能,如果两个 Frame 中相同的层级有相同的元素名,且启用了 Smart animate(或其它动画勾选了 Smart animate matching layers),则将自动过渡此元素变化。比如下面所示的返回按钮在切换页面的放大缩小:

如果要实现更多 Smart animate,那么就需要比较脏一点的手法了,比如将下方白色卡片和上方大海报分别隐藏到第一个列表页的上面和下面,设置 Layer Pass through 为 0,这样过渡时就会有海报向下放大,详情由底部上升的动画效果了。当然,介于此,可交互原型和静态原型一般需要区分开,避免静态原型结构因为可交互而变得杂乱。以及,虽然 Figma 很容易实现动画,但这是以一些非常规的手段实现的 —— 为了动画而动画,在实际工程中,可能需要在可实现性、可维护性和动画效果之间做出选择(比如 SwiftUI 为了实现这里的上下合并显示详情动画就需要类似于 Figma 在列表页隐藏两个组件,点击后先填充图片和文本,然后对这两个组件的透明度和 Offset 应用动画,或者简单点,直接对详情页上下组件应用 Offset 的过渡)。

反馈和测试

Figma 提升了 UI 设计师的工作效率,从三个方面:①最小工具集实现的丰富的设计能力(相比较 Sketch 和 AI 裁剪掉的,以及基于字体和颜色面板、组件系统实现的);②原型工具,以最小的努力将设计直接带入到现实生活中。而这里的 ② 则是 ③ 的基础:快速获得产品开发初期各个参与者、早期用户的反馈的绝佳途径。软件开发是一种对想法的不断澄清的过程,太多的经验表明, 要在不同人员之间实现这样关于功能的最终愿景是一件多么麻烦和耗时的工作,更不用说需求总是在反馈中不断地变化,也因为外界环境而不断改变。因为早期模糊的需求以及早早确定的设计稿导致后期实现后发现不尽如人意,却再也没有时间去返工修改只能作罢,导致用户体验很差的例子比比皆是 —— 在中小公司尤其如此。