ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

设计系统 Token 架构实战:在 ui-ux-pro-max-skill 中构建三层可主题化设计令牌体系

设计系统 Token 架构实战:在 ui-ux-pro-max-skill 中构建三层可主题化设计令牌体系 设计系统 Token 架构实战在 ui-ux-pro-max-skill 中构建三层可主题化设计令牌体系【免费下载链接】ui-ux-pro-max-skillAn AI skill that provides design intelligence for building professional UI/UX across multiple platforms.项目地址: https://gitcode.com/gh_mirrors/ui/ui-ux-pro-max-skill本篇技术指南围绕 ui-ux-pro-max-skill 仓库中 design-system 技能的核心文档 token-architecture.md系统讲解「Primitive原始值→ Semantic语义别名→ Component组件级」三层 Token 架构的设计原理、完整 CSS 实现、命名规范与暗色模式切换策略并结合仓库内 generate-tokens.cjs 与 validate-tokens.cjs 两个真实工具脚本展示从 JSON 定义到 CSS 变量生成、再到代码库硬编码值审计的完整自动化链路。读完本文你将能够独立设计一套可扩展、可换肤、与 Tailwind 和 shadcn/ui 兼容的企业级设计令牌体系。为什么需要三层 Token 架构设计系统的核心矛盾在于底层设计值颜色、字号、间距需要保持稳定而业务语义主色、警示色、区块间距会随品牌与主题变化组件外观又需要独立定制。若把所有值直接写死在组件里换肤与品牌升级将演变成全局查找替换的灾难。三层 Token 架构通过引入间接层解决这一问题┌─────────────────────────────────────────┐ │ Component Tokens │ Per-component overrides │ --button-bg, --card-padding │ ├─────────────────────────────────────────┤ │ Semantic Tokens │ Purpose-based aliases │ --color-primary, --spacing-section │ ├─────────────────────────────────────────┤ │ Primitive Tokens │ Raw design values │ --color-blue-600, --space-4 │ └─────────────────────────────────────────┘三个层级各司其职变更频率差异显著层级职责何时修改Primitive承载基础设计值颜色、尺寸极少修改——它是整个体系的根基Semantic赋予值以业务含义目的别名主题切换时修改Component组件级定制按组件需求单独覆盖在 SKILL.md 中这一架构被正式声明为设计系统的核心模式Primitive (raw values) ↓ Semantic (purpose aliases) ↓ Component (component-specific)并强调组件中绝不直接使用原始 hex 色值始终引用 Token是第一最佳实践。第一层Primitive Tokens原始值层原始值层存放不带任何语义的裸设计值是整个体系的事实来源。以 4px 为基准的间距系统、灰度/主色/状态色色阶、字号、圆角、阴影、动效时长都定义在这一层。:root { /* Colors */ --color-gray-50: #F9FAFB; --color-gray-900: #111827; --color-blue-500: #3B82F6; --color-blue-600: #2563EB; /* Spacing (4px base) */ --space-1: 0.25rem; /* 4px */ --space-2: 0.5rem; /* 8px */ --space-4: 1rem; /* 16px */ --space-6: 1.5rem; /* 24px */ /* Typography */ --font-size-sm: 0.875rem; --font-size-base: 1rem; --font-size-lg: 1.125rem; /* Radius */ --radius-sm: 0.25rem; --radius-default: 0.5rem; --radius-lg: 0.75rem; /* Shadows */ --shadow-sm: 0 1px 2px rgb(0 0 0 / 0.05); --shadow-default: 0 1px 3px rgb(0 0 0 / 0.1); }仓库配套文档 primitive-tokens.md 提供了更完整的原始值清单可作为落地时的参考基准色阶gray 从 50 到 950 共 11 阶blue 主色 50~900外加 green/yellow/red 状态色间距以--space-00到--space-246rem的完整 4px 倍增阶梯同时提供--space-px1px与--space-0-52px等细分档位排版--font-size-xs0.75rem到--font-size-5xl3rem共 10 档字号配套--leading-*行高、--font-weight-*字重与--tracking-*字距圆角--radius-none0到--radius-full9999px共 9 档阴影--shadow-none到--shadow-2xl含--shadow-inner内阴影动效--duration-7575ms到--duration-10001000ms并预置--duration-fast/normal/slow语义化时长层级--z-0到--z-50数值档位以及--z-dropdown1000到--z-tooltip1400的浮层语义档位。第二层Semantic Tokens语义别名层语义层不定义新值而是用var()引用原始值并赋予业务含义。这样组件永远不关心主色具体是什么蓝只关心我的主色叫 primary。换主题时只需改语义层的指向无需触碰任何组件。:root { /* Background */ --color-background: var(--color-gray-50); --color-foreground: var(--color-gray-900); /* Primary */ --color-primary: var(--color-blue-600); --color-primary-hover: var(--color-blue-700); /* Secondary */ --color-secondary: var(--color-gray-100); --color-secondary-foreground: var(--color-gray-900); /* Muted */ --color-muted: var(--color-gray-100); --color-muted-foreground: var(--color-gray-500); /* Destructive */ --color-destructive: var(--color-red-600); --color-destructive-foreground: white; /* Spacing */ --spacing-component: var(--space-4); --spacing-section: var(--space-6); }完整的语义色体系参见 semantic-tokens.md它细化了更多类别--color-card/--color-popover等表面色、--color-primary-active按下态等状态色、--color-success/warning/error/info状态色、--color-border/input/ring边框与焦点环色间距语义拆分为--spacing-component-*组件内间距、--spacing-section-*区块间距与--spacing-page-*页面留白排版语义提供--font-heading-*、--font-body-*、--font-label、--font-caption等用途别名交互状态语义则包含--ring-width2px、--ring-offset2px、--opacity-disabled0.5与--transition-*过渡属性。该文档还给出了清晰的使用准则组件中只能引用语义 Token直接引用原始值被视为反模式——/* Good - uses semantic tokens */ .card { background: var(--color-card); color: var(--color-card-foreground); border: 1px solid var(--color-border); } /* Bad - uses primitive tokens directly */ .card { background: var(--color-gray-50); color: var(--color-gray-900); }第三层Component Tokens组件级层组件层是每个组件专属的 Token 集合统一引用语义层。它的价值在于当某个组件需要个性化外观例如输入框聚焦环更粗时只需覆盖该组件的 Token而不影响其他组件。:root { /* Button */ --button-bg: var(--color-primary); --button-fg: white; --button-hover-bg: var(--color-primary-hover); --button-padding-x: var(--space-4); --button-padding-y: var(--space-2); --button-radius: var(--radius-default); /* Input */ --input-bg: var(--color-background); --input-border: var(--color-gray-300); --input-focus-ring: var(--color-primary); --input-padding: var(--space-2) var(--space-3); /* Card */ --card-bg: var(--color-background); --card-border: var(--color-gray-200); --card-padding: var(--space-4); --card-radius: var(--radius-lg); --card-shadow: var(--shadow-default); }component-tokens.md 把组件层扩充到了 Button、Input、Card、Badge、Alert、Dialog、Table 七个核心组件每个组件都按背景/前景/边框 尺寸 形状的维度组织并覆盖各变体。以 Button 为例它不仅包含默认态还预定义了 secondary / outline / ghost / destructive 四种变体及 sm/lg 尺寸档位/* 变体模式组件内用局部变量承载语义变体只需改局部变量 */ .component { --component-bg: var(--color-primary); --component-fg: var(--color-primary-foreground); background: var(--component-bg); color: var(--component-fg); } .component.secondary { --component-bg: var(--color-secondary); --component-fg: var(--color-secondary-foreground); } .component.destructive { --component-bg: var(--color-destructive); --component-fg: var(--color-destructive-foreground); }组件级 Token 的实际消费方式见 component-tokens.md 的 Usage Example是CSS 规则体内只写var(--button-*)hover 态切换--button-hover-bg二次按钮切换--button-secondary-*。组件规格尺寸表、状态表、解剖结构图则在 component-specs.md 中与 Token 一一对应例如 Button 默认尺寸为高 40px、水平内边距 16px、垂直内边距 8px、字号 14px恰好对应--button-padding-x: var(--space-4)、--button-padding-y: var(--space-2)的定义。暗色模式只覆盖语义层暗色主题之所以能一键切换正是因为组件与原始值层都不需要改动——只需在.dark选择器下重新指向语义 Token.dark { --color-background: var(--color-gray-900); --color-foreground: var(--color-gray-50); --color-muted: var(--color-gray-800); --color-muted-foreground: var(--color-gray-400); --color-secondary: var(--color-gray-800); }切换逻辑只需一行 JS参见 semantic-tokens.md 与 tailwind-integration.md// Toggle dark mode document.documentElement.classList.toggle(dark);如需跟随系统偏好if (window.matchMedia((prefers-color-scheme: dark)).matches) { document.documentElement.classList.add(dark); }命名规范--{category}-{item}-{variant}-{state}统一的命名规范让 Token 表意清晰、可检索。四段式语法为--{category}-{item}-{variant}-{state} Examples: --color-primary # category-item --color-primary-hover # category-item-state --button-bg-hover # component-property-state --space-section-sm # category-semantic-variant解析规则category顶级分类如color、space、font-size、radius、shadow、durationitem分类下的具体条目语义名或数值名variant可选用于语义变体如section-smstate可选用于交互状态如hover、active、disabled。仓库定义的 Token 分类一览分类示例colorprimary, secondary, muted, destructivespace1, 2, 4, 8, section, componentfont-sizexs, sm, base, lg, xlradiussm, default, lg, fullshadowsm, default, lgdurationfast, normal, slow文件组织分层文件 or 单文件分节两种组织方式均可根据团队规模选择方式一分层文件适合大型设计系统职责隔离清晰tokens/ ├── primitives.css # Raw values ├── semantic.css # Purpose aliases ├── components.css # Component tokens └── index.css # Imports all方式二单文件分节适合中小项目便于整体浏览/* PRIMITIVES */ :root { ... } /* SEMANTIC */ :root { ... } /* COMPONENTS */ :root { ... } /* DARK MODE */ .dark { ... }值得注意的是仓库的自动化生成脚本 generate-tokens.cjs 输出的正是第二种单文件分节形态——它自动生成/* PRIMITIVES */、/* SEMANTIC */、/* COMPONENTS */三段:root块并在存在暗色定义时追加/* DARK MODE */的.dark块与文档规范完全一致。从扁平 Token 迁移到三层架构已有系统通常是扁平命名值直接写死在 Token 名里迁移的核心是把值下沉到原始层、把用途提升到语义与组件层Before扁平--button-primary-bg: #2563EB; --button-secondary-bg: #F3F4F6;After三层/* Primitive */ --color-blue-600: #2563EB; --color-gray-100: #F3F4F6; /* Semantic */ --color-primary: var(--color-blue-600); --color-secondary: var(--color-gray-100); /* Component */ --button-bg: var(--color-primary); --button-secondary-bg: var(--color-secondary);迁移收益立刻显现换主题时只需改 semantic 段的指向换品牌色时只需改 primitive 段的原始值单独定制按钮时只需改 component 段。三层之间通过var()引用形成单向依赖链绝不允许反向引用组件层不可被原始层引用。对齐 W3C DTCG 标准JSON 形态的 Token为了工具链互操作与跨团队共享Token 应同步提供 W3C Design Tokens Community Group 标准的 JSON 形态。该格式以$value/$type声明值与类型嵌套结构天然对应三层体系{ color: { blue: { 600: { $value: #2563EB, $type: color } } } }仓库提供了开箱即用的三层 JSON 模板 design-tokens-starter.json结构清晰分为四个顶层键primitive颜色gray/blue/red/green/yellow/white、间距、字号、圆角、阴影、时长均以$type标注color/dimension/shadow/durationsemantic背景/前景/主色/次色/静默色/破坏色等语义色以及component/section间距语义值通过{primitive.color.gray.50}形式的引用语法指向原始层componentbutton/input/card 的组件级 Token引用 semantic 或 primitivedark暗色模式下对 semantic 层的覆盖集。自动化生成从 JSON 到 CSS 变量仓库的 generate-tokens.cjs 将上述 JSON 模板一键编译为 CSS 变量文件命令如下见 SKILL.md 的 Quick Startnode scripts/generate-tokens.cjs --config tokens.json -o tokens.css命令行参数说明参数简写说明默认值--config-c输入 JSON Token 文件必填—--output-o输出文件路径缺省输出到 stdoutstdout--format-f输出格式css或tailwindcss--help-h打印帮助信息—该脚本实现了文档中描述的关键机制可从源码generate-tokens.cjs确认其工作原理引用解析resolveReference对{primitive.color.blue.600}形式的引用按.分割路径逐级查找 JSON若解析结果仍是引用则递归解引用直到得到最终字面值扁平化flattenTokens递归遍历 JSON遇到含$value的节点即视为一个 Token用toCssVarName将路径拼接为--color-blue-600形式的 CSS 变量名-- 路径用-连接.替换为-分层输出generateCSS分别扁平化primitive带primitive前缀、semantic、component与dark.semantic四段输出为带分节注释的 CSSTailwind 输出generateTailwind抽取 semantic 段中所有含color的变量生成colors: { primary: var(--color-primary), ... }形式的 Tailwind 颜色配置可直接粘贴进theme.extend.colors。自动化校验拦截硬编码值设计系统能否长期保鲜取决于纪律。仓库配套的 validate-tokens.cjs 提供代码级合规审计node scripts/validate-tokens.cjs --dir src/ node scripts/validate-tokens.cjs --dir src/ --fix # 仅提示建议修复不自动改写该校验器扫描.css/.scss/.tsx/.jsx/.ts/.js/.vue/.svelte文件检测四类违规validate-tokens.cjs检测类型正则匹配违规示例建议hexColor#RGB/#RRGGBB#2563EB改用var(--color-*)rgbColorrgb(r,g,b)rgb(37, 99, 235)改用var(--color-*)pixelValue两位数及以上 pxpadding: 16px改用var(--space-*)或var(--radius-*)remValue非 Token 定义处的 remfont-size: 1.5rem改用var(--space-*)或var(--font-size-*)脚本的细节设计体现了工程严谨性validate-tokens.cjs跳过白名单tailwind.config、globals.cssToken 定义处、tokens.css/json、压缩产物均不扫描避免误报常见豁免纯黑#000/#FFF等被认为是有意为之不报告忽略目录默认忽略node_modules、.git、dist、build、.next可用-i追加退出码发现违规时以非零退出码结束process.exit(1)可直接接入 CI 阻断合并。与 Tailwind / shadcn 的桥接三层 Token 的最终消费场景是 Tailwind 配置。tailwind-integration.md 给出了完整的桥接方案核心要点HSL 无函数格式在layer base中把语义色定义为空格分隔的 HSL 三值如--primary: 217 91% 60%;Tailwind 侧通过hsl(var(--primary))消费。这种格式的关键收益是支持透明度修饰符div classNamebg-primary/50 // 50% opacity div classNametext-primary/80 // 80% opacity // CSS 输出: background-color: hsl(217 91% 60% / 0.5);tailwind.config.ts 映射将background、foreground、primary、secondary、muted、accent、destructive、border、input、ring、card等键逐一映射到 CSS 变量圆角用var(--radius)及其派生值calc(var(--radius) - 2px/4px)定义lg/md/sm三级。组件类layer components.btn基类统一apply焦点环、禁用态与过渡.btn-default/.btn-secondary/.btn-outline/.btn-ghost/.btn-destructive五个变体类只引用语义色类bg-primary、text-primary-foreground等尺寸类.btn-sm/md/lg控制高度与内边距。shadcn/ui 兼容该配置与 shadcn/ui 的 CSS 变量命名、HSL 格式、色阶结构完全一致可直接执行npx shadcnlatest init与npx shadcnlatest add button card input新增组件会自动消费你定义的设计系统 Token。从架构文档到最佳实践SKILL.md 将 Token 架构固化为六条工程纪律可作为落地检查清单组件中绝不使用原始 hex 值一律引用 Token语义层是主题切换亮/暗的唯一入口组件 Token 提供按组件定制的能力使用 HSL 格式以获得透明度控制每个 Token 都应记录用途幻灯片等产物必须导入 design-tokens.css 并仅使用var()。这套三层 Token 架构与 semantic-tokens.md、component-tokens.md、states-and-variants.md交互状态优先级、焦点环、禁用/加载/错误态规范、component-specs.md组件规格表共同构成完整的设计系统闭环JSON 定义 → 脚本生成 CSS → Tailwind 桥接 → 组件消费 → 校验器守护。接入时从仓库模板 design-tokens-starter.json 起步、以 generate-tokens.cjs 与 validate-tokens.cjs 为工具链即可在一套代码库中同时获得品牌一致性、主题可切换与组件可定制的三重能力。【免费下载链接】ui-ux-pro-max-skillAn AI skill that provides design intelligence for building professional UI/UX across multiple platforms.项目地址: https://gitcode.com/gh_mirrors/ui/ui-ux-pro-max-skill创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表