UI/UX 设计语言系统

设计语言系统(Design Language System,DLS)是一套完整的设计标准,旨在通过可复用的组件和模式来大规模管理设计。它将品牌、设计规范和代码实现统一为一个有凝聚力的生态系统,使设计师和开发者能够高效、一致地构建数字产品。

核心定义:设计语言系统 = 设计理念(Principles) + 设计令牌(Tokens) + 组件库(Components) + 模式库(Patterns) + 文档指南(Guidelines)

1. 概述

1.1 DLS 五层模型

一个成熟的设计语言系统通常在以下层面产生价值:

层级内容典型产物
设计理念品牌价值观、设计原则、可访问性标准Design Principles、Brand Guidelines
Design Tokens颜色、间距、字体、阴影等原子级设计决策tokens.json、CSS Variables、Sass Maps
组件Button、Input、Card、Modal 等可复用 UI 单元React/Vue 组件、Figma Variants
模式表单页、列表页、详情页等可复用页面布局Page Templates、Layout Presets
文档使用指南、代码示例、设计规范Storybook、Zeroheight、Docusaurus

1.2 主流设计流程规范

在动手搭建 DLS 之前,必须先理解业界公认的 UI/UX 设计流程框架。以下四套方法论是当今互联网和软件行业最广泛采用的设计流程标准。

Double Diamond(双钻模型)— 英国设计委员会

最具影响力的设计流程框架之一,将设计过程分为四个阶段,两次「发散—收敛」循环,形态如两颗钻石。

阶段动作核心产出
Discover 发现用户研究、竞品分析、利益相关者访谈用户画像、旅程地图、问题陈述
Define 定义综合研究发现,收敛为清晰的问题定义设计简报(Design Brief)、HMW 问题
Develop 开发头脑风暴、草图、低保真原型、多方案迭代线框图、交互原型、A/B 方案
Deliver 交付高保真设计、用户测试、最终验收高保真 Mockup、设计标注、开发 Spec
核心思想:先拓宽(发散)再收窄(收敛),确保「做正确的事」再「正确地做事」。与 DLS 的关系——Discover/Define 阶段产出设计原则和 Token 命名策略;Develop/Deliver 阶段产出组件库和文档。

Design Thinking(设计思维)— IDEO / Stanford d.school

以人为中心的设计方法论,强调同理心和快速迭代,广泛用于产品创新和数字化转型项目。

阶段核心问题常用方法
Empathize 共情用户真正需要什么?用户访谈、影子观察、沉浸式体验
Define 定义核心问题是什么?亲和图、POV 陈述、用户故事
Ideate 构思有哪些可能的解决方案?头脑风暴、疯狂八分钟、SCAMPER
Prototype 原型如何快速验证想法?纸质原型、可交互原型、Wizard of Oz
Test 测试方案是否有效?如何改进?可用性测试、A/B 测试、启发式评估

Google Design Sprint — Google Ventures

5 天快速验证产品方向的紧凑流程,适合新功能或新产品从零到一的场景。

Day主题活动
周一Map 绘制地图定义长期目标、绘制用户旅程、选择焦点
周二Sketch 草图发散竞品闪电演示、个人方案草图
周三Decide 决策投票选出最优方案、绘制故事板
周四Prototype 原型搭建可交互的高保真原型
周五Test 测试与 5 名真实用户进行可用性测试

User-Centered Design(以用户为中心的设计)— ISO 9241-210

国际标准化组织定义的交互系统人因工程标准,是所有设计流程的底层哲学基础。

原则含义在 DLS 中的体现
基于用户、任务和环境的明确理解设计决策必须有用户数据支撑Color Token 命名考虑色觉障碍用户(WCAG 对比度 ≥ 4.5:1)
用户全程参与设计与开发从需求到验收用户持续介入组件库发布前执行可用性测试,收集开发者使用反馈
通过用户反馈驱动与迭代设计设计是循环迭代过程Storybook 集成 Chromatic 视觉回归测试,每个版本收集 Analytics
设计面向整体用户体验考虑视觉、交互、情感、可访问性Token 覆盖颜色/间距/动效/声音,组件覆盖 loading/empty/error 状态
设计团队包含多学科技能和视角设计师+开发者+PM+用户研究Design Token 采用 DTCG 规范,设计师在 Figma 与开发者在代码中使用同一套变量名

流程规范与 DLS 的映射关系

一个 DLS 项目的完整落地路径,自然对应上述流程的不同阶段:

DLS 建设阶段对应流程关键产物
品牌与设计原则确立Double Diamond (Discover + Define)Design Principles 文档、品牌色板
Design Token 体系设计Design Thinking (Empathize + Define)Token 命名规范、Global/Alias/Component 三层架构
组件库 MVP 构建Design Sprint (Sketch + Prototype)核心组件 (Button/Input/Table/Modal) 代码实现
文档站与使用指南ISO 9241-210 (用户参与)Storybook / Zeroheight + 快速入门指南
迭代与维护Design Thinking (Test → 循环)版本 CHANGELOG、组件使用统计、定期 Review

2. 行为图(系统"做什么")

从用户角色与工作流的角度,描述设计语言系统在生产环境中的运转方式。

2.1 用例图 —— 参与者与使用场景

设计语言系统的核心参与者包括设计师、前端开发者、产品经理和品牌团队。每个角色在系统中有不同的关注点和操作。

DLS Use Case Diagram
图 2-1:设计语言系统用例图

2.2 活动图 —— 设计系统构建与消费流程

从 Foundation 层的 Design Token 定义开始,逐层构建到 Component、Pattern,最终被设计师与开发者消费。

DLS Activity Diagram
图 2-2:设计语言系统构建与消费活动图

Demo — Style Dictionary 配置示例:下方展示了如何用 Style Dictionary 将一份 token 定义转换为多平台输出。

// tokens/color.json
{
  "color": {
    "primary": { "value": "#1677ff" },
    "success": { "value": "#52c41a" },
    "warning": { "value": "#faad14" },
    "danger":  { "value": "#ff4d4f" }
  }
}

// config.js —— Style Dictionary 配置
const StyleDictionary = require('style-dictionary');

StyleDictionary.extend({
  source: ['tokens/**/*.json'],
  platforms: {
    css: {
      transformGroup: 'css',
      buildPath: 'dist/',
      files: [{ destination: 'variables.css', format: 'css/variables' }]
    },
    scss: {
      transformGroup: 'scss',
      buildPath: 'dist/',
      files: [{ destination: 'variables.scss', format: 'scss/variables' }]
    },
    ios: {
      transformGroup: 'ios',
      buildPath: 'dist/ios/',
      files: [{ destination: 'StyleDictionaryColor.h', format: 'ios/colors.h' }]
    }
  }
}).buildAllPlatforms();

2.3 序列图 —— 从 Design Token 到最终 UI 的渲染管线

一条设计决策如何在设计工具中产生,通过 Token 系统编译,注入组件库,最终渲染为终端用户看到的 UI。

DLS Sequence Diagram
图 2-3:Design Token 到 UI 的端到端序列图

3. 结构图(系统"由什么组成")

从架构与数据模型的维度,拆解设计语言系统的内部组成与模块关系。

3.1 包图 —— DLS 模块分层架构

设计语言系统通常遵循 Atomic Design 分层模型,从 Foundation(原子级的 Token)到 Component(分子/有机体级的 UI 单元),再到 Pattern(页面模板)。

DLS Package Diagram
图 3-1:设计语言系统模块分层包图

Demo — 原子组件 → 分子组件 → 有机体组件:

// ------ Atoms: Token 驱动的原子组件 ------
// Button.tsx(仅依赖 token 变量)
import './button.css';  // 内部引用 var(--color-primary) 等 CSS 变量

export const Button = ({ variant = 'primary', children }) => (
  <button className={`btn btn-${variant}`}>{children}</button>
);

// ------ Molecules: 组合原子 ------
// SearchBar.tsx(组合 Input + Button)
import { Input } from './Input';
import { Button } from './Button';

export const SearchBar = ({ onSearch }) => (
  <div className="search-bar">
    <Input placeholder="搜索..." />
    <Button variant="primary">搜索</Button>
  </div>
);

// ------ Organisms: 组合分子 ------
// PageHeader.tsx(组合 Logo + Nav + SearchBar + Avatar)
export const PageHeader = () => (
  <header className="page-header">
    <Logo />
    <Nav items={navItems} />
    <SearchBar onSearch={handleSearch} />
    <Avatar />
  </header>
);

3.2 组件图 —— DLS 系统整体拓扑

从工具链、Token 引擎、组件库到文档站与 CI/CD 管线的全链路架构。

DLS Component Diagram
图 3-2:设计语言系统组件拓扑图

3.3 类图 —— Design Token 与 Component 数据模型

设计语言系统中最核心的数据模型:DesignToken 承载原子级设计决策,Theme 组织多套 Token 集合,Component 引用 Token 进行渲染,Pattern 组合 Component 构建页面。

DLS Class Diagram
图 3-3:设计语言系统核心类图

Demo — Token JSON 结构示例:

{
  "global": {
    "color": {
      "blue":  { "500": { "value": "#1677ff" } },
      "red":   { "500": { "value": "#ff4d4f" } },
      "green": { "500": { "value": "#52c41a" } },
      "gray":  { "100": { "value": "#f5f5f5" }, "900": { "value": "#1f1f1f" } }
    },
    "spacing": {
      "xs": { "value": "4px" },
      "sm": { "value": "8px" },
      "md": { "value": "16px" },
      "lg": { "value": "24px" },
      "xl": { "value": "32px" }
    },
    "radius": {
      "sm": { "value": "4px" },
      "md": { "value": "8px" },
      "round": { "value": "9999px" }
    }
  },
  "alias": {
    "color": {
      "primary":   { "value": "{global.color.blue.500}" },
      "danger":    { "value": "{global.color.red.500}" },
      "success":   { "value": "{global.color.green.500}" },
      "bg-base":   { "value": "{global.color.gray.100}" },
      "text-base": { "value": "{global.color.gray.900}" }
    }
  },
  "component": {
    "button": {
      "padding-x": { "value": "{global.spacing.md}" },
      "padding-y": { "value": "{global.spacing.sm}" },
      "radius":    { "value": "{global.radius.md}" },
      "bg-primary": { "value": "{alias.color.primary}" }
    }
  }
}

4. 实战速查手册

4.1 主流设计系统对比

设计系统出品方核心框架Token 方案适用场景
Material Design 3GoogleAndroid / Flutter / Web Design Token + M3 Tokens 跨平台移动/Web 应用
Human Interface GuidelinesAppleSwiftUI / UIKit SF Symbols + Color Assets iOS / macOS 原生应用
Fluent 2MicrosoftReact / WinUI Fluent Tokens M365 / Windows 生态
Ant Design 5蚂蚁集团React / Vue / Angular CSS-in-JS + ConfigProvider 企业级中后台
CarbonIBMReact / Svelte / Vue Carbon Tokens 企业 SaaS 产品
PolarisShopifyReact Polaris Tokens 电商管理后台
SpectrumAdobeReact / SwiftUI Spectrum Tokens 创意工具 / 企业应用

4.2 Design Token 设计速查

Token 三层架构(DTCG 规范):

Token 类别示例 Key示例 ValueCSS 变量
颜色color-brand-primary#1677ff--color-brand-primary
间距spacing-md16px / 1rem--spacing-md
字号font-size-body14px / 0.875rem--font-size-body
字重font-weight-bold600--font-weight-bold
圆角radius-md8px--radius-md
阴影shadow-card0 2px 8px rgba(0,0,0,0.1)--shadow-card
动效duration-fast150ms--duration-fast
断点breakpoint-md768px--breakpoint-md

4.3 Atomic Design 层级速查

Brad Frost 提出的 Atomic Design 方法论是大多数设计语言系统的思想基础:

层级类比含义Web 示例
Atoms原子不可再分的 UI 基础元素Button、Input、Icon、Label、Color
Molecules分子多个原子组合成的功能单元SearchBar(Input + Button)、FormItem(Label + Input)
Organisms有机体多个分子组成的独立区域PageHeader、Sidebar、ProductCard
Templates模板有机体布局形成页面骨架列表页模板、详情页模板
Pages页面模板填入真实内容后的最终产物用户管理列表页、订单详情页

4.4 工具链速查

环节工具用途
设计工具Figma / SketchUI 设计、组件 Variant 管理、Token 预览
Token 管理Style Dictionary / Tokens StudioToken 定义、编译、多平台输出
组件开发Storybook / Ladle组件独立开发、可视化测试
文档站点Zeroheight / Docusaurus / Gatsby设计规范文档、使用指南
版本管理Git + Changesets组件版本控制、CHANGELOG 自动生成
CI/CDGitHub Actions / Chromatic自动构建、视觉回归测试、NPM 发布
质量保障Lighthouse / axe-core可访问性检测、性能审计

5. 实战演示

本章完整演示从整体布局设计 → Token 工程 → 组件开发 → 文档站搭建的全流程,以管理员后台(Admin Dashboard)为目标场景。

5.1 整体布局设计

设计任何 UI 的第一步永远是确定整体布局骨架。在动手写组件或 Token 之前,先回答三个问题:

  1. 信息架构(IA):页面有哪些区域?它们之间的主次关系是什么?
  2. 网格系统(Grid):用几列栅格?间距基准是多少?
  3. 响应式策略:不同屏幕宽度下布局如何变化?

示例场景:管理员后台 Dashboard

我们定义如下页面区域:

Dashboard Layout Wireframe
图 5-1:管理员后台整体布局线框图

布局 Token(Layout Tokens)—— 在 tokens/layout.json 中定义:

{
  "layout": {
    "sidebar":  { "width": { "value": "240px" }, "collapsed": { "value": "64px" } },
    "header":   { "height": { "value": "56px" } },
    "content":  { "max-width": { "value": "1280px" } }
  },
  "grid": {
    "columns":  { "value": 12 },
    "gutter":   { "value": "16px" },
    "margin":   { "value": "24px" }
  },
  "breakpoint": {
    "xs": { "value": "0" },
    "sm": { "value": "576px" },
    "md": { "value": "768px" },
    "lg": { "value": "992px" },
    "xl": { "value": "1200px" },
    "xxl":{ "value": "1600px" }
  }
}

CSS 栅格系统实现 grid.css:

:root {
  --grid-columns: 12;
  --grid-gutter:  16px;
  --grid-margin:  24px;
}

.ds-grid {
  display: grid;
  grid-template-columns: repeat(var(--grid-columns), 1fr);
  gap: var(--grid-gutter);
  padding: 0 var(--grid-margin);
}

.ds-col-4  { grid-column: span 4; }
.ds-col-6  { grid-column: span 6; }
.ds-col-8  { grid-column: span 8; }
.ds-col-12 { grid-column: span 12; }

/* 响应式 — 小屏时列堆叠 */
@media (max-width: 768px) {
  .ds-grid { grid-template-columns: 1fr; }
  .ds-col-4, .ds-col-6, .ds-col-8, .ds-col-12 {
    grid-column: span 1;
  }
}

页面布局骨架结构 DashboardLayout.tsx:

export const DashboardLayout = ({ children, collapsed }) => (
  <div className="app-shell">
    <aside className={`sidebar ${collapsed ? 'collapsed' : ''}`}>
      <Logo />
      <Nav items={menuItems} collapsed={collapsed} />
    </aside>
    <div className="main-area">
      <header className="topbar">
        <Breadcrumb />
        <UserMenu />
      </header>
      <main className="content">
        {children}
      </main>
    </div>
  </div>
);

布局样式 layout.css(100% 引用 Token 变量):

.app-shell {
  display: flex;
  height: 100vh;
}
.sidebar {
  width: var(--layout-sidebar-width);
  background: var(--semantic-color-bg-subtle);
  border-right: 1px solid var(--semantic-color-border);
  transition: width var(--duration-normal, 0.2s);
  flex-shrink: 0;
}
.sidebar.collapsed {
  width: var(--layout-sidebar-collapsed);
}
.main-area {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.topbar {
  height: var(--layout-header-height);
  background: var(--semantic-color-bg-container);
  border-bottom: 1px solid var(--semantic-color-border);
  display: flex; align-items: center;
  padding: 0 var(--spacing-lg);
  justify-content: space-between;
  flex-shrink: 0;
}
.content {
  flex: 1;
  overflow-y: auto;
  padding: var(--spacing-xl);
  max-width: var(--layout-content-max-width);
  margin: 0 auto;
  width: 100%;
}
@media (max-width: 768px) {
  .sidebar { width: var(--layout-sidebar-collapsed); }
  .content { padding: var(--spacing-md); }
}
设计原则:先定骨架,再填血肉。整体布局决定了导航模式、用户流线和信息密度,是后续所有组件设计的上层约束。布局 Token 和栅格系统必须在项目最早阶段锁定,避免后期大规模重构。

5.2 搭建 Design Token 工程

目标:使用 Style Dictionary 将一份 Token JSON 源文件编译为 CSS 变量、SCSS 变量和 Swift 常量,实现「一次定义、多端输出」。

Step 1 — 初始化工程:

mkdir my-dls && cd my-dls
npm init -y
npm install style-dictionary --save-dev

Step 2 — 定义 Token 源文件 tokens/color.json:

{
  "color": {
    "brand": {
      "primary":   { "value": "#1677ff" },
      "success":   { "value": "#52c41a" },
      "warning":   { "value": "#faad14" },
      "danger":    { "value": "#ff4d4f" }
    },
    "neutral": {
      "black":     { "value": "#000000" },
      "white":     { "value": "#ffffff" },
      "gray-100":  { "value": "#f5f5f5" },
      "gray-500":  { "value": "#8c8c8c" },
      "gray-900":  { "value": "#1f1f1f" }
    }
  }
}

Step 3 — 定义语义化 Alias Token tokens/semantic.json:

{
  "semantic": {
    "color": {
      "primary":       { "value": "{color.brand.primary}" },
      "success":       { "value": "{color.brand.success}" },
      "danger":        { "value": "{color.brand.danger}" },
      "bg-container":  { "value": "{color.neutral.white}" },
      "bg-subtle":     { "value": "{color.neutral.gray-100}" },
      "text-primary":  { "value": "{color.neutral.gray-900}" },
      "text-secondary":{ "value": "{color.neutral.gray-500}" }
    }
  }
}

Step 4 — 编写 Style Dictionary 配置文件 sd.config.js:

const StyleDictionary = require('style-dictionary');

StyleDictionary.extend({
  source: ['tokens/**/*.json'],
  platforms: {
    css: {
      transformGroup: 'css',
      buildPath: 'dist/css/',
      files: [
        { destination: 'tokens.css',   format: 'css/variables' },
        {
          destination: 'tokens.json',
          format: 'json/flat',
          options: { outputReferences: true }
        }
      ]
    },
    scss: {
      transformGroup: 'scss',
      buildPath: 'dist/scss/',
      files: [
        { destination: '_tokens.scss', format: 'scss/variables' }
      ]
    },
    swift: {
      transformGroup: 'ios-swift',
      buildPath: 'dist/ios/',
      files: [
        { destination: 'DSColor.swift', format: 'ios-swift/class.swift' }
      ]
    }
  }
}).buildAllPlatforms();

Step 5 — 执行构建并验证输出:

npx style-dictionary build --config sd.config.js

# 输出的 CSS 变量示例 (dist/css/tokens.css)
# --color-brand-primary: #1677ff;
# --semantic-color-primary: #1677ff;
# --semantic-color-bg-container: #ffffff;
产出物:一份 Token JSON 源文件 → 三套平台产物(CSS / SCSS / Swift),后续组件开发只需引用这些变量,切换主题品牌色只需修改源文件重新构建。

5.3 构建主题化组件

目标:基于 Token CSS 变量构建一套 React 组件(Button / Card / Notification),支持亮色/暗色主题一键切换。

Step 1 — 定义暗色主题 Token tokens/dark-theme.json:

{
  "semantic": {
    "color": {
      "bg-container":  { "value": "{color.neutral.gray-900}" },
      "bg-subtle":     { "value": "#2a2a2a" },
      "text-primary":  { "value": "{color.neutral.white}" },
      "text-secondary":{ "value": "#a0a0a0" }
    }
  }
}

Step 2 — 在 sd.config.js 中新增暗色主题构建平台:

// 在 platforms 中追加:
cssDark: {
  transformGroup: 'css',
  buildPath: 'dist/css/',
  files: [
    {
      destination: 'tokens-dark.css',
      format: 'css/variables',
      filter: (token) => token.filePath.includes('dark-theme')
    }
  ]
}

Step 3 — 编写主题切换 Hook useTheme.ts:

import { useState, useEffect } from 'react';

type Theme = 'light' | 'dark';

const STORAGE_KEY = 'app-theme';

export function useTheme() {
  const [theme, setTheme] = useState<Theme>(() => {
    const stored = localStorage.getItem(STORAGE_KEY);
    if (stored === 'light' || stored === 'dark') return stored;
    return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
  });

  useEffect(() => {
    localStorage.setItem(STORAGE_KEY, theme);
  }, [theme]);

  const toggle = () => setTheme(t => t === 'light' ? 'dark' : 'light');

  return { theme, toggle };
}

Step 4 — 实现 Button 组件 Button.tsx:

import React from 'react';
import './Button.css';

interface ButtonProps {
  variant?: 'primary' | 'secondary' | 'danger';
  size?: 'sm' | 'md' | 'lg';
  disabled?: boolean;
  loading?: boolean;
  children: React.ReactNode;
  onClick?: () => void;
}

export const Button: React.FC<ButtonProps> = ({
  variant = 'primary', size = 'md',
  disabled = false, loading = false,
  children, onClick
}) => (
  <button
    className={`ds-btn ds-btn--${variant} ds-btn--${size}`}
    disabled={disabled || loading}
    onClick={onClick}
  >
    {loading && <span className="ds-btn__spinner" />}
    {children}
  </button>
);

Step 5 — Button 样式 Button.css(全部引用 Token 变量):

.ds-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: inherit;
  font-size: var(--font-size-body, 14px);
  font-weight: var(--font-weight-medium, 500);
  border: 1px solid transparent;
  border-radius: var(--radius-md, 6px);
  cursor: pointer;
  transition: background var(--duration-fast, 0.15s),
              box-shadow var(--duration-fast, 0.15s);
}
.ds-btn--sm  { padding: 4px 12px; font-size: 12px; }
.ds-btn--md  { padding: 8px 16px; }
.ds-btn--lg  { padding: 12px 24px; font-size: 16px; }

.ds-btn--primary {
  color: #fff;
  background: var(--semantic-color-primary, #1677ff);
}
.ds-btn--primary:hover:not(:disabled) {
  background: var(--color-brand-primary-hover, #4096ff);
}
.ds-btn--primary:active:not(:disabled) {
  background: var(--color-brand-primary-active, #0958d9);
}

.ds-btn--secondary {
  color: var(--semantic-color-text-primary);
  background: var(--semantic-color-bg-container);
  border-color: var(--color-neutral-gray-300, #d9d9d9);
}
.ds-btn--secondary:hover:not(:disabled) {
  color: var(--semantic-color-primary);
  border-color: var(--semantic-color-primary);
}

.ds-btn--danger {
  color: #fff;
  background: var(--semantic-color-danger, #ff4d4f);
}
.ds-btn:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

.ds-btn__spinner {
  width: 14px; height: 14px;
  border: 2px solid transparent;
  border-top-color: currentColor;
  border-radius: 50%;
  animation: ds-spin 0.6s linear infinite;
}
@keyframes ds-spin { to { transform: rotate(360deg); } }

Step 6 — 主题注入 App.tsx:

import { useTheme } from './useTheme';
import { Button } from './components/Button';

function App() {
  const { theme, toggle } = useTheme();

  return (
    <div className={`app app--${theme}`}>
      <header style={{ display:'flex', justifyContent:'space-between',
                        padding:16, background:'var(--semantic-color-bg-subtle)' }}>
        <h1 style={{ color:'var(--semantic-color-text-primary)' }}>My DLS</h1>
        <Button variant="secondary" size="sm" onClick={toggle}>
          {theme === 'light' ? '🌙 暗色' : '☀️ 亮色'}
        </Button>
      </header>
      <main style={{ padding: 24 }}>
        <Button variant="primary">主按钮</Button>
        <Button variant="secondary">次按钮</Button>
        <Button variant="danger">危险按钮</Button>
        <Button variant="primary" loading>加载中</Button>
        <Button variant="primary" disabled>禁用</Button>
      </main>
    </div>
  );
}
验证效果:点击右上角主题切换按钮,页面背景、文字颜色、按钮边框色随暗色 Token 变量自动切换,无需修改任何组件代码。验证了「Token → CSS 变量 → 组件 → 页面」的全链路主题化能力。

5.4 搭建 Storybook 组件文档

目标:为上面的 Button 组件搭建 Storybook 文档站,实现组件的可视化开发、交互测试和自动文档生成。

Step 1 — 安装 Storybook:

npx storybook@latest init --type react
npm install @storybook/addon-essentials --save-dev

Step 2 — 配置 Token 注入 .storybook/preview.ts:

import type { Preview } from '@storybook/react';
import '../dist/css/tokens.css';  // 全局注入 Token CSS 变量

const preview: Preview = {
  parameters: {
    backgrounds: {
      default: 'light',
      values: [
        { name: 'light', value: '#ffffff' },
        { name: 'dark',  value: '#1f1f1f' }
      ]
    },
    controls: { matchers: { color: /background|color$/i } }
  }
};

export default preview;

Step 3 — 编写 Button Story src/stories/Button.stories.tsx:

import type { Meta, StoryObj } from '@storybook/react';
import { Button } from '../components/Button';

const meta: Meta<typeof Button> = {
  title: 'Components/Button',
  component: Button,
  argTypes: {
    variant: { control:'select', options:['primary','secondary','danger'] },
    size:    { control:'select', options:['sm','md','lg'] },
    loading: { control:'boolean' },
    disabled:{ control:'boolean' },
    onClick: { action:'clicked' }
  }
};
export default meta;
type Story = StoryObj<typeof Button>;

export const Primary: Story = { args: { variant:'primary',    children:'主按钮' } };
export const Secondary: Story = { args: { variant:'secondary', children:'次按钮' } };
export const Danger: Story = { args: { variant:'danger',     children:'危险按钮' } };
export const Loading: Story = { args: { variant:'primary', loading:true, children:'加载中' } };
export const Disabled: Story = { args: { variant:'primary', disabled:true, children:'禁用' } };
export const Sizes: Story = {
  render: () => (
    <div style={{ display:'flex', gap:8, alignItems:'center' }}>
      <Button size="sm">小号</Button>
      <Button size="md">中号</Button>
      <Button size="lg">大号</Button>
    </div>
  )
};

Step 4 — 启动 Storybook:

npm run storybook
# 访问 http://localhost:6006 即可查看 Button 组件文档
Storybook 页面功能
Controls 面板动态切换 variant / size / disabled 等 Props,实时预览组件变化
Actions 面板捕获 onClick 事件,验证交互回调
Backgrounds 面板切换亮/暗背景,验证组件在两种主题下的视觉效果
Docs 页面自动生成 Props 表格、代码示例、组件描述
总结:通过以上三个步骤,我们完成了 DLS 的最小闭环——Token 定义与编译 → 主题化组件开发 → Storybook 文档与测试。这套流程可直接复用到真实项目中,作为企业级设计语言系统的启动模板。

6. 高颜值动效设计方法论

前面几章讲「设计语言系统如何搭建」,本章回答另一个问题:为什么有的页面一眼就「炫酷高级」,有的堆满特效却廉价?以 MotionSites / Awwwards 系高颜值 3D 动效落地页为研究对象,提炼出一套可复制的设计方法论——不是堆特效,而是用一套系统化手法把「注意力 + 技术信号」做出来。

6.1 设计与技术栈的两层关系

先说清一个常见误区:「设计跟技术栈没关系」这句话要拆成两层看——设计的内容无关,设计的实现高度相关。

层面是否与技术栈有关说明
设计内容
(规范 / 语言)
无关色彩、间距、字体、动效 Token、栅格是抽象标准,同一套可落地到 React / Vue / SwiftUI / Compose / Figma——这正是 DLS + Style Dictionary 的价值
设计实现
(边界 / 成本)
高度相关技术栈与浏览器能力划定了「设计可行域」:backdrop-filter、3D transform、GPU 合成、WebGL 粒子能否实现、成本多高

关于「UI 库不是都带了样式吗」:UI 库带的样式是预制默认值,是「设计的一种实现快照」,不是设计本身,更不是设计上限——

层面决定什么谁说了算
UI 库默认样式下限(及格线)库作者
Design Tokens 覆盖换主题 / 换观感你
设计规范上限(审美品位)你

同一个 shadcn/ui,换一套 Tokens 既可做成 Stripe 风、也可做成暗黑赛博风——库的样式只是起点。

真正的耦合点 — 生态锁定:技术栈会「锁定」你能抄什么。6.6 的资源库里,Aceternity / Magic UI / reactbits / 21st.dev 几乎全是 React + Tailwind 生态,shadcnblocks 绑定 shadcn/ui,Vue 生态的高颜值库明显更少。所以「复制成功设计」这件事本身隐含技术栈选择:选 React + Tailwind ≈ 打开最大的高颜值资源池。

6.2 设计语言本质 — 颜值为什么值钱

高颜值设计本质上是 注意力经济 + 技术信号 的复合产物:

机制本质对用户的作用
注意力经济信息过载时代,视觉是第一印象过滤层先抓住眼球,用户才愿意继续看
技术信任信号3D / 动效 / 粒子 = 「我们技术很强」的潜台词对产品能力产生先入为主的信任
Aesthetic-Usability Effect好看的界面被认为「更好用」降低决策摩擦,容忍小瑕疵
社交货币高颜值页面用户更愿意截图 / 分享自传播,降低获客成本
差异化壁垒AI 生成内容同质化,视觉是最后非价格竞争维度与同质化竞品拉开差距
一句话:高颜值不是「美」,而是「让别人觉得你很专业、很值钱」的那个印象。设计方法论的目的是把这种「审美溢价」系统化、可复制地生产出来。

6.3 五大方法论支柱

支柱一:Aesthetic-Usability 驱动(视觉优先)

支柱二:Motion Design as a System(动效是一个系统,不是堆特效)

支柱三:3D 氛围策略(3D 是氛围层,不是内容层)

支柱四:色彩与光影体系

手法做法效果
Dark mode first深色背景打底3D 发光 / 粒子更突出
Gradient 替代纯色弥散光 / 渐变背景比纯色更有质感
Accent glow关键元素加发光 / 辉光焦点引导
克制用色1 主色 + 1 强调色 + 中性灰阶高级感来自克制

支柱五:滚动叙事(Scroll-triggered storytelling)

以滚动为时间轴,把整页组织成一个「逐段展开的故事」。每个 Section 由一个滚动锚点驱动其内部动效,形成「读到哪、动到哪」的沉浸体验。

滚动叙事落地页结构
图 6-1:滚动叙事落地页结构 — 每个 Section 由一个滚动锚点驱动动效

6.4 工具链方法

层工具职责
动效编排GSAP + ScrollTrigger时间轴、滚动触发、错峰
3D 渲染Three.js / React Three Fiber背景 3D、粒子、视差
视觉效果CSS filter / backdrop-filter / canvas辉光、玻璃拟态、粒子
性能保障只动 transform / opacity + will-change60fps 保底
黄金组合:GSAP 管「怎么动」,Three.js 管「背景有多炫」,CSS 管「质感」,性能铁律兜底——四者各司其职,缺一不可。

6.5 反向工程案例 — 把设计语言拆成 Prompt

MotionSites 这类产品本质是 把「审美溢价」做成可复制的商品:将高颜值页面的设计语言拆成四层,再写成 AI 能理解的 Prompt,一键生成。

层拆什么Prompt 描述示例
布局结构Section 顺序与内容「Hero → 特性 → 3D 展示 → 定价 → CTA」
动效参数滚动到哪触发什么、缓动 / 错峰「滚动进入时特性卡片 stagger 上浮,0.6s ease-out」
色彩光影渐变值、透明度、辉光「深空黑底 + 靛紫渐变辉光 + 关键元素 glow」
3D 资产粒子数量 / 旋转 / 颜色「背景漂浮几何体,随鼠标视差移动,透明 0.4」
# 一份可复制的落地页 Prompt 模板(结构化)
主题:SaaS AI 产品 Landing Page
布局:Hero(超大标题 + 3D 背景)→ 特性(stagger 进场)→ 定价 → CTA
动效:滚动叙事;特性卡片 0.6s ease-out 错峰上浮;CTA 磁吸辉光
色彩:深空黑底(#0a0a14) + 靛紫渐变(#6366f1→#a855f7) + 白色文字
3D  :背景粒子 + 浮动几何体,鼠标视差,透明 0.4,缓慢自转
性能:全部 transform/opacity 动画,prefers-reduced-motion 降级
与 DLS 的关系:本章手法可直接落到第 5 章的 DLS 闭环里——把「动效参数、色彩光影、滚动锚点」抽象成 Motion Token / 色彩 Token,用 Style Dictionary 编译,组件库消费,Storybook 文档化,即可在任意项目规模化复用这套「高颜值设计语言」。

6.6 资源库速查 — 直接复制成功设计

日常做高颜值页面,优先复制而非从零设计:从灵感库挑参考 → 抄现成组件 / Prompt → 让 AI 拼装,几乎不用手写样式。以下是经核实的主流资源入口。

① AI 提示词类(同 MotionSites 赛道,复制 Prompt 即可)

站点收费特点
motionsites.ai免费/订阅落地页 prompt,复制后贴进 Lovable / Bolt / Cursor / Claude 即可出站
21st.dev免费+会员12000+ 组件/模板/主题,每个都做成 prompt,贴进 Cursor/Claude Code/v0/Lovable 自动落进仓库;免费每天 2 次

② Copy-Paste 组件 / 区块库(直接抄代码,最实用)

站点规模收费特点
ui.aceternity.com200+ 组件/blocks免费+ProReact + Tailwind + Motion,高颜值动效(3D card、bento、globe、sparkles)
magicui.design150+ 组件开源免费shadcn 配套动效组件,GitHub 开源
shadcnblocks.com1837 blocks免费+Proshadcn/ui 生态最大块库,Hero/Feature/Pricing 全场景,CLI 一键装
reactbits.dev大量动效组件免费动画组件集,直接复制
originui.com508 components开源免费Base UI 之上的现代组件库
uiverse.io数千个免费纯 CSS/HTML 元素(按钮、卡片、loading),免登录复制

③ 灵感 + 可直接拆的落地页

站点用途
landingfolio.com精品落地页灵感库(按行业/颜色筛选)+ 791 个可复制组件
awwwards.com顶级动效站点风向标
lapa.ninja落地页设计精选
godly.website高颜值网页灵感
framer.com/templates官方模板库,可在 Framer 里直接 clone

④ 直接扒站工具(真正的"复制成功设计")

工具用途
getdesign.ai一键把任意网页复制成组件,进 Lovable / Claude / Cursor
Framer可 clone 任意公开 Framer 站点
Chrome 扒站插件抓取任意站点 HTML / CSS / JS(如 SingleFile 等)
最快工作流:landingfolio 找灵感 → shadcnblocks / Aceternity / 21st 抄组件或 Prompt → 交给 AI 拼装适配。一套高颜值页面从灵感到上线通常只需数小时,无需从零写样式。