CSS `Design Tokens` 的 `Token Language` 标准化与跨平台通用性

各位观众,各位朋友,大家好!我是今天的主讲人,咱们今天聊点前端的“硬通货”—— Design Tokens,尤其是它们标准化和跨平台通用性的那些事儿。

开场白:设计与开发的“语言障碍”

不知道大家有没有遇到过这种情况:设计师辛辛苦苦搞出一套美轮美奂的UI,开发吭哧吭哧照着实现,结果总是差那么点意思?颜色不对劲?字体不一样?间距好像差了几个像素?原因很简单,设计师和开发者使用的“语言”不一样。设计师用的是设计工具的语言,比如Sketch的颜色选择器,Figma的样式库;开发者用的是代码的语言,比如CSS,JavaScript。这中间就存在一个“翻译”的过程,而翻译往往会出错。

Design Tokens 就是为了解决这个“语言障碍”而生的。它们就像一种通用的“设计语言”,可以被设计工具和开发代码同时理解,保证设计稿到最终产品的完美还原。

什么是 Design Tokens?

简单来说,Design Tokens 就是命名的设计属性值

想想看,一个按钮的颜色,与其叫它 #FF0000(红色),不如叫它 primary-button-background-color。这样一来,即使颜色变了,我们只需要修改 primary-button-background-color 的值,所有用到这个 Token 的地方都会自动更新。

更正式一点的说法是: Design Tokens 是一个抽象的概念,代表视觉设计的原子级别的值。这些值可以包括:

  • 颜色 (Colors): primary-color, secondary-color, text-color
  • 字体 (Typography): font-family-base, font-size-large, line-height-base
  • 间距 (Spacing): space-small, space-medium, space-large
  • 尺寸 (Sizes): border-radius-small, icon-size-medium, container-width
  • 阴影 (Shadows): box-shadow-default, text-shadow-highlight
  • 不透明度 (Opacity): opacity-disabled, opacity-hover
  • 动画 (Animation): animation-duration-fast, animation-easing-standard

为什么我们需要 Design Tokens?

  • 一致性 (Consistency): 确保整个产品线的设计风格一致。
  • 可维护性 (Maintainability): 修改设计更方便,只需要修改 Token 的值。
  • 可扩展性 (Scalability): 方便添加新的设计元素,例如新的颜色主题。
  • 跨平台 (Cross-Platform): 将 Token 转换为不同平台的代码,例如 CSS, JavaScript, Swift, Kotlin。
  • 协作 (Collaboration): 促进设计师和开发者之间的协作。

Token Language 的标准化:W3C 的参与

目前,Design Tokens 还没有一个官方的、统一的标准。但是,W3C(万维网联盟)已经开始关注这个问题,成立了 Design Tokens Community Group (DTCG),致力于推动 Design Tokens 的标准化。

虽然还没有正式的标准,但是 DTCG 已经提出了一些关键的概念和方向:

  • Token Format: 定义 Token 的数据格式,例如 JSON, YAML。
  • Token Transform: 定义 Token 的转换规则,例如将颜色从 HEX 转换为 RGB。
  • Token Reference: 定义 Token 之间的引用关系,例如一个 Token 的值可以引用另一个 Token。
  • Token Schema: 定义 Token 的结构和类型,例如一个颜色 Token 必须包含 HEX 值、RGB 值、HSL 值等。

Token Format:JSON 还是 YAML?

目前最常用的 Token Format 是 JSON 和 YAML。

  • JSON (JavaScript Object Notation): 简单、易于解析,被广泛支持。

    {
      "color": {
        "primary": {
          "value": "#007bff",
          "comment": "主要颜色"
        },
        "secondary": {
          "value": "#6c757d",
          "comment": "次要颜色"
        }
      },
      "font": {
        "size": {
          "base": {
            "value": "16px",
            "comment": "基础字体大小"
          }
        }
      }
    }
  • YAML (YAML Ain’t Markup Language): 可读性更强,支持注释,可以定义复杂的结构。

    color:
      primary:
        value: "#007bff"
        comment: "主要颜色"
      secondary:
        value: "#6c757d"
        comment: "次要颜色"
    font:
      size:
        base:
          value: "16px"
          comment: "基础字体大小"

选择哪种格式取决于你的项目需求和个人偏好。一般来说,对于简单的项目,JSON 就足够了;对于复杂的项目,YAML 可能更适合。

Token Transform:让 Token 适应不同的平台

Token Transform 是将 Token 转换为不同平台代码的关键。例如,一个颜色 Token 在 CSS 中可能需要转换为 HEX 值,在 iOS 中可能需要转换为 UIColor 对象。

Token Transform 可以通过编程实现,也可以使用一些现成的工具,例如 Style Dictionary。

Style Dictionary:一个强大的 Token 管理工具

Style Dictionary 是 Amazon 开发的一个开源工具,可以用来管理和转换 Design Tokens。它支持多种平台,包括 Web, iOS, Android, React Native 等。

使用 Style Dictionary,你可以定义 Token 的格式、转换规则和输出目标,然后自动生成不同平台的代码。

一个 Style Dictionary 的例子

假设我们有一个名为 tokens.json 的 Token 文件:

{
  "color": {
    "primary": {
      "value": "#007bff",
      "type": "color",
      "description": "主要颜色"
    },
    "secondary": {
      "value": "#6c757d",
      "type": "color",
      "description": "次要颜色"
    },
    "danger": {
        "value": "#dc3545",
        "type": "color",
        "description": "危险颜色"
    }
  },
  "font": {
    "size": {
      "base": {
        "value": "16px",
        "type": "number",
        "description": "基础字体大小"
      }
    },
    "family": {
      "base": {
        "value": "Arial, sans-serif",
        "type": "fontFamily",
        "description": "基础字体"
      }
    }
  },
  "spacing": {
    "small": {
      "value": "8px",
      "type": "number",
      "description": "小间距"
    },
    "medium": {
      "value": "16px",
      "type": "number",
      "description": "中等间距"
    },
    "large": {
      "value": "24px",
      "type": "number",
      "description": "大间距"
    }
  }
}

然后,我们可以创建一个名为 config.json 的 Style Dictionary 配置文件:

{
  "source": [
    "tokens.json"
  ],
  "platforms": {
    "web": {
      "transformGroup": "css",
      "buildPath": "build/web/",
      "files": [{
        "destination": "variables.css",
        "format": "css/variables",
        "options": {
          "showFileHeader": false
        }
      }]
    },
    "ios": {
      "transformGroup": "ios",
      "buildPath": "build/ios/",
      "files": [{
        "destination": "DesignTokens.swift",
        "format": "ios/swift",
        "className": "DesignTokens",
        "filter": {
            "attributes": {
                "category": "color"
            }
        }
      }]
    }
  }
}

在这个配置文件中,我们定义了两个平台:webios

  • web 平台使用 css transformGroup,将 Token 转换为 CSS 变量,并输出到 build/web/variables.css 文件中。
  • ios 平台使用 ios transformGroup,将颜色 Token 转换为 Swift 代码,并输出到 build/ios/DesignTokens.swift 文件中。

要运行 Style Dictionary,你需要先安装它:

npm install -g style-dictionary

然后,在命令行中执行以下命令:

style-dictionary build config.json

Style Dictionary 会根据配置文件,自动生成 CSS 和 Swift 代码。

生成的 build/web/variables.css 文件内容如下:

:root {
  --color-primary: #007bff;
  --color-secondary: #6c757d;
  --color-danger: #dc3545;
  --font-size-base: 16px;
  --font-family-base: Arial, sans-serif;
  --spacing-small: 8px;
  --spacing-medium: 16px;
  --spacing-large: 24px;
}

生成的 build/ios/DesignTokens.swift 文件内容如下(简化版):

import UIKit

class DesignTokens {
    static let colorPrimary: UIColor = UIColor(red: 0.00, green: 0.48, blue: 1.00, alpha: 1.0)
    static let colorSecondary: UIColor = UIColor(red: 0.42, green: 0.46, blue: 0.49, alpha: 1.0)
    static let colorDanger: UIColor = UIColor(red: 0.86, green: 0.21, blue: 0.27, alpha: 1.0)
}

Token Reference:让 Token 之间建立联系

Token Reference 允许一个 Token 的值引用另一个 Token。这可以用来创建复杂的、可维护的设计系统。

例如,我们可以定义一个 button-background-color Token,它的值引用 primary-color Token:

{
  "color": {
    "primary": {
      "value": "#007bff",
      "type": "color",
      "description": "主要颜色"
    }
  },
  "button": {
    "background-color": {
      "value": "{color.primary.value}",
      "type": "color",
      "description": "按钮背景颜色"
    }
  }
}

在这个例子中,button-background-color 的值是 {color.primary.value}。Style Dictionary 会自动将这个值替换为 primary-color 的值,也就是 #007bff

如果 primary-color 的值发生了变化,button-background-color 的值也会自动更新。

Token Schema:规范 Token 的结构

Token Schema 定义了 Token 的结构和类型。这可以用来保证 Token 的一致性和可预测性。

例如,我们可以定义一个颜色 Token 的 Schema,要求它必须包含 HEX 值、RGB 值和 HSL 值:

{
  "type": "object",
  "properties": {
    "value": {
      "type": "string",
      "description": "颜色值的 HEX 表示"
    },
    "rgb": {
      "type": "string",
      "description": "颜色值的 RGB 表示"
    },
    "hsl": {
      "type": "string",
      "description": "颜色值的 HSL 表示"
    }
  },
  "required": [
    "value",
    "rgb",
    "hsl"
  ]
}

在这个 Schema 中,我们要求颜色 Token 必须包含 valuergbhsl 三个属性。

跨平台通用性的挑战与解决方案

尽管 Design Tokens 可以很好地解决设计与开发之间的“语言障碍”,但是跨平台通用性仍然面临一些挑战:

  • 不同平台对设计属性的支持程度不同: 例如,某些平台可能不支持某些 CSS 属性。
  • 不同平台的代码风格不同: 例如,CSS 使用 kebab-case 命名,JavaScript 使用 camelCase 命名。
  • 不同平台的设计规范不同: 例如,iOS 和 Android 的 UI 设计规范不同。

为了解决这些挑战,我们需要:

  • 选择合适的 Token Format 和 Transform Group: 根据目标平台选择合适的 Token Format 和 Transform Group。
  • 自定义 Transform: 如果现有的 Transform Group 不能满足需求,可以自定义 Transform。
  • 使用平台特定的设计规范: 针对不同的平台,使用不同的设计规范。

表格总结:Design Tokens 的关键概念

概念 描述
Design Tokens 命名的设计属性值,代表视觉设计的原子级别的值。
Token Format 定义 Token 的数据格式,例如 JSON, YAML。
Token Transform 定义 Token 的转换规则,例如将颜色从 HEX 转换为 RGB。
Token Reference 定义 Token 之间的引用关系,例如一个 Token 的值可以引用另一个 Token。
Token Schema 定义 Token 的结构和类型,例如一个颜色 Token 必须包含 HEX 值、RGB 值、HSL 值等。
Style Dictionary Amazon 开发的一个开源工具,可以用来管理和转换 Design Tokens。它支持多种平台,包括 Web, iOS, Android, React Native 等。

结尾:拥抱 Design Tokens 的未来

Design Tokens 已经成为现代前端开发中不可或缺的一部分。随着 W3C 的参与和相关工具的不断完善,Design Tokens 的标准化和跨平台通用性将会越来越好。

希望今天的讲座能帮助大家更好地理解 Design Tokens,并在实际项目中应用它们。 记住,好的设计系统可以大大提高开发效率,并保证产品的一致性和可维护性。 而Design Tokens,正是构建优秀设计系统的基石。

感谢大家的观看!希望下次有机会再和大家分享更多有趣的技术话题。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注