设计系统多品牌架构实践:一套 Token 驱动多套视觉的系统化方案
设计系统多品牌架构实践一套 Token 驱动多套视觉的系统化方案一、多品牌视觉统一的管理困局Token 重复定义与一致性失控当一家 SaaS 公司推出多个子品牌或者一个平台需要支持白标White Label定制时设计系统的复杂度会呈指数级增长。典型场景包括集团旗下针对不同行业的子产品需要统一的组件行为但差异化的视觉风格、独立产品为不同客户提供可定制的 UI 主题、以及国际化产品需要适配不同地区的设计偏好。在多品牌场景下设计系统面临的核心矛盾是组件逻辑需要高度复用一个 Button 组件在所有品牌中的交互行为是一致的但视觉表现需要灵活切换颜色、圆角、字体、间距在不同品牌间差异明显。传统的做法是维护多套独立的 CSS 变量文件或主题配置但这种方式容易导致某品牌新增一个组件的视觉定义后忘记同步到其他品牌、主题变量在多套文件中重复定义导致维护成本线性增长、以及设计规范变更时需要逐一修改多套主题文件。一套系统化的多品牌架构需要解决三个核心问题Token 的单一定义源、品牌间变量映射的自动化、以及组件的品牌感知能力。二、多品牌 Token 架构的核心层次2.1 三层 Token 模型设计 Token 的三层模型是解决多品牌映射的关键抽象基础 TokenPrimitive Tokens设计语言的最原子级别定义。它们是纯粹的值不携带语义。例如blue-500: #1976D2、spacing-16: 16px、radius-md: 8px。基础 Token 由设计团队维护变更频率极低。语义 TokenSemantic Tokens将基础 Token 赋予功能性含义。例如color-primary: {blue-500}、spacing-container: {spacing-16}。同一语义 Token 在不同品牌中可以映射到不同的基础 Token。这一层是多品牌差异化的核心。组件 TokenComponent Tokens绑定到具体 UI 组件。例如button-primary-bg: {color-primary}、card-border-radius: {radius-lg}。组件 Token 通常直接引用语义 Token仅在需要组件级微调时才独立定义。三层模型的优势在于变更的影响范围可控修改基础 Token 的值会影响所有引用它的语义 Token全局变更修改语义 Token 的映射仅影响当前品牌品牌级变更修改组件 Token 仅影响特定组件。2.2 品牌映射机制的实现品牌映射的核心数据结构是一个 Token Map它将语义 Token 名称映射到不同品牌的实际值。这个映射关系需要在构建时解析并在运行时通过 CSS 变量注入到 DOM 中。两种映射策略的选择构建时静态映射在构建阶段为每个品牌生成独立的 CSS 文件。优势是运行时零开销劣势是无法在运行时动态切换品牌需要页面重新加载。运行时动态映射将所有品牌的 Token 值都编译为 CSS 变量前缀如--brand-a-color-primary运行时通过切换 CSS 类名实现品牌切换。优势是支持热切换劣势是 CSS 文件体积更大。实际项目中更常见的是混合策略默认主题使用构建时静态映射保证首屏性能品牌切换逻辑通过 CSS 变量覆盖实现如通过 JavaScript 动态修改:root上的 CSS 变量值。2.3 品牌衍生的自动化流程品牌衍生不应是每次手动复制粘贴 Token 文件。一个可持续的流程应包括品牌基类定义所有品牌共有的默认 Token 值品牌 A 作为基准。增量覆盖品牌 B 仅定义与基准有差异的 Token其余自动继承基准值。差异检测告警当基准 Token 增加新定义时自动检测哪些品牌尚未覆盖生成提醒通知。设计稿同步支持从 Figma 的 Design Token 插件导出 JSON自动转换为代码中的 Token 映射表。三、生产级多品牌系统实现以下实现展示了一个完整的多品牌设计系统包含 Token 引擎、品牌管理和组件注入/** * 多品牌设计 Token 引擎 * 实现三层 Token 模型 品牌映射 CSS 变量生成 */ // ---- Token 类型定义 ---- interface PrimitiveTokens { colors: Recordstring, string; spacing: Recordstring, string; radii: Recordstring, string; fonts: Recordstring, string; } interface SemanticTokens { colorPrimary: string; colorSecondary: string; colorBackground: string; colorSurface: string; colorText: string; colorTextSecondary: string; colorBorder: string; spacingXs: string; spacingSm: string; spacingMd: string; spacingLg: string; radiusSm: string; radiusMd: string; radiusLg: string; fontFamily: string; fontSizeBase: string; } interface ComponentTokens { button: { primaryBg: string; primaryText: string; borderRadius: string; paddingX: string; paddingY: string; }; card: { bg: string; borderRadius: string; padding: string; shadow: string; }; input: { bg: string; border: string; borderRadius: string; paddingX: string; paddingY: string; focusBorder: string; }; } // ---- 基础 Token单一定义源 ---- const primitives: PrimitiveTokens { colors: { blue-500: #1976D2, blue-600: #1565C0, green-500: #4CAF50, red-500: #F44336, orange-500: #FF9800, gray-50: #FAFAFA, gray-100: #F5F5F5, gray-200: #EEEEEE, gray-300: #E0E0E0, gray-600: #757575, gray-800: #424242, gray-900: #212121, white: #FFFFFF, black: #000000, }, spacing: { 4: 4px, 8: 8px, 12: 12px, 16: 16px, 24: 24px, 32: 32px, }, radii: { sm: 4px, md: 8px, lg: 16px, full: 9999px, }, fonts: { sans: Inter, -apple-system, BlinkMacSystemFont, sans-serif, mono: JetBrains Mono, Fira Code, monospace, }, }; // ---- 品牌映射层 ---- interface BrandConfig { id: string; name: string; // 语义 Token 从基础 Token 的映射函数 semanticResolver(primitives: PrimitiveTokens): SemanticTokens; // 组件 Token 从语义 Token 的映射函数可选覆盖 componentOverrides?: PartialComponentTokens; } // 品牌 A默认基准 const brandA: BrandConfig { id: brand-a, name: 默认品牌, semanticResolver: (p) ({ colorPrimary: p.colors[blue-500], colorSecondary: p.colors[green-500], colorBackground: p.colors[gray-50], colorSurface: p.colors[white], colorText: p.colors[gray-900], colorTextSecondary: p.colors[gray-600], colorBorder: p.colors[gray-300], spacingXs: p.spacing[4], spacingSm: p.spacing[8], spacingMd: p.spacing[16], spacingLg: p.spacing[24], radiusSm: p.radii[sm], radiusMd: p.radii[md], radiusLg: p.radii[lg], fontFamily: p.fonts[sans], fontSizeBase: 16px, }), }; // 品牌 B深色主题 橙色主调 const brandB: BrandConfig { id: brand-b, name: 企业版品牌, semanticResolver: (p) ({ colorPrimary: p.colors[orange-500], colorSecondary: p.colors[blue-500], colorBackground: p.colors[gray-900], colorSurface: p.colors[gray-800], colorText: p.colors[white], colorTextSecondary: p.colors[gray-300], colorBorder: p.colors[gray-600], spacingXs: p.spacing[4], spacingSm: p.spacing[8], spacingMd: p.spacing[16], spacingLg: p.spacing[24], radiusSm: 6px, // 品牌 B 圆角更大 radiusMd: 12px, radiusLg: 20px, fontFamily: p.fonts[sans], fontSizeBase: 16px, }), componentOverrides: { card: { // 品牌 B 的卡片有特殊阴影 shadow: 0 4px 20px rgba(0,0,0,0.3), }, }, }; // ---- Token 引擎 ---- class DesignTokenEngine { private brands: Mapstring, BrandConfig new Map(); private defaultComponentTokens!: ComponentTokens; /** * 注册品牌配置 */ registerBrand(config: BrandConfig): void { this.brands.set(config.id, config); } /** * 为指定品牌生成完整的 CSS 变量 */ generateCSSVariables(brandId: string): string { const brand this.brands.get(brandId); if (!brand) { throw new Error(品牌 ${brandId} 未注册可用品牌${[...this.brands.keys()].join(, )}); } // 1. 生成语义 Token const sematic brand.semanticResolver(primitives); // 2. 基于语义 Token 生成组件 Token const components this.buildComponentTokens(sematic, brand.componentOverrides); // 3. 拼接为 CSS 变量字符串 const lines: string[] []; lines.push(/* ${brand.name} 主题 - 自动生成 */); lines.push([data-brand brandId ] {); // 语义级变量 lines.push( --dt-color-primary: ${sematic.colorPrimary};); lines.push( --dt-color-secondary: ${sematic.colorSecondary};); lines.push( --dt-color-bg: ${sematic.colorBackground};); lines.push( --dt-color-surface: ${sematic.colorSurface};); lines.push( --dt-color-text: ${sematic.colorText};); lines.push( --dt-color-text-secondary: ${sematic.colorTextSecondary};); lines.push( --dt-color-border: ${sematic.colorBorder};); lines.push( --dt-spacing-xs: ${sematic.spacingXs};); lines.push( --dt-spacing-md: ${sematic.spacingMd};); lines.push( --dt-spacing-lg: ${sematic.spacingLg};); lines.push( --dt-radius-sm: ${sematic.radiusSm};); lines.push( --dt-radius-md: ${sematic.radiusMd};); lines.push( --dt-font-family: ${sematic.fontFamily};); // 组件级变量 lines.push( --dt-btn-primary-bg: ${components.button.primaryBg};); lines.push( --dt-btn-primary-text: ${components.button.primaryText};); lines.push( --dt-btn-radius: ${components.button.borderRadius};); lines.push( --dt-btn-px: ${components.button.paddingX};); lines.push( --dt-btn-py: ${components.button.paddingY};); lines.push( --dt-card-bg: ${components.card.bg};); lines.push( --dt-card-radius: ${components.card.borderRadius};); lines.push( --dt-card-padding: ${components.card.padding};); lines.push( --dt-card-shadow: ${components.card.shadow};); lines.push( --dt-input-bg: ${components.input.bg};); lines.push( --dt-input-border: ${components.input.border};); lines.push( --dt-input-radius: ${components.input.borderRadius};); lines.push( --dt-input-focus-border: ${components.input.focusBorder};); lines.push(}); return lines.join(\n); } /** * 生成所有已注册品牌的 CSS */ generateAllBrandsCSS(): string { const blocks: string[] []; // 首先生成默认主题不带品牌属性作为兜底 blocks.push(this.generateDefaultTheme()); // 逐个品牌生成 for (const brandId of this.brands.keys()) { blocks.push(this.generateCSSVariables(brandId)); } return blocks.join(\n\n); } /** * 生成默认降级主题无>

相关新闻

面向FaaS的算网异构算力调度技术

面向FaaS的算网异构算力调度技术

引 言 国家发改委等四部门联合发布《全国一体化大数据中心协同创新体系算力枢纽实施方案》,提出在京津冀、长三角、粤港澳大湾区、成渝以及贵州、内蒙古、甘肃、宁夏建设全国算力网络国家枢纽节点,启动实施“东数西算”工程,构建国家算力网络…

2026/7/17 16:23:14阅读更多 →
前端容器化隔离方案对比:iframe、Shadow DOM 与 Web Component 的架构选型

前端容器化隔离方案对比:iframe、Shadow DOM 与 Web Component 的架构选型

前端容器化隔离方案对比:iframe、Shadow DOM 与 Web Component 的架构选型 一、微前端与组件嵌入的隔离困局:CSS 污染、JS 冲突与安全边界 前端容器化隔离的需求正在快速增长。微前端架构、第三方组件嵌入、多团队协作、以及低代码平台的可插拔 Widget 机…

2026/7/17 16:23:14阅读更多 →
Anolis OS 8安装NVIDIA Corporation GA102GL [A10]显卡驱动

Anolis OS 8安装NVIDIA Corporation GA102GL [A10]显卡驱动

文章目录⚙️驱动安装Tips:下面的全部都没用~~🖥️ 一、准备工作~~🖥️ 二、安装 NVIDIA 驱动直接安装方法(推荐):~~**dnf 安装**(不推荐)~~**验证安装:**🖥️ ~~三、安装 CUDA 驱动(不推荐)~~🖥️ 四、验证…

2026/7/17 16:23:14阅读更多 →
Windows环境下微信数据库密钥提取:Sharp-dumpkey工具原理与实战教程

Windows环境下微信数据库密钥提取:Sharp-dumpkey工具原理与实战教程

1. 项目概述:为什么需要关注微信数据库密钥在移动应用开发、数据安全研究乃至个人数据备份的领域,微信的本地数据库一直是一个绕不开的话题。无论是出于分析用户行为模式、进行数据恢复,还是进行安全审计,访问微信存储在本地的聊天…

2026/7/17 17:29:03阅读更多 →
2000行代码挑战Netty、Spring,轻量级框架如何打破“代码量崇拜”迷思?

2000行代码挑战Netty、Spring,轻量级框架如何打破“代码量崇拜”迷思?

大学老师白教了但凡正经学过计算机基础课的人,都记得老师反复强调:代码量从来不是衡量标准,算法的时间复杂度和空间复杂度才是。但很多人走出校门就把这条准则忘得一干二净。他们质疑“你这框架才这么点代码,能稳定吗?…

2026/7/17 17:29:03阅读更多 →
Windows11与WSL2开发环境配置全指南

Windows11与WSL2开发环境配置全指南

1. Windows11与WSL2的黄金组合:开发者的效率革命三年前当我第一次尝试在Windows上搭建Python开发环境时,被各种路径冲突和包管理问题折磨得焦头烂额。直到发现WSL2这个神器,才真正体会到在Windows系统上获得完整Linux开发体验的畅快。不同于传…

2026/7/17 17:29:03阅读更多 →
GPT5.6Sol误删数据引争议:AI越聪明越易出事,Agent时代安全成关键!

GPT5.6Sol误删数据引争议:AI越聪明越易出事,Agent时代安全成关键!

GPT5.6Sol误删数据引争议:AI越聪明越易出事?Agent时代安全成关键!雷科技发现,随着GPT5.6全面推送,“GPT删用户资料”的吐槽在推特、Reddit等海外论坛、社区愈发常见。用户反馈,GPT虽变聪明,却也…

2026/7/17 17:29:03阅读更多 →
OpenClaw 2.6.4 Windows一键部署指南:AI Agent运行时环境筑基

OpenClaw 2.6.4 Windows一键部署指南:AI Agent运行时环境筑基

1. 项目概述:这不是普通软件安装,而是一次面向AI Agent开发者的环境筑基OpenClaw 2.6.4 这个名字最近在ROS开发者、机器人算法工程师和本地大模型应用实践者圈子里频繁出现,它不是传统意义上的桌面工具,而是一个专为Windows平台深…

2026/7/17 17:29:03阅读更多 →
【AI驱动LinkedIn增长实战手册】:20年SaaS营销专家亲授7大自动化运营策略,错过再等一年

【AI驱动LinkedIn增长实战手册】:20年SaaS营销专家亲授7大自动化运营策略,错过再等一年

更多请点击: https://intelliparadigm.com 第一章:AI驱动LinkedIn增长的核心逻辑与底层认知 LinkedIn 的增长早已超越传统社交网络的“连接人数”范式,转向以 AI 为引擎的智能价值匹配系统。其底层认知并非简单地优化点击率或停留时长&#…

2026/7/17 17:24:01阅读更多 →
VSCode TypeScript 环境配置对比:全局安装 vs 项目本地安装的4个关键差异

VSCode TypeScript 环境配置对比:全局安装 vs 项目本地安装的4个关键差异

VSCode TypeScript 环境配置对比:全局安装 vs 项目本地安装的4个关键差异当你在VSCode中启动一个新的TypeScript项目时,第一个技术决策往往从安装方式开始。这个看似简单的选择——全局安装还是项目本地安装——实际上会深刻影响你的开发流程、团队协作和…

2026/7/17 10:42:55阅读更多 →
智慧树刷课插件:5分钟实现自动化学习的智能助手

智慧树刷课插件:5分钟实现自动化学习的智能助手

智慧树刷课插件:5分钟实现自动化学习的智能助手 【免费下载链接】zhihuishu 智慧树刷课插件,自动播放下一集、1.5倍速度、无声 项目地址: https://gitcode.com/gh_mirrors/zh/zhihuishu 智慧树刷课插件是一款专为智慧树在线教育平台设计的Chrome浏…

2026/7/17 8:31:03阅读更多 →
Steam创意工坊下载器WorkshopDL:跨平台游戏模组获取的终极解决方案

Steam创意工坊下载器WorkshopDL:跨平台游戏模组获取的终极解决方案

Steam创意工坊下载器WorkshopDL:跨平台游戏模组获取的终极解决方案 【免费下载链接】WorkshopDL WorkshopDL - The Best Steam Workshop Downloader 项目地址: https://gitcode.com/gh_mirrors/wo/WorkshopDL 你是否在GOG或Epic Games Store购买了心仪的游戏…

2026/7/17 13:22:23阅读更多 →
VS Code 高效配置与个性化定制全攻略

VS Code 高效配置与个性化定制全攻略

1. VS Code 高效配置基础作为一款轻量级但功能强大的代码编辑器,VS Code 的默认配置已经能满足基本需求,但通过合理调整设置可以大幅提升编码效率。我使用 VS Code 已经有五年多时间,期间尝试过各种配置方案,总结出这套适合大多数…

2026/7/17 0:00:01阅读更多 →
从竞赛代码到桌面工具:让 SuperADD 与 SubspaceAD 真正跑进自己的图像

从竞赛代码到桌面工具:让 SuperADD 与 SubspaceAD 真正跑进自己的图像

在异常检测领域,很多优秀算法最初都是以研究代码的形式发布的。它们能够在固定测试集上复现实验结果,却不一定能被普通用户直接拿来测试自己的图片。尤其是最近很多算法仅提供在固定测试集的测试环境,而gradio的demo演示也不会提供。 对工程应用和在自己的图片上进行测试来…

2026/7/17 0:00:01阅读更多 →
WinRAR高效配置指南:从基础安装到高级压缩实战

WinRAR高效配置指南:从基础安装到高级压缩实战

前几天帮同事处理一个客户发来的压缩包,解压时系统自带的工具弹出一串乱码,换用 WinRAR 却顺利打开了。这种看似简单的场景,恰恰暴露了不同压缩工具在处理非标准编码、分卷压缩或加密文件时的差异。WinRAR 作为一款老牌工具,真正价…

2026/7/17 0:00:01阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/16 20:13:14阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/17 13:22:38阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/17 17:26:50阅读更多 →