CSS `Design Tokens`:统一设计系统中的样式值与多平台同步

各位观众老爷,大家好!今天咱们不聊风花雪月,聊点实在的——CSS Design Tokens,这玩意儿能让你的设计系统像个训练有素的特种部队,统一且同步,在各种平台上横扫千军,避免出现“你在iOS上看到的是玫瑰红,到了安卓上却成了姨妈红”的尴尬局面。

开场白:设计系统里的“一言堂”

想象一下,你是一个乐队的指挥,手下有吉他手、鼓手、键盘手、贝斯手等等。如果每个人都按照自己的想法演奏,那出来的绝对不是音乐,而是噪音。设计系统也是一样,它是一个团队共同创造的“音乐”,需要一套统一的规则来协调各个“乐器”(平台、组件、样式等等)。

而 Design Tokens,就是这个“一言堂”的规则,它定义了设计决策,例如颜色、字体、间距等,并将这些决策转化为可重用的值,让所有平台都能遵循。

什么是 Design Tokens?

简单来说,Design Tokens 是一系列命名的值,代表了设计系统中的视觉属性。它们不是直接的 CSS 值,而是抽象的引用,指向实际的值。

举个栗子:

// 不使用 Design Tokens
.button {
  background-color: #007bff;
  color: white;
  font-size: 16px;
  padding: 10px 20px;
}

// 使用 Design Tokens
:root {
  --color-primary: #007bff;
  --text-color-light: white;
  --font-size-base: 16px;
  --spacing-medium: 10px;
  --spacing-large: 20px;
}

.button {
  background-color: var(--color-primary);
  color: var(--text-color-light);
  font-size: var(--font-size-base);
  padding: var(--spacing-medium) var(--spacing-large);
}

看到区别了吗? 使用Design Tokens之后,.button不再直接写死颜色值,而是引用了--color-primary这个变量。这样做的好处是,如果我们需要修改主色调,只需要修改--color-primary的值,所有引用它的地方都会自动更新。

Design Tokens 的价值:

  • 一致性: 确保所有平台和组件使用相同的设计决策,避免视觉上的不一致。
  • 可维护性: 修改设计决策变得更加容易,只需更改 Token 的值,而无需在整个代码库中搜索和替换。
  • 可扩展性: 方便添加新的主题或变体,只需定义新的 Token 值即可。
  • 跨平台: 将 Token 导出为各种格式,例如 CSS、JavaScript、JSON 等,方便在不同平台上使用。

Design Tokens 的种类:

Design Tokens 可以分为很多种,常见的有:

  • 颜色 (Color): 例如主色、辅助色、背景色、文字颜色等等。
  • 字体 (Typography): 例如字体家族、字号、字重、行高等。
  • 间距 (Spacing): 例如内边距、外边距、间距大小等等。
  • 尺寸 (Size): 例如按钮高度、图标大小、边框宽度等等。
  • 阴影 (Shadow): 例如阴影颜色、阴影偏移、阴影模糊半径等等。
  • 动画 (Animation): 例如动画时长、动画曲线等等。
  • 圆角 (Border Radius): 例如按钮圆角、图片圆角等等。

如何使用 Design Tokens?

使用 Design Tokens 的流程通常包括以下几个步骤:

  1. 定义 Token: 确定需要哪些 Token,并为它们命名。
  2. 创建 Token 文件: 将 Token 定义存储在文件中,例如 CSS 变量、JSON 文件等。
  3. 在代码中使用 Token: 在 CSS、JavaScript 或其他代码中使用 Token 来引用设计决策。
  4. 管理 Token: 使用工具或流程来管理 Token,例如更新、版本控制等。

实战演练:用 CSS 变量管理 Design Tokens

CSS 变量(也称为自定义属性)是管理 Design Tokens 的一种常见方式。它简单易用,并且可以直接在 CSS 中使用。

1. 定义 Token:

假设我们需要定义以下 Token:

Token Name Value Description
--color-primary #007bff 主色
--color-secondary #6c757d 辅助色
--text-color-dark #212529 深色文字颜色
--text-color-light #fff 浅色文字颜色
--font-size-base 16px 基础字号
--font-family-base sans-serif 基础字体
--spacing-small 8px 小间距
--spacing-medium 16px 中间距
--border-radius-small 4px 小圆角

2. 创建 Token 文件 (例如:tokens.css):

:root {
  --color-primary: #007bff;
  --color-secondary: #6c757d;
  --text-color-dark: #212529;
  --text-color-light: #fff;
  --font-size-base: 16px;
  --font-family-base: sans-serif;
  --spacing-small: 8px;
  --spacing-medium: 16px;
  --border-radius-small: 4px;
}

3. 在代码中使用 Token:

<!DOCTYPE html>
<html>
<head>
  <title>Design Tokens Example</title>
  <link rel="stylesheet" href="tokens.css">
  <style>
    body {
      font-family: var(--font-family-base);
      font-size: var(--font-size-base);
      color: var(--text-color-dark);
      padding: var(--spacing-medium);
    }

    .button {
      background-color: var(--color-primary);
      color: var(--text-color-light);
      padding: var(--spacing-small) var(--spacing-medium);
      border-radius: var(--border-radius-small);
      border: none;
      cursor: pointer;
    }

    .button:hover {
      background-color: #0056b3; /* 略微修改,体现 hover 效果 */
    }

    .secondary-button {
      background-color: var(--color-secondary);
    }

    .secondary-button:hover {
      background-color: #545b62;
    }
  </style>
</head>
<body>
  <h1>Welcome to my awesome page!</h1>
  <p>This is some content using our defined tokens.</p>
  <button class="button">Primary Button</button>
  <button class="button secondary-button">Secondary Button</button>
</body>
</html>

在这个例子中,我们在 bodybutton 元素中使用了 Design Tokens 来定义样式。

4. 管理 Token:

虽然 CSS 变量很简单,但对于大型项目,手动管理 Token 可能会变得繁琐。我们需要考虑以下问题:

  • 版本控制: 如何跟踪 Token 的变化?
  • 跨平台: 如何将 Token 导出为不同的格式?
  • 自动化: 如何自动化 Token 的生成和更新?

为了解决这些问题,我们可以使用一些工具来管理 Design Tokens。

进阶:使用 Style Dictionary 管理 Design Tokens

Style Dictionary 是 Amazon 推出的一个开源工具,专门用于管理和转换 Design Tokens。它可以将 Token 定义转换为各种格式,例如 CSS、JavaScript、JSON、Swift、XML 等,从而方便在不同平台上使用。

1. 安装 Style Dictionary:

npm install -g style-dictionary

2. 创建 Token 文件 (例如:tokens.json):

{
  "color": {
    "primary": {
      "value": "#007bff",
      "comment": "主色"
    },
    "secondary": {
      "value": "#6c757d",
      "comment": "辅助色"
    },
    "text": {
      "dark": {
        "value": "#212529",
        "comment": "深色文字颜色"
      },
      "light": {
        "value": "#fff",
        "comment": "浅色文字颜色"
      }
    }
  },
  "font": {
    "size": {
      "base": {
        "value": "16px",
        "comment": "基础字号"
      }
    },
    "family": {
      "base": {
        "value": "sans-serif",
        "comment": "基础字体"
      }
    }
  },
  "spacing": {
    "small": {
      "value": "8px",
      "comment": "小间距"
    },
    "medium": {
      "value": "16px",
      "comment": "中间距"
    }
  },
  "borderRadius": {
    "small": {
      "value": "4px",
      "comment": "小圆角"
    }
  }
}

3. 创建配置文件 (例如:config.json):

{
  "source": ["tokens.json"],
  "platforms": {
    "css": {
      "transformGroup": "css",
      "buildPath": "build/css/",
      "files": [{
        "destination": "variables.css",
        "format": "css/variables",
        "options": {
          "showFileHeader": false
        }
      }]
    },
    "js": {
      "transformGroup": "js",
      "buildPath": "build/js/",
      "files": [{
        "destination": "tokens.js",
        "format": "javascript/module",
        "options": {
          "showFileHeader": false
        }
      }]
    }
  }
}

这个配置文件告诉 Style Dictionary:

  • source: 从 tokens.json 文件读取 Token 定义。
  • platforms: 定义要生成的平台和格式。
    • css: 生成 CSS 变量,使用 css/variables 格式。
    • js: 生成 JavaScript 模块,使用 javascript/module 格式。

4. 运行 Style Dictionary:

style-dictionary build

这会生成 build/css/variables.cssbuild/js/tokens.js 文件。

build/css/variables.css:

:root {
  --color-primary: #007bff;
  --color-secondary: #6c757d;
  --color-text-dark: #212529;
  --color-text-light: #fff;
  --font-size-base: 16px;
  --font-family-base: sans-serif;
  --spacing-small: 8px;
  --spacing-medium: 16px;
  --borderRadius-small: 4px;
}

build/js/tokens.js:

module.exports = {
  "color": {
    "primary": {
      "value": "#007bff",
      "comment": "主色"
    },
    "secondary": {
      "value": "#6c757d",
      "comment": "辅助色"
    },
    "text": {
      "dark": {
        "value": "#212529",
        "comment": "深色文字颜色"
      },
      "light": {
        "value": "#fff",
        "comment": "浅色文字颜色"
      }
    }
  },
  "font": {
    "size": {
      "base": {
        "value": "16px",
        "comment": "基础字号"
      }
    },
    "family": {
      "base": {
        "value": "sans-serif",
        "comment": "基础字体"
      }
    }
  },
  "spacing": {
    "small": {
      "value": "8px",
      "comment": "小间距"
    },
    "medium": {
      "value": "16px",
      "comment": "中间距"
    }
  },
  "borderRadius": {
    "small": {
      "value": "4px",
      "comment": "小圆角"
    }
  }
};

现在,你就可以在 CSS 中使用 build/css/variables.css,在 JavaScript 中使用 build/js/tokens.js 来引用 Design Tokens 了。

Style Dictionary 的强大之处:

  • Transform: 转换 Token 的值,例如将 px 转换为 rem
  • Filter: 过滤 Token,只生成需要的 Token。
  • Format: 自定义输出格式,例如生成 Sass 变量、Less 变量等。
  • Validation: 验证 Token 的值,确保符合规范。

Design Tokens 的最佳实践:

  • 语义化命名: 使用有意义的名称来命名 Token,例如 --color-primary 而不是 --color-1
  • 分层组织: 将 Token 分成不同的层级,例如 color.primary.base
  • 避免硬编码: 尽量避免在代码中直接使用硬编码的值,而是使用 Token 来引用。
  • 使用工具管理: 使用工具来管理 Token,例如 Style Dictionary。
  • 保持更新: 定期更新 Token,以反映设计系统的变化。

Design Tokens 的陷阱:

  • 过度抽象: 不要过度抽象 Token,否则会使代码变得难以理解。
  • 命名冲突: 避免 Token 命名冲突,可以使用命名空间来解决。
  • 性能问题: 过多的 CSS 变量可能会影响性能,需要注意优化。

总结:

Design Tokens 是一个强大的工具,可以帮助你构建一致、可维护、可扩展的设计系统。 虽然学习曲线稍微陡峭,但是一旦掌握,你就能像一个经验丰富的乐队指挥一样,协调各种“乐器”,创造出和谐统一的“音乐”。 记住,设计系统的目标是让用户体验更加流畅和一致,而 Design Tokens 正是实现这一目标的关键。

好了,今天的讲座就到这里,希望大家有所收获。下次再见!

发表回复

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