发布时间:2026/7/24 15:54:10
设计 Token 体系搭建:从前端变量到跨平台一致性的工程化实践 设计 Token 体系搭建从前端变量到跨平台一致性的工程化实践一、设计师在 Figma 里改了一个色值前端要在 37 个文件里改 89 处如果你经历过这个场景你需要一个设计 Token 体系。设计 TokenDesign Token这个概念被提出快十年了但在国内前端团队的落地情况依然不乐观。问题不在于不知道 Token 是什么而在于怎么在工程里把它用起来而不只是一堆 JSON 文件。设计 Token 的本质是将设计决策抽象为平台无关的变量然后通过转译工具生成各平台Web、iOS、Android、Flutter的原生代码。它让设计师在 Figma 改一个主色这件事的工程影响从全局搜索替换变成改一行 JSON自动生成所有平台的代码。这篇文章我会从 Token 的层级设计、命名规范、转译工具链、CI 集成四个维度给你一套可以直接照搬的 Token 体系搭建方案。二、设计 Token 的层级架构为什么需要三层很多人直接把 Figma 里的色值写成 CSS 变量这就跳过了最重要的语义层// 错误基础值和语义值混在一起 { color-primary: #3B82F6, color-primary-hover: #2563EB }这种结构的致命问题是当你想在暗黑模式下把主色从#3B82F6换成#93C5FD时你需要改的是语义 Token而不是基础色值。如果基础和语义混在一起你就失去了一个值关联多个语义的灵活性// 正确三层分离 // primitives.json { blue: { 500: { value: #3B82F6 }, 600: { value: #2563EB }, 300: { value: #93C5FD } } } // semantics.json { color: { primary: { value: {blue.500} }, primary-hover: { value: {blue.600} }, primary-on-dark: { value: {blue.300} } } } // 暗黑模式只需要这一层 // semantics-dark.json { color: { primary: { value: {blue.300} }, primary-hover: { value: {blue.200} } } }三、Token 体系的完整工程实现命名规范使用 CTICategory / Type / Item结构[category]-[type]-[item]-[variant]-[state] 示例 color-background-primary-hover font-size-heading-xl spacing-layout-section-gap radius-component-button shadow-elevation-card完整的 Token Map 示例{ color: { text: { primary: { value: {color.neutral.900} }, secondary: { value: {color.neutral.600} }, disabled: { value: {color.neutral.400} }, inverse: { value: {color.neutral.0} } }, background: { primary: { value: {color.neutral.0} }, secondary: { value: {color.neutral.50} }, overlay: { value: rgba(0, 0, 0, 0.5) } }, border: { default: { value: {color.neutral.200} }, focus: { value: {color.blue.500} }, error: { value: {color.red.500} } } }, spacing: { xs: { value: 4px }, sm: { value: 8px }, md: { value: 16px }, lg: { value: 24px }, xl: { value: 32px }, 2xl: { value: 48px } }, radius: { sm: { value: 4px }, md: { value: 8px }, lg: { value: 16px }, full: { value: 9999px } }, shadow: { sm: { value: 0 1px 2px rgba(0,0,0,0.05) }, md: { value: 0 4px 6px rgba(0,0,0,0.07) }, lg: { value: 0 10px 25px rgba(0,0,0,0.1) } } }使用 Style Dictionary 做转译Style Dictionary 是设计 Token 领域最成熟的转译工具Amazon 开源已维护 7 年。// build-tokens.js const StyleDictionary require(style-dictionary); const sd StyleDictionary.extend({ source: [ tokens/primitives/**/*.json, tokens/semantics/**/*.json, ], platforms: { /** CSS 变量输出 */ css: { transformGroup: css, buildPath: dist/css/, files: [ { destination: tokens.css, format: css/variables, options: { outputReferences: true, // 保留引用关系 }, }, ], /** 暗黑模式通过>/* dist/css/tokens.css (构建产物) */ :root { --color-text-primary: #1A1A2E; --color-text-secondary: #64748B; --color-background-primary: #FFFFFF; --color-background-secondary: #F8FAFC; } [data-themedark] { --color-text-primary: #E2E8F0; --color-text-secondary: #94A3B8; --color-background-primary: #0F172A; --color-background-secondary: #1E293B; } /* 或使用 prefers-color-scheme */ media (prefers-color-scheme: dark) { :root:not([data-themelight]) { --color-text-primary: #E2E8F0; --color-text-secondary: #94A3B8; --color-background-primary: #0F172A; --color-background-secondary: #1E293B; } }Token 变更的 CI 检查# .github/workflows/token-check.yml name: Design Token Consistency Check on: pull_request: paths: - tokens/** jobs: check: runs-on: ubuntu-latest steps: - uses: actions/checkoutv4 - name: Build Tokens run: npx style-dictionary build - name: Check Token Changes run: | # 检测是否有意外的 Token 变更 git diff --exit-code dist/ || { echo ⚠️ Token 构建产物有变更请提交 dist/ 目录 exit 1 } - name: Validate Token References run: node scripts/validate-token-refs.js - name: Check Contrast Ratios run: node scripts/check-contrast.js - name: Generate Token Changelog run: node scripts/token-diff.js token-changelog.md - name: Comment on PR uses: actions/github-scriptv7 with: script: | const fs require(fs); const changelog fs.readFileSync(token-changelog.md, utf8); github.rest.issues.createComment({ issue_number: context.issue.number, owner: context.repo.owner, repo: context.repo.repo, body: ## 设计 Token 变更清单\n\n${changelog} });四、常见踩坑与避坑指南Token 太多没人知道该用哪个建议控制在 80-120 个语义 Token。多了就说明你的层级设计有问题或者有 Token 该合并。设计师不在 Figma 里用 Token 名这是落地最大的障碍。解决方案是使用 Figma Tokens 插件让设计师在 Figma 里直接用 Token 名和代码一一对应。Token 命名是政治问题spacing-md还是spacing-3color-primary还是color-brand这类命名分歧本质是团队对什么是设计语言的共识问题。建议先定规范文档再建 Token。跨平台 Token 不可能 100% 一致iOS 的 SF Pro 字体和 Android 的 Roboto 字体渲染不同同一个 Token 值会产出视觉差异。接受 95% 的一致性5% 让平台特性接管。五、总结设计 Token 体系不是一堆 JSON 文件 一个 SD 构建脚本它是设计决策的工程化。三层架构基础 → 语义 → 组件保证了灵活性CTI 命名规范保证了可读性Style Dictionary 保证了多平台一致性。最重要的是——当这个体系真正运转起来之后设计师改了一个色值的工程影响从改 89 处代码变成了改一行 JSON 跑一次构建。这才是设计系统该有的样子。作者李慕杰Leo / 8limujie一个花了三年时间、终于让设计师和前端对色值的定义达成共识的前端匠人

相关新闻

2026/7/24 15:54:10

YOLO铁锈腐蚀识别系统:工业检测的AI解决方案

1. 项目背景与核心价值在工业设备维护和基础设施管理中,金属锈蚀问题一直是困扰运维人员的难题。传统的人工巡检方式不仅效率低下,而且受限于人眼识别精度,往往难以发现早期锈蚀。我们团队开发的这套基于YOLO的铁锈腐蚀识别系统,正…

2026/7/24 15:49:09

LLM网关项目复盘:多模型统一接入层的架构设计与工程挑战

LLM网关项目复盘:多模型统一接入层的架构设计与工程挑战 一、多模型的"巴别塔"问题 一个AI应用同时使用了5个LLM Provider(OpenAI、Anthropic、DeepSeek、通义千问、Moonshot)。每个Provider有自己的SDK、请求格式、响应格式、错误…

2026/7/24 15:49:09

UnityEditor命名空间报错全解析:从编译原理到项目结构优化

1. 项目概述:当UnityEditor“消失”时 如果你在Unity编辑器里写脚本,尤其是那些用来扩展编辑器功能、创建自定义工具窗口或者自动化流程的脚本,那么“not exist in the namespace ‘UnityEditor‘”这个报错,大概率是你绕不开的一…

2026/7/24 17:24:19

流式输出的渲染预算:节流与批量提交的工程化治理

流式输出的渲染预算:节流与批量提交的工程化治理 一、逐 token 渲染的卡顿现场:当 SSE 高频更新撞上虚拟 DOM 大模型流式输出在前端落地,最常见的故障不是网络断流,而是渲染卡顿。SSE 或 ReadableStream 把回答切成 token&#xf…

2026/7/24 17:24:19

095、ESP-DL的异常检测案例

095、ESP-DL的异常检测案例 昨晚调试到凌晨三点,板子上的LED突然开始有规律地闪烁——不是代码里写的那个闪烁模式,而是一种诡异的、像心跳一样的节奏。我盯着逻辑分析仪上的波形看了十分钟,才意识到ESP-DL的异常检测模型真的把那个“异常”抓出来了。这感觉就像你养了一条…

2026/7/24 17:24:19

工业级PCB缺陷检测系统:Faster-RCNN实战与优化

1. 项目概述:工业级PCB缺陷检测系统实战 去年参与某PCB代工厂的质检系统升级时,我第一次见识到产线上工人用放大镜目检微米级线路的场景。这种传统检测方式不仅效率低下(每块板子平均耗时3分钟),漏检率更是高达15%。这…

2026/7/24 17:24:19

094、ESP-DL的传感器手势识别案例

094、ESP-DL的传感器手势识别案例 从一次深夜调试说起 凌晨两点,示波器探头还夹在MPU6050的SDA线上。我盯着串口输出的数据流,明明手势已经挥了十几遍,模型输出的置信度始终在0.3到0.4之间徘徊——这跟瞎猜没区别。更诡异的是,把同样的模型部署到PC端跑,准确率能到92%。…

2026/7/24 17:19:18

Django毕业设计-基于协同过滤算法的 Django 电影个性化推荐系统设计与实现 融合协同过滤的影视智能推荐 Web 平台设计(源码+LW+部署文档+全bao+远程调试+代码讲解等)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

2026/7/23 12:54:51

Unity与Python本地通信:基于Flask的跨语言数据交换实战

1. 项目概述:为什么我们需要一个本地通信服务器?在游戏开发、数字孪生、仿真训练等众多领域,Unity作为强大的实时3D内容创作平台,其核心逻辑通常由C#驱动。然而,当我们需要进行复杂的数据分析、机器学习推理、科学计算…

2026/7/24 0:03:10

不同品牌斜齿行星减速机如何替换?以PX与PAG系列为例

不同品牌斜齿行星减速机如何替换?以 PX 与 PAG 系列为例 一、系列对应不等于型号直接互换 PX 与 PAG 都属于斜齿、方法兰、输出轴式精密行星减速机,结构形式和应用方向具有对应关系。 原设备使用PX系列时,可以优先从PAG系列中寻找替换型号。但…

2026/7/24 0:03:10

jdk8 把list 扁平化成String 多个以逗号分隔

在 JDK 8 中&#xff0c;将 List 扁平化为以逗号分隔的 String&#xff0c;有几种非常简洁且高效的方法。&#x1f680; 推荐方案&#xff1a;使用 Collectors.joining()这是最标准的 Java 8 写法&#xff0c;适用于 List<String>。javaimport java.util.stream.Collecto…

2026/7/24 0:03:10

java 两个 long id 怎么合并成一个long id 并且不重复

“把两个 Long ID 合并成一个唯一的 Long ID&#xff0c;且保证不重复”这个需求&#xff0c;在 Java 里直接做数学上的“完美合并”是不可能的。因为两个 Long&#xff08;各 64 位&#xff09;要合并成一个 Long&#xff08;64 位&#xff09;&#xff0c;在信息论上是有损压…

2026/7/23 23:42:43

3个高效策略:快速掌握Axure中文界面配置

3个高效策略&#xff1a;快速掌握Axure中文界面配置 【免费下载链接】axure-cn Chinese language file for Axure RP. Axure RP 简体中文语言包。支持 Axure 11、10、9。不定期更新。 项目地址: https://gitcode.com/gh_mirrors/ax/axure-cn 还在为Axure RP的英文界面感…