关于 design-system
design-system 是面向设计系统构建者的技能,指导以设计上下文和现有代码为基础组织令牌、组件与主题。内容还涵盖文档、无障碍状态和渲染验证。
主要功能
- 01构建原始、语义和组件令牌层级
- 02组织 CSS 变量文件与主题覆盖
- 03定义组件变体、尺寸和交互状态
- 04建立间距、阴影、圆角与动效体系
- 05编写组件文档并验证主题与对比度
适用场景
- 01为现有项目扩展设计令牌和组件
- 02统一跨组件的主题与状态样式
- 03记录组件用法并检查不同主题下的呈现
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ arnavpuri/ designskills --skill design-system安装后在 Claude Code 中输入/design-system确认已加载。
详细介绍
设计系统
使用令牌、组件和主题架构,构建可扩展且易于维护的设计系统。
前置条件
构建设计系统之前,请先检查现有的设计上下文:
- 阅读
.agents/design-context.md(参见design-context),了解颜色、字体、基础字号、比例系数、圆角、阴影样式和间距系统。基础令牌必须以此为依据,而不是凭空设定。 - 扫描代码库,查找现有令牌(CSS 变量、Tailwind 主题、
tokens.json),并在此基础上扩展。 - 确定所用框架(React、Vue、Svelte、原生),以决定组件模式。
- 不要重新推导由相邻工具负责的内容:颜色阶梯来自
color-palette(--brand-*、--gray-*、--success-*、--warning-*、--error-*、--info-*),字号阶梯来自typography(--text-xs…--text-5xl)。
步骤 1:设计令牌层级
令牌是设计系统的原子值。将其分为三层:
第 1 层:基础令牌(原始值)
根据令牌的本质命名。切勿在组件中直接使用。
使用 oklch 在 :root 中定义所有原始值。包括:
- 颜色:
--brand-50…950、--gray-50…950、语义颜色--success-*、--warning-*、--error-*、--info-*(来自 color-palette) - 间距:
--space-N= N × 4px,以 rem 为单位(0、px、0.5、1、2、3、4、5、6、8、10、12、16、20、24)——参见步骤 6 - 字号:
--text-xs…--text-5xl根据设计上下文中的基础字号 × 比例系数生成(typography 技能)。不要另行硬编码字号阶梯。 - 圆角:none、sm(0.25rem)、md(0.5rem)、lg(0.75rem)、xl(1rem)、2xl(1.5rem)、full(9999px);将 md 设为设计上下文中的圆角值
第 2 层:语义令牌(用途)
根据令牌的作用命名。这些是主题的主要接口。
在 :root 中将基础令牌映射到用途:
- 背景:
--bg-primary(gray-50)、--bg-secondary(white)、--bg-tertiary(gray-100)、--bg-inverse(gray-900) - 文本:primary(gray-900)、secondary(gray-600)、tertiary(gray-400)、inverse、brand
- 边框:default(gray-200)、strong(gray-300)、brand(brand-500)
- 交互:
--interactive-primary/-hover/-active(brand-500/600/700)、secondary/hover(灰度阶梯) - 品牌别名:
--color-primary、--color-secondary、--color-accent(design-context 会自动检测这些名称) - 语义颜色:
--color-success(success-500)、--color-warning(warning-500)、--color-error(error-500) - 间距:gap-xs 到 gap-section 映射到 space 令牌
- 圆角:button(md)、card(lg)、input(md)、badge(full)、modal(xl)
第 3 层:组件令牌(作用域)
根据使用位置命名。复杂系统可选用,但功能强大。
将令牌限定到单个组件。以 .btn 为例:使用语义令牌定义 --btn-padding-x、--btn-padding-y、--btn-radius、--btn-font-size、--btn-bg、--btn-color、--btn-border,然后在同一规则中使用这些令牌。变体只覆盖需要更改的组件令牌。
步骤 2:CSS 自定义属性架构
文件组织
tokens/
_primitives.css /* Layer 1: raw values */
_semantic.css /* Layer 2: purpose mappings */
_themes.css /* Theme overrides (dark mode, etc.) */
components/
_button.css
_card.css
_input.css
index.css /* Imports all */
导入顺序
/* index.css */
@import './tokens/_primitives.css';
@import './tokens/_semantic.css';
@import './tokens/_themes.css';
@import './components/_button.css';
@import './components/_card.css';
@import './components/_input.css';
使用数据属性限定作用域
/* _themes.css */
[data-theme="dark"] {
--bg-primary: var(--gray-950);
--bg-secondary: var(--gray-900);
--bg-tertiary: var(--gray-800);
--text-primary: var(--gray-50);
--text-secondary: var(--gray-300);
--border-default: var(--gray-700);
--interactive-primary: var(--brand-400);
}
/* Follow the OS setting instead of (or as well as) a manual theme */
@media (prefers-contrast: more) {
:root { --text-secondary: var(--text-primary); --border-default: var(--gray-900); }
}
在 Windows 高对比度模式 / forced-colors: active 下,自定义颜色会被系统颜色替换:切勿仅通过背景色传达状态,并在按钮上保留透明的 outline 或 border,确保其仍清晰可见。
导出令牌(W3C DTCG 格式)
对于工具(Style Dictionary、Tokens Studio、Figma variables),还应以 Design Tokens Community Group 格式生成 tokens.json:每个令牌都是包含 $value 和 $type 的对象($type 可在组级别设置一次),别名使用 {group.token},元数据放在 $description 中。稳定规范(2025.10)使用结构化颜色和尺寸值;较旧的工具可能需要 "#0F74C5" / "16px" 字符串——请确认所用工具支持的格式。
{
"color": {
"$type": "color",
"brand": {
"500": { "$value": { "colorSpace": "oklch", "components": [0.55, 0.15, 250], "hex": "#0F74C5" } }
},
"interactive": {
"primary": { "$value": "{color.brand.500}", "$description": "Primary buttons, links" }
}
},
"space": {
"$type": "dimension",
"4": { "$value": { "value": 1, "unit": "rem" } }
},
"duration": {
"$type": "duration",
"normal": { "$value": { "value": 200, "unit": "ms" } }
},
"easing": {
"$type": "cubicBezier",
"out": { "$value": [0, 0, 0.2, 1] }
}
}
步骤 3:组件 API 设计
变体
使用 CSS 类实现变体。尺寸变体(--sm、--lg)会覆盖内边距和字号令牌。样式变体(--secondary、--ghost、--outline、--danger)只会覆盖背景、颜色和边框令牌。
状态
每个交互式组件都需要::hover(调整背景)、:active(更深的背景 + scale(0.98))、:focus-visible(2px 轮廓 + 2px 偏移,与背景的对比度为 3:1)、:disabled / [aria-disabled="true"](降低不透明度,cursor: not-allowed;对于 aria-disabled,还要在 JS 中阻止点击——它会保持可聚焦状态,这正是其设计目的)。
一致的 API 模式
| 属性 | 选项 |
|---|---|
| 尺寸 | sm、md(默认)、lg |
| 变体 | primary(默认)、secondary、ghost、outline、danger |
| 状态 | default、hover、active、focus、disabled |
| 形状 | default、pill(radius-full) |
步骤 4:可组合的组件模式
Card(可组合)
组成部分:.card(边框、圆角、溢出处理)、.card-header / .card-body / .card-footer(使用语义令牌设置内边距,页眉/页脚带有分隔边框)。.card-media 使用 aspect-ratio: 16/9; object-fit: cover。变体:--elevated(使用阴影而非边框)、--interactive(悬停时增加阴影 + translateY)。
Input(完整)
使用组件令牌(--input-height、--input-border、--input-radius、--input-bg)。默认高度为 2.5rem,宽度为 100%。状态::hover(边框加深)、:focus(品牌色边框 + 不透明度为 0.15 的 3px 光环)、--error(错误色边框)。尺寸:--sm(2rem)、--lg(3rem)。
步骤 5:主题架构
切换主题
在 <html> 上设置 data-theme 属性。JS:先检查 localStorage,若没有则回退到 prefers-color-scheme: dark 媒体查询。监听操作系统的更改;如果没有已保存的偏好设置,则更新主题。在 <head> 中运行一个简短的内联 <script>(在 CSS 绘制之前),以避免错误主题闪现;并设置 color-scheme: light dark,使表单控件和滚动条与主题相匹配。
多品牌主题
使用 [data-brand="name"] 选择器重新映射第 2 层令牌(交互颜色、字体)。只需更改语义令牌的值,同一组件就能根据不同品牌呈现不同效果。
步骤 6:间距比例
使用 4px 基准单位:--space-N = N × 4px。除 2px 细线外,所有值均为 4 的倍数。如果 design-context 指定“8px 基准网格”,则保留此比例,但将布局间距限制为偶数步长(2、4、6、8……)。layout-composition 使用相同的比例。
比例
| 令牌 | 值 | rem | 用例 |
|---|---|---|---|
| 0.5 | 2px | 0.125 | 细线间隙 |
| 1 | 4px | 0.25 | 紧凑的内部内边距 |
| 2 | 8px | 0.5 | 图标间距、紧凑内边距 |
| 3 | 12px | 0.75 | 按钮内边距、输入框内边距 |
| 4 | 16px | 1 | 卡片内边距、标准间距 |
| 5 | 20px | 1.25 | 卡片内边距(舒适) |
| 6 | 24px | 1.5 | 区块内部间距 |
| 8 | 32px | 2 | 组件组之间 |
| 10 | 40px | 2.5 | 大型组件间距 |
| 12 | 48px | 3 | 区块内边距 |
| 16 | 64px | 4 | 区块外边距 |
| 20 | 80px | 5 | Hero 内边距 |
| 24 | 96px | 6 | 主要区块分隔 |
使用场景
- 组件内部(图标与文本之间、标签与输入框之间):space-1 到 space-3。
- 同级组件之间(卡片之间、字段之间):space-4 到 space-6。
- 区块之间:space-12 到 space-24。
步骤 7:阴影/层级系统
阴影用于表示层级。请构建分层系统。
定义 6 个级别:--shadow-xs 到 --shadow-2xl,使用多层 oklch(0 0 0 / opacity) 阴影,并逐步增大模糊半径和偏移量。
:root {
--shadow-sm: 0 1px 2px oklch(0 0 0 / 0.06), 0 1px 3px oklch(0 0 0 / 0.08);
--shadow-md: 0 2px 4px oklch(0 0 0 / 0.06), 0 4px 12px oklch(0 0 0 / 0.10);
--shadow-lg: 0 4px 8px oklch(0 0 0 / 0.06), 0 12px 32px oklch(0 0 0 / 0.14);
}
根据设计上下文中的 Shadow Style 调整不透明度:none = 仅使用边框/表面颜色,subtle ≈ 上述数值,medium ≈ 1.5×,dramatic ≈ 2×,并采用更大的偏移量。
| 级别 | 阴影 | 用途 |
|---|---|---|
| 0 | none | 与表面齐平(默认) |
| 1 | xs/sm | 卡片、按钮 |
| 2 | md | 下拉菜单、弹出框 |
| 3 | lg | 模态框、抽屉 |
| 4 | xl/2xl | Toast 通知、浮起的模态框 |
在深色模式中,提高阴影不透明度(0.3+),或改用表面颜色差异来体现层级。
步骤 8:边框圆角系统
刻度:none(0)、sm(4px)、md(8px)、lg(12px)、xl(16px)、2xl(24px)、full(9999px)。
嵌套圆角规则:inner-radius = outer-radius - padding。如果结果为 0 或负数,则使用刻度中小一级的尺寸。
步骤 9:过渡和动画令牌
定义时长令牌(--duration-fast:100ms、--duration-normal:200ms、--duration-slow:300ms、--duration-slower:500ms)和缓动令牌(--ease-out、--ease-in、--ease-in-out、--ease-spring)——名称和值与 motion-design skill 中的相同。创建组合过渡令牌(--transition-colors、--transition-transform、--transition-shadow、--transition-opacity),将时长与缓动组合起来。组件组合使用这些令牌,例如,按钮使用 var(--transition-colors), var(--transition-transform)。
始终支持减少动态效果:
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
scroll-behavior: auto !important;
}
}
步骤 10:组件文档编写模式
编写组件文档
设计系统中的每个组件都应包含:
- 描述:组件是什么,以及何时使用。
- 变体:视觉变体(primary、secondary、ghost 等)。
- 尺寸:可用尺寸(sm、md、lg)。
- 状态:交互状态(hover、active、focus、disabled)。
- 结构:组件的组成部分及其令牌。
- 建议/避免:使用指南。
- 代码示例:可复制粘贴的 HTML/CSS。
使用 Storybook 风格的 HTML 页面:每个组件使用一个 <section>,包含描述,随后添加 .doc-row 容器(flex wrap、gap、tertiary bg),并排展示所有变体、尺寸和状态。
步骤 11:验证并保存
- 渲染文档页面(步骤 10),并在两种主题下截屏:
npx playwright screenshot --full-page "file://$PWD/docs.html" light.png,然后使用--color-scheme=dark(或切换data-theme)再次截屏。使用 Read 查看两张截图。检查每种变体/尺寸/状态是否都能正确渲染、焦点环是否清晰可见、禁用状态是否看起来确实不可用,以及是否有组件使用原始十六进制颜色而非令牌(grep -nE '#[0-9a-fA-F]{3,8}\b' components/)。 - 检查两种主题下每组文字/背景和按钮的对比度(使用 color-palette skill 中的脚本)。
- 提出回写建议:将已变更的基础值(Color System hex、fonts、Base Size、Scale Ratio、Border Radius、Shadow Style、Spacing System)写回
.agents/design-context.md,仅更新这些字段。展示差异并在保存前询问。
快速参考:设计系统检查清单
- 定义基础令牌(颜色、间距、字号、圆角)。
- 映射语义令牌(背景、文字、边框、交互)。
- 使用 data attributes 设置主题(至少包含浅色/深色)。
- 为每个组件设置作用域限定的组件令牌。
- 设计组件 API:统一尺寸(sm/md/lg)和变体。
- 实现所有交互状态(hover、active、focus-visible、disabled)。
- 使用 4px 间距基准单位。
- 构建 5-6 级阴影系统。
- 定义过渡令牌,确保动画一致。
- 为每个组件编写文档,包含变体、尺寸、状态和示例。