通过本系列文章的上篇(理论篇),我们已对 Design Token 有了较为深入的理解。在本篇中,我们将为大家分享如何将Design Token在设计工具中有效落地并与开发协作。
1
Token 在设计工具中的落地
下面,我们将把 token 分为 style token、component token、template token、file token 来展开介绍其在设计工具中的落地策略。然而,不同设计工具的逻辑是不同的。如:Figma 没有 Sketch 中的 color variable,Sketch 也没有 Figma 的 layout grid。所以,以下我们会为最主流的 Figma 和 Sketch 提供不同的 Design Token 落地方案。
1. Style Token
Style token 落地的核心任务是:为不同类型的 style token 在工具中找到合适的载体。下面,我们将 style token 分为以下几类来进行讨论:
• Paint Token;
• Typography Token;
• Layer Style Token;
• Dimension Token;
• Transition Token.
Paint Token
Paint token 包括 color token、gradient token 两种类型。
在 Figma 中,选用 color style 作为 color token、gradient token 的载体。但因 color style 不支持 alias,所以在实践中,我们需为所有 color style 指向具体的色值。
在 Sketch 中,选用 color variable 作为 color token 的载体。我们需在 color variable 枚举所有会用到的 solid color,且需保证同一色值不会被多个 color variable 使用(枚举且不重复)。若设计稿使用的仍是更早的 color swatch,则可以使用 Color Variables Migrator 将其转换为 color variable。
在 Sketch 中,选用 preset 作为 gradient token 的载体。但因 preset 不支持调用 color variable,所以我们需要手动输入色值。
其中,gradient token 是一种典型的 composite token,它包含了 color、position 两个 property。
值得一提的是,在实践中,我们也可以将常用的图像填充设为 color style 或 present。
Typography token
Typography token 是一种典型的 composite token。它包含以下 property:
• font family;
• font size;
• font weight;
• letter spacing;
• line height…
在 Figma 和 Sketch 中,均选用 text style 作为 typography token 的载体。
需要注意的是,Sketch 中的 text style 比 Figma 多了 text color、text alignment 两个参数,即 Sketch 所指的 typography token 比 Figma 的多了 text color、text alignment 这两个 property。从实践中来看,Figma 的机制能为设计师带来更高的管理灵活度。
Layer Style Token
Layer style token 是一种典型的 composite token。它通常由多种如下 token 类型组成:
• Paint Token;
• Stroke Token;
• Shadow Token;
• Blur Token.
因为 Figma 没有 layer style 的概念,所以在 Figma 中,需通过手动组合 paint、stroke、effect 来生成 layer style。如,Sketch 中用一个 layer style 即可实现的模糊材质图层效果,在 Figma 中需用 paint 和 effect 组合生成:
由此,在 Figma 中,选用 effect 作为 shadow token、blur token 的载体,暂不支持 stroke token 的落地。
Sketch 则支持将 paint、stroke、shadow、blur 进行灵活打包。所以,在Sketch 中,选用 layer style 作为 stroke token、shadow token、blur token 以及 layer style token 的载体。
Dimension Token
在 Figma 中,选用 layout grid 作为 dimension token 的载体。其中,grid size 即 spatial system 中的 base unit。
Sketch 暂不支持 dimension token 的落地。
Transition Token
Transition token 是一种典型的 composite token。它可包含以下 property:
• duration (timing scale);
• delay;
• cubic bézier (timing function).
Sketch 和 Figma 都暂不支持 transition token 的落地:
• Figma 支持自定义动画,但不支持将其存储为复用样式;
• 在 Sketch 中,设计师只能调用 5 种预设的动画类型,不可自定义具体参数,且不支持将其存储为复用样式。
由此,我们建议设计师使用文档来管理 transition token。以下是我们在实践中的部分案例:
对于管理 easing bézier 的文档,我们建议同时提供可粘贴到 Figma 中的参数以及用于 CSS、iOS、Android 的参数。如:
多模式的处理
有时,设计师需要输出多种模式下的设计稿,如:
• 浅色模式;
• 深色模式;
• 高对比度模式;
• 子品牌(sub-brand);
• 特定域(domain,如 public、internal、partner)。
我们建议将不同模式的样式库分为多个文件,且与组件库解耦。这样做的好处是,设计师仅需制作一套模式的设计稿,即可通过一定的手段生成其他各种模式的设计稿。下面是我们探索出的具体做法(以浅色模式生成深色模式为例)。
在 Figma 中,将浅色模式组件库文件调用的浅色模式样式库(fundation)直接 swap 至深色模式样式库,即可生成深色模式组件库。
在 Sketch 中,通过 swap color libraries 用深色模式样式库(在实践中可只准备好深色模式变量库)和浅色模式组件库,即可生成深色模式组件库。
接着,再通过 symbol swapper 和 swap color libraries 用深色模式组件库和浅色模式设计稿,即可生成深色模式设计稿。
另一种做法是,通过 puzzle tokens 用浅色模式的组件库、设计稿、design token 文件直接生成深色模式的组件库和设计稿。
多业务的处理
有时,因业务的特异性,设计师需要突破基础的样式。我们建议,在使用基础样式库的同时,业务设计师可酌情维护业务样式库。主要有以下两个场景:
• 子业务要使用基础样式库中没有的样式;
设计师可在「业务样式库」中新增此样式。新增样式的命名在遵循已有格式的同时,还要保证其命名不与已有样式冲突,以便日后合入。如,基础样式库的前景色都叫「FG XX」,那新创的前景色也要用「FG XX」的格式,而不是自创一个「Foreground XX」的格式。直到有两个或两个以上的业务开始使用此样式,才可将其合入基础样式。
• 子业务要替换部分基础样式;
这相当于在继承基础样式的同时进行 override。设计师可自行添加、维护此样式,样式的命名应于要替换/覆盖的样式一致。如,若某一子业务要将微信品牌色「brand」全部变为黄色,则新创的样式也应叫「brand」,以便向开发同学传达替换/覆盖的设计决策。
总结
以下为各种 style token 在 Figma 和 Sketch 中的落地载体建议:
2. Component Token
对组件管理的研究在开发界已开展了较长时间。开发同学非常注重组件的可复用性与可扩展性。因此,设计师管理组件库时可从已有的代码中获取灵感。由此,此部分的核心任务是:在保证设计师使用效率的同时,尽可能将组件的设计逻辑与代码逻辑相契合。
但因 Sketch 本身的逻辑限制,设计师很难在 Sketch 中用更加贴近于代码的形式来管理 symbol。所以,下面我们仅给面向 Figma 的落地建议。
Main Component & Instance
这是两个许多设计师常常忽略的概念。Main component 指的是组件的源。Instance 指的是在设计中实际使用的组件副本,中文一般被翻译为「实例」。
Component Set
Component set 指的是含有多个 variant 的 component。一般来说,一个 component 对应一个 component token。而一个 component set 也对应一个 component token。
在代码中同属一组的 component 才应合为一个 component set。如,对于设计师来说,普通按钮和 FAB 等其他按钮都可以合为一个 component set。但在开发同学看来,他们是多种 component。所以,设计师最好也将他们拆为多个 component set。
另一个值得考虑的点是,设计师高频使用且在 assets 面板的缩略图中能清晰辨认的 component,可以突破代码表现拆为多个 component set。如,avatar 在代码中是一个 component,但 avatar 的每个 variant(square、circular、group)都是设计师高频使用的,且其缩略图清晰可认。此时,设计师可以考虑将它们拆成多个 component set。
Property 和 Variant
我们用 property 来区别一个 component set 中的各个 variant。
在 Figma 中,property 有 4 种类型。除了最为基础的 variant property,boolean property、instance swap property、text property 都是是用来传达 component 中有哪些部分是可以被修改的(从开发的角度来看,就是表达哪些部分是可以配置的),如:
• Boolean property:用来表示可以显示/隐藏 component 中的哪些图层。其包括 true 和 false 这 2 个 value(也可以是 on 和 off),在 Figma 的面板中表现为一个开关;
• Instance swap property:用来表示可以替换 component 中的哪些 instance;
• Text property:用来表示可以修改 component 中的哪些文本。
Property 和 Value 的命名
在遵循 Design Token 命名规范的基础上,还要满足如下规则:
• 同一组 value 的词性需相同(如「Hovered、Pressed、Disabled」而不是「Hover、Pressed、Grey」);
• 尽可能使用阿拉伯数字(如「2 Icons」而不是「Two Icons」、「Double Icons」);
• 避免使用实际参数命名(如「2A」而不是「16pt」);
• Boolean property 的命名需使用「Show XX」的格式(如「Show Icon」「Show Title」);
• 强调「仅有某元素」使用「XX Only」的格式(如「Icon Only」「Title Only」);
• 表达「用于某元素之上」使用「On XX」的格式(如「On Dark」「On Light」);
• 表达「相对常规的多出某元素」使用「+ XX」的格式(如「+ Icon」「+ Title」);
• 表达「有多个元素复合而成」使用「XX + XX」的格式(如「Icon + Title」「Title + Description」)。
Property 和 Value 的排序
对于 property 的排序,主要有以下两种思路:
• 可以按空间结构排(如从上到下、从左到右);
• 按逻辑关系排(如先放控制尺寸的 property、再放控制颜色的 property)。
对于 value 的排序,主要有以下两种思路:
• 按数值梯度排(如 S、M、L);
• 按使用频次排(如将最常用的 default、pressed 排在前面,很少用的 focused 排在后面)。
Variant Property 转换为 Boolean Property
在 Figma 中,我们可以将只有两个 values 的 variant property 的 values 设置为「True」「False」。这样,在调用 component 时,此 property 在侧边面板中就会变为更简洁的开关而不是下拉框。
这样处理后,Figma 仍会将此类 property 视为 variant property,但理论上,我们已经将其转换为 boolean property 了。
由此,我们建议,尽可能将 variant property 设置为更简洁的 boolean property,但要在满足以下条件的情况下:
• 只有两个 values;
• 未来不大可能增加更多 values。
如以下的「Inputing」property:
转换为 boolean property 后,若担心 value 的表意不够清晰或有歧义,可备注于 description。
如以下的「Filled」property:
若转换后 property 和 value 的表意不明,则可不转换。
如上一个案例中的「Type」property 被转换为如下表述后,就很难清晰理解其含义了:
若能妥善设置 property,component 的各个 variant 将会被自动标准化命名。如,checkbox 中 type property 的 value 为 on、state property 的 value 为 enabled 的 variant 的名称即为「Type=On, State=Enabled」。这样的命名更贴近代码中的表现,能让开发同学理解设计稿的过程变得更轻松。
内部构成
Component 内部的 layer、property、value 的命名和结构,以及 property 的类型均需尽可能贴合代码。下面的案例展示了一个 component 的代码及其在 Figma 中的构成:
FormGroup/index.js
<FormGroup>
<Input label="Email Address" type="email" required />
</FormGroup>
Input/index.js
<div id={id} className={classes} {...attributes}>
{label && (
<Label htmlFor={id} {...labelProps}>
{label}
</Label>
)}
{children}
</div>
FormGroup/index.js
<FormGroup>
<Input label="Email Address" type="email" required />
</FormGroup>
Input/index.js
<div id={id} className={classes} {...attributes}>
{label && (
<Label htmlFor={id} {...labelProps}>
{label}
</Label>
)}
{children}
</div>
内部交互
对于 component group 内的交互表现,可以尝试制作 interactive component,以方便设计师制作原型。如下方所示的 switch 即实现了组件内交互:
自适应
需支持变化尺寸的 component,使用 auto layout 及 resizing constraint 来实现自适应,与代码表现对齐。我们建议只处理实际场景下会发生变化的方向(横向、纵向)。在实践中,这为我们节省了不少精力。
总结
在实践中,我们仍很难将组件实现代码和设计的一一对应。但受益于更规范的命名和更科学的管理,我们进一步弥合了开发与设计之间的认知鸿沟,减少了大量不必要的沟通成本。
3. Template Token
Template 的概念来自于 atomic design,它能极大地提升设计的实现效率。
在 Sketch 中,使用 template 作为 template token 的载体。设计师仅需制作好 template 源文件后选择「File > New From Template….」即可。
Figma 尚不支持 template。
4. File Token
一般情况下,design system 需要以下类型的 file token:
• text(如:国家名、月份、星座等);
• image(如:用户头像、场景插画等);
• video(如:教育视频等);
• linked data(如:成组的综合类型数据等)。
在 Sketch 中,选用 data 作为 file token 的载体。
其中,text data 存放于 TXT 文件中,如:
`北京``上海``广州``深圳``...`
Image data 直接存放于文件夹中。
Linked data 存放于 JSON 文件中,如:
[
{
"Photo": "WeStore.jpeg",
"Location": "海珠区艺苑路",
"Title": "微信形象店 WeStore",
},
{
"Photo": "SUPERMONKEY.jpeg",
"Location": "海珠区新港中路",
"Title": "超级猩猩(客村全能店)",
},
{
"Photo": "Guangzhou Restaurant.jpeg",
"Location": "天河区体育东路",
"Title": "广州酒家(体育东路店)",
}
]
如果需要更为复杂或自定义地托管 file token,可以委托开发同学制作 data supplier plugin。Sketch 官方也给到了插件的制作指引,详见Do more with Data: Building a Data Supplier plugin for Sketch。
Figma 尚不支持 data。不过,我们仍能选用 color style 作为 file token 中指向 image 的 token 在 Figma 中的载体:
2
与开发的协作方式
在设计工具中管理好 design token 后,我们就可以将它们交付给开发同学了。Sketch 和 Figma 均原生支持 developer handoff。出于信息安全的考量或有更个性化的协作诉求,我们也可以通过以下方式输出开发同学可用的 design token 文件。
1. 输出样式库的 Token
Sketch
Color variable 是 Sketch 原生支持输出的唯一类型。可使用 Sketch web app 输出 color variable 的 token 文件,详情请见Using a Color Tokens export from Sketch。若需要输出更多类型,我们建议使用第三方插件Design Token Sketch Plugin。
Figma
Figma 不支持导出 design token 文件,但可使用第三方插件figma Token 导出。
2. 输出组件库、模板库的 Token
在实践中,我们通过 design guideline、design specification、component property 等文档向开发输出各个 component、template 的命名、构成、使用场景等详情,以让团队成员对其的认知更趋于一致。
其中,component property 文档是将 component「token 化」最为重要的文档。如下是我们使用的文档编排方式:
若有余力,还可以与开发协作实现一套所见即所得的预览器。
3. Token 文件的版本管理
对于 token 文件的版本号,我们建议采用如下格式:
[Major].[Minor].[Patch]
按此格式,就可以写出类似于「v 1.8.0」的版本号。其中,major 只有全面更新时才会更替,minor 一般指半年度版本,patch 则为更小的季度版本等。
更重要的是,我们需要在版本更新时向大家清晰地传达此次更新的具体内容。因此,我们需在合适的位置维护好组件库的更新日志(changelog)。而更新日志也可以结构化如下:
Design Token Documentation Update ([date]):
🎉 What’s New
• ...
• ...
🛠 What’s Modified
• Bug fix for ...
• Thing updated for ...
⚰️ What’s Moved to Graveyard
• ...
• ...
我们于本文给到了许多建议,这些内容兴许能对你帮助,但它们也很有可能并不适合你的团队。所以,可能还需要读者去做进一步的思考及探索。
不过,设计「设计过程」本身也是设计师的工作职责,design token 只是我们实现「更科学高效的设计」的手段之一。
因笔者认知、经验有限,本文难免有误读与疏漏,望读者谅解,并加以批评指正。
参考文献:
• Design Tokens Community Group. (2022, August 31). Design Tokens Format Module.
•Thomas Lowry. (n.d.). Typography systems in Figma.
•Ale Muñoz. (2018, October 2). Do more with Data: Building a Data Supplier plugin for Sketch.
•Lukas Oppermann. (2021, February 5). Building better products with a design token pipeline.
•Nathan Curtis. (2016, June 25). Tokens in Design Systems.
•John Choura. (n.d.). Stack mirroring: Designing for code and coding for design.
•Computer Hope. (2021, February 1). What is a Boolean?
•Facebook Inc. (n.d.). Components and Props –. React — A JavaScript Library for Building User Interfaces.
•Hoffman, C. (2021, August 13). What Is an API, and How Do Developers Use Them? How-To Geek.
— The end —
本文仅代表作者观点
如需转载,请注明来自WeDesign
Boren
小确幸之光
var first_sceen__time = (+new Date()); if (“” == 1 && document.getElementById(‘js_content’)) { document.getElementById(‘js_content’).addEventListener(“selectstart”,function(e){ e.preventDefault(); }); }
预览时标签不可点