界面色彩理论
UI 中的色彩很大程度上是一个亮度问题,只是披着色相的外衣。层级、对比度、可读性和深色模式都由亮度决定;色相承载身份和意义;色度(饱和度)承载强调效果。请按此顺序工作。
工具包 — 用它代替猜测
scripts/palette.py(Python 3,无依赖)在 OKLCH 色彩空间中计算一切,并映射到 sRGB 色域。永远不要凭肉眼估算对比度或手工发明一个渐变,当你可以计算它时。
S=<skill-dir>/scripts/palette.py # <skill-dir> = 此技能加载时显示的基础目录
python3 $S system "#6d28d9" # 完整系统:渐变 + 浅/深色角色,所有组合已验证
python3 $S system "#6d28d9" --format tailwind # Tailwind v4 @theme + 语义变量(也支持:css, json = DTCG)
python3 $S ramp "#0f766e" --format css # 单个 50–950 渐变(输入值会吸附到最近的色阶)
python3 $S neutral "#0f766e" --tint 0.01 # 朝向品牌色相着色的灰色渐变
python3 $S contrast "#fff" "#7c3aed" # WCAG 比率 + 等级 + APCA Lc
python3 $S cvd "#16a34a" "#dc2626" "#2563eb" # 色盲模拟 + 易混淆色对
python3 $S harmony "#6d28d9" --scheme split # OKLCH 中的色相关系
python3 $S convert "hsl(...)/#hex/oklch(...)" # 表示法转换 + 色彩鲜艳度
当一对颜色对比度失败时(例如,将 text-muted 调暗直到达到 4.5:1),system 命令会自动沿着渐变步进调整,并打印每次调整 —— 将这些信息传达给用户,它们是设计决策。
工作流程:从“我需要颜色”到交付令牌
- 找到锚点。 有现有品牌色?使用它。没有?根据产品个性推导(见下文选择色相),并给出 2-3 个种子色及每行一个理由,而不是一个随意的选择。
- 使用
palette.py system <seed>生成系统。 一个强调色渐变、一个中性色渐变,以及产品实际渲染的状态色渐变。 - 映射到语义角色, 永远不要在组件中使用原始色值(使用
--color-accent、--color-text-muted,而不是--violet-600)。设计系统构建技能涵盖了令牌架构的细节。 - 验证: 检查渲染后配对(文本在其实际背景上,包括 alpha/叠加)的对比度,两种主题都需要,对任何颜色编码含义(图表、状态、标签)进行 CVD 检查。
- 克制的应用(下文),然后查看其渲染效果。
多少颜色:分布
- 中性色完成约 90% 的工作。 背景、表面、文本、边框。一个建立在优良中性色并带有一个强调色的 UI,几乎总是比多色相 UI 看起来更专业。
- 60-30-10 是一个有用的经验法则:约 60% 主导中性色,约 30% 辅助表面/中性色变体,约 10% 强调色。如果强调色占据的像素超过约 10–15%,它就不再意味着“在此操作”。
- 每个视图一个填充的主要操作。 按钮背景上的颜色从远处读起来像是主要操作;有色文本读起来像链接。
- 一种颜色,一种含义。 如果紫色意味着“品牌/交互”,不要也用它作为分类标签。状态色相必须明显区别于强调色(工具保持 ≥25° 的 OKLCH 色相差异)。
- 颜色永远不是唯一信号。 约 8% 的男性和约 0.5% 的女性有色觉缺陷;将颜色与图标、标签、图案或位置配对。
选择色相(在没有品牌色时)
联想与文化和执行效果相比是弱相关的 —— 任何色相下搭建良好的调色板都优于一个使用不佳的“心理学正确”色相。将它们作为打破平局的参考:
| 色相家族 | 常见 UI 解读 | 典型产品 | 注意事项 |
|---|---|---|---|
| 蓝色 / 靛蓝 | 信任、冷静、胜任 | 金融科技、SaaS、医疗、企业 | 最通用的选择;提高色度或转向靛蓝/蓝绿以脱颖而出 |
| 紫色 | 创意、高端、“AI” | 创意工具、AI 产品 | 高饱和度紫色现在是“AI 垃圾信息”的标志 |
| 绿色 / 蓝绿色 | 增长、金钱、健康、成功 | 金融、可持续、健康 | 与“成功”状态冲突 —— 调整状态色相 |
| 红色 / 玫瑰色 | 能量、紧迫、激情 | 食品、媒体、娱乐 | 与“危险”冲突;用于品牌时刻,保持破坏性操作区分开来 |
| 橙色 / 琥珀色 | 温暖、友好、行动 | 消费、食品、市场 | 深橙色变棕;检查浅色模式的填充色 |
| 黄色 / 黄绿色 | 乐观、吸引注意 | 消费、有趣 | 无法承载白色文字;在黄色填充上使用深色文字,或使用品牌色作为强调色-柔和,并为填充选择更深的色阶(--hue-shift -15 保持色调金黄而非橄榄绿) |
| 近中性色(黑/石色/沙色) | 奢华、编辑、工具 | 开发工具、时尚、作品集 | 需要排版和空间技巧来避免感觉空旷 |
值得注意的区域差异:红色在中国是幸运/庆祝色,但在西方金融中意味着亏损(而在中国/日本股票代码中意味着上涨);白色在部分东亚地区与哀悼相关。对于金融 UI,使涨跌颜色可配置。
感知色彩 — 为什么选择 OKLCH
HSL 亮度具有欺骗性:hsl(60 100% 50%)(黄色)和 hsl(240 100% 50%)(蓝色)具有相同的“L=50%”,但感知亮度相差巨大。这就是为什么 HSL 渐变的对比度不均匀,且深/浅色阶在不同色相间无法对齐的原因。
OKLCH = L(感知亮度 0–1)· C(色度,约 0–0.37)· H(色相角度)。相等的 L ≈ 在不同色相之间具有相同的感知亮度,因此:
- 不同渐变上相同的色阶(所有
-600色阶)与白色具有相似的对比度, - 你可以在不改变亮度的情况下旋转色相(和谐色、需要“匹配”的背景/状态色),
- 可以通过推理 L 来推导深色模式。
注意事项:sRGB 色域不规则 —— 每个色相在每条 L 上都有不同的最大色度(黄色在 L≈0.95 附近达到峰值,蓝色在 L≈0.45 附近)。该工具通过降低色度(保留 L 和 H)来进行色域映射。宽色域(Display-P3)色彩是一种增强:首先声明 sRGB 值,然后在 @media (color-gamut: p3) 中声明 P3/oklch() 的鲜艳值。
CSS 在所有现代浏览器中都支持 oklch();在新 Web 项目中使用它。在原生平台上,转换为平台表示法(hex/sRGB、Color(red:green:blue:)、Color(0xFF…))—— 该工具的 --notation hex 选项有助于此操作。
渐变、中性色和着色
- 渐变全程保持单一色相, 在亮端步进更精细(那里是背景所在,人眼最敏感),并在渐变中部色度达到峰值。11 色阶(50–950,Tailwind 约定)或 12 色阶(Radix 约定,每个色阶有命名的职责) —— 参见
references/ramps-and-roles.md了解角色映射。 - 着色中性色: 将少量品牌色相混入灰色(色度 ≈ 0.005–0.02)。这使整个 UI 感觉连贯;纯色 #808080 的灰色在饱和强调色旁边会显得死气沉沉。暖色品牌 → 暖灰色;冷色 → 冷灰色。
- 在品牌 UI 中,长文本永远不要使用纯黑配纯白; 使用近黑色(neutral-950)配近白色可以减少眩光。在深色模式下,纯黑背景会在滚动时导致 OLED 屏幕拖影;使用 L ≈ 0.13–0.18。
深色模式不是反转
- 层级关系朝向更亮方向发展,而非更深阴影:表面色 > 背景色约 0.03–0.06 L。
- 略微降低强调色的饱和度并提高其亮度;饱和的中色调在深色背景上会产生震动感。
- 正文文本使用略带米白的白色(neutral-50/100),弱化文本约在 neutral-400。
- 填充色通常将其标签翻转为深色文字(工具通过对比度决定)。
- 重新测量每一对颜色;对比度不会在反转后幸存。参见
references/dark-mode.md。
对比度 — 标准
| 配对 | WCAG 2.2 AA | AAA | APCA 指南(建议性) |
|---|---|---|---|
| 正文文本 (<24px / <18.66px 粗体) | 4.5:1 | 7:1 | Lc 75+(90 为佳) |
| 大文本 (≥24px 或 ≥18.66px 粗体) | 3:1 | 4.5:1 | Lc 60+ |
| UI 组件及理解它们所需的图形对象(输入边框、图标、焦点环、图表标记) | 3:1 (SC 1.4.11) | — | Lc 45+ |
| 禁用控件、装饰元素、Logo | 豁免 | — | — |
WCAG 2.x 是法律/合规基线(ADA、EN 301 549 / 欧洲无障碍法案)。APCA(WCAG 3 候选标准)更好地模拟了感知,特别是对于深色模式和浅色文字,但 WCAG 3 尚未定稿 —— 符合 WCAG 2.2 AA 并将 APCA 作为第二意见。详情、焦点环规则和注意事项见 references/contrast-and-cvd.md。
渐变、叠加和 alpha
- 在
in oklab中插值渐变(平滑,无浑浊中间色);对于多色相扫描(中间会变灰的渐变),使用in oklch。对于背景后的文本,保持停靠点在亮度上接近。 - 图片上的文字:使用渐变叠加层或实色背景;测量最差情况区域。
- Alpha 颜色(
/50、rgba)会根据下方内容改变对比度。文本优先使用实色令牌;保留 alpha 用于叠加层、悬停和阴影。
数据可视化
分类调色板需要大致相等亮度且最大色相分离;序列调色板单调地变化亮度;发散调色板共享一个中性中点。如果可用,可以使用 dataviz 技能 —— 它有经过验证的调色板方法。始终对图表系列颜色运行 palette.py cvd 命令。
评审他人的颜色 — 快速检查清单
- 每个文本/背景对在两种主题下均已测量(非估计)
- 输入边框、焦点环、传达含义的图标 ≥ 3:1
- 组件中无原始 hex/rgb 值;仅使用语义令牌
- 一个强调色,仅用于交互/主要含义
- 状态色与强调色区分开,且在 CVD 模拟下彼此之间也区分开
- 中性色一致着色(不是冷灰色和暖灰色的混合)
- 深色模式已设计(更亮的表面用于层级,调整强调色),而非反转
- 含义绝不单独由颜色传达
如需进行带有严重程度排序发现项的完整色彩系统审计,better-colors 技能非常出色;对于挑选/推导/生成,请留在此处。
参考资料
references/ramps-and-roles.md— 逐步角色映射(Tailwind 50–950 和 Radix 1–12)、状态色(悬停/激活/禁用/选中)references/dark-mode.md— 深色主题构建、层级、平台特异性(iOS 语义颜色、Material 色调表面)references/contrast-and-cvd.md— WCAG 2.2 详情、APCA 等级、焦点指示器、CVD 设计规则references/harmony-and-brand.md— 和谐方案、推导次要颜色、品牌到 UI 的转换、色温、同时对比