查看原文
其他

快来用设计令牌升级你的样式体系吧!

肆二 淘系前端团队 2021-08-10

众所周知,我们目前主流的设计稿交付方式还是依赖不同端的开发分别利用一些设计稿生成代码的工具,再进行设计稿还原。而每一次设计迭代,都需要去抱各个端的大腿,将需要变化的设计要素、组件一一传达给前端(这里就涉及到H5, Weex, Flutter等各种框架了)、客户端(iOS、安卓,甚至是鸿蒙)。

这里每一端的开发都需要先理解设计小姐姐的诉求,然后找到相应的UI代码去进行变更。而在理解设计这一层,往往就已经问题多多,前端不理解设计里的规范,也看不出来实现了以后没有还原的问题出在哪……


而Design token就可以解决以上的尴尬,帮助设计规范的落地无缝衔接生产,也能让前端在编写UI代码时得心应手。

什么是Design Token

Design Token是用来将设计系统里的带有具体值的参数用层层递进的命名空间来架构的一套设计工程化的体系。它存储了用户界面样式里一切可被参数化的值,使用token体系可以帮助我们实现具备一致性和可延展性的产品体验。

通常一套完整的设计系统包含以下定义:

  • 色彩 Color
  • 字体 Typography
  • 尺寸与间距 Space (dimensions, padding, margins, etc)
  • 形状 Shape
  • 海拔(阴影) Elevation
  • 图标与插图 Iconography and Illustrations
  • 动效 Animation
  • 声音 Sound
  • 触觉(振动)Haptics

这里面所有的类型,包括动效参数、声音、甚至是跟触觉系统相关的交互界面参数都可以被token化。设计语言不再只是文档中大段的场景和规则描述,而转译成了能直接在前端工程文件中被友好使用的key和value。

设计规范之所以成为被不同域和团队使用的一套规则,说明里面定义的场景是具有一定通用性的,规范了在设计工作中相对被高频遇见的问题的解决方案。而design token就是对设计规范的工程化承接方式。任何被相对高频使用的样式属性,都可以成为一个token。

它好比是设计师和前端开发人员之间所制定好的一套编码标准和协议,在UI样式实现过程中,需要尽可能的使用定义过的token,尽可能避免使用非规范内的样式值。因此对于规避设计和UI开发之间由于工作语言不一致导致的差错,以及不同系统、不同平台、不同域、不同团队之间的设计表达和实现一致性,有着极大的作用。

为什么要用Design Token?

Design token是将设计系统和UI工程体系无缝衔接的一种方法。通过制定一套完备的token体系,为设计系统的迭代、维护、使用和落地都有着极大的帮助。

🌰 1号栗子:小明作为设计系统的维护者,制定了产品里栅格系统里网格的基数为4px。小飞是新来的一名设计师,在一个新页面A里将卡片的上下间距设置为16px。而小黑在一个历史页面B的设计里卡片的上下间距是12px。由于小明在设计系统里并没有制定对于这种细节的规范,导致了两个页面在实现时间距的不一致。

🌰 2号栗子:小黑接到了一个适老化需求,需要为B页面设计一版适老化UI,字体更大,间距更大。这时前端小姐姐则需要根据小黑的新设计写一套新样式代码,而小明又需要根据这个新场景去更新自己的设计系统以及进行规范的宣讲。

🌰 3号栗子:公司老板说我们app的品牌视觉需要换新,主品牌色由沉闷的暗橙色变为更加活泼的亮黄色。研发老大掐指一算,这每个页面从设计到开发,包括web, iOS, 安卓都需要花上不少时间呀,要是能一键换肤可多好。

而Design Token就可以很好的解决以上问题:

  • 对于使用场景进行了语义化的描述,使得设计决策的过程可以很简单,而不需要dive in到非结构化的、迭代很难通知到整个团队的规范文档中
  • 通过由抽象到具体的层级架构保证了任意一级的值的变更不会影响到上级或下级的稳定性,比如品牌色调整了色值,直接替换该token的值,所有引用该token的变量值都会自动更新。同时通过像Style Dictionary的工具可以将一份token文件转化成不同格式的样式文件,适用于多种前端客户端框架
  • 保证了生产环节的一致性,在编码过程中,样式变量可以以自动提示的方式确保使用场景的明确性,而不只是一个无语义的value

VS code里对于具体值的提示


还可以做个小插件实现更友好的token-value提示


如何将Design System与Design Token做好映射关联

在我的实践过程中,如下的token体系可以灵活变化不同上下文中的取值,也便于理解使用的:


  • Global token, 即全局token, 用于管理最基础的样式属性取值,不带有任何语义。在颜色中对应各HEX值,rgba, HSV等具体色值,在字体中对应字号大小、具体字重等,在间距中对应栅格阶梯……
  • Alias token, 是带有一定抽象语义的token, 比如color-background-primary, 即描述了该颜色用于主背景,但并没有说明具体用在什么组件。
  • Component token,即最终用于具体组件的token, 比如button-color-background-primary-active 就描述了该token具体在组件上的使用场景。

通常在一个良好的工作流中,可以用三层不同的文件对应这3层不同的token类型,使得设计系统在工程体系中可以便利的进行迭代和维护。


此外,对于一些常被搭配的组合,比如背景色和前景色,还可以写成bundle方便直接使用:


Token的命名方式

Token的命名规则应该是建设token体系时需要花最多时间讨论和思考的。因为一旦制定了一套命名规则,未来在任意场景中所有的样式属性都需要按照该方式进行编码命名。在我的项目中是按照如下方式对一个component token进行命名的,它很自然的描述了该token的使用场景,无须查看文档就已经知道这是用于active状态下的一级按钮背景色。当然每个人可以根据自己项目最适合的开发场景来定义token的命名。


Nathan Curtis把token的命名层级按照分类学进行了以下分组:

  • Base 作为token的主干名,包括 类型category (color, font, spacing), 设计概念concept (feedback, action), 以及属性property (size, background)
  • Modifier 包括一个或更多的 变体variant (primary, success), 状态state (hover, disabled), 比例scale (100,200), 以及 模式mode (dark, light)
  • Object 包括 组件component (button, tab), 组件中的元件 element (left-icon, link), 以及 组件组 component group (forms, feeds)
  • Namespace 包括 系统名 system (tbapp), 主题 theme (sky-blue), 和具体的域 domain (buyer, seller)


无论在你的项目中需要哪几个层级,最好是按照从宏观到微观,从相对稳定到容易变化,从上下文情境到具体使用的顺序去命名token。毕竟它最主要的作用就是让人一读就懂。

值得注意的是,并不是所有的token都需要按照一模一样的层级去命名的,而是只保留该token所描述的使用场景需要的最简层级,避免名称的冗余。

设计工具与Token

无论是用Sketch还是Figma进行设计系统的建设,或是在日常设计工作中使用设计系统中的样式元素,都可以与token进行映射。比如一个Sketch文件,本质上来说就是JSON文件包,里面包含各种设计领域的对象数据,因此从设计源文件中获得样式数据是很好实现的。


除了这些样式数据外,Sketch的Symbol 或 Figma的Components使得组件级别的token也可以被维护。

所以Sketch/Figma to token可以基于一系列命名规则实现一部分token的自动生成,此外token的定期评审维护机制也能保证设计系统准确的对接前端、落地生产。

目前我们也还在研究如何更智能的将设计师日常维护的规范自动生成合理的token并应用于生产流程。也欢迎对智能UI设计和设计工程化领域感兴趣的盆友留言或私信我讨论~

资料参考:

  • Naming Tokens in Design Systems:https://medium.com/eightshapes-llc/naming-tokens-in-design-systems-9e86c7444676


往期推荐


软件缺陷智能分析技术之技术地图

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存