颜色系统 是做什么的?
概述
一个精心策划的、即用型颜色库(浅色 + 深色),覆盖四个领域——网页应用UI、营销/落地页、数据可视化和终端/TUI——以及构建新调色板和验证其可访问性的方法论。
核心原则: 根据语义角色(背景、文本、主色、错误色……)选择颜色,而非原始色相。此库中的每个调色板都将十六进制色值映射到角色,从而确保主题可互换、一致且可访问。先选择角色,再读取其十六进制色值——在角色应出现的位置硬编码十六进制色值正是后期破坏主题的原因。
导航
以下索引和角色契约本身就能回答“该用哪个调色板”。当任务需要其有效载荷时,仅加载一个参考文件——不要全部加载。
| 加载 | 时机 |
|---|---|
| references/carbon.md | 构建必须使用Carbon的页面或成品——仅读取此文件;它包含Carbon在两种模式下的角色、仪表盘套件和三元组 |
| references/palettes.md | 需要任何其他调色板的十六进制色值——四个领域,浅色 + 深色;填充/柔和/强调三元组;Dusk、Driftwood和Meadow背后的12阶色阶 |
| references/contrast.md | 验证WCAG/APCA阈值、色盲安全性,或调试一对失败的组合 |
| references/build-your-own.md | 库中调色板都不合适,且正在生成新色阶(OKLCH配方) |
| references/theory.md | 选择配色方案,或证明色彩空间/色阶决策的合理性 |
调色板库(快速索引)
当某个调色板是首选时,会标记⭐;营销和TUI没有默认值,因为选择取决于品牌或用户自己的终端主题。
网页应用UI — 浅色 + 深色,13个语义角色 + 每色一个三元组
- Carbon ⭐ (默认) — 深石板蓝,深色优先。分析仪表盘、性能报告和开发工具。附带完整的仪表盘套件(A–F等级药丸、有序阶段序列、内联代码色调、成功高亮)。当浅色模式必须经过精细调校以达到对等时,请使用Graphite。
- Graphite — 冷石板 + 蓝色。密集的B2B仪表盘、开发工具;浅色+深色对等的默认选择。
- Evergreen — 翠绿品牌色搭配真实中性锌色。清新、自信、非蓝色的身份标识。
- Terracotta — 暖赤陶/浓缩咖啡中性色 + 铁锈色。编辑、内容平台、写作工具。
- Bloom — 淡紫丁香/紫罗兰色,深色模式深邃。友好的开发工具,俏皮但整洁的应用。
- Teal Slate — 深蓝绿色搭配冷石板色,单一暖强调色。技术报告、SRE/速率限制仪表盘;与数字用单色字体搭配使用。
基于12阶OKLCH色阶生成,这些色阶随其角色一起提供,以便扩展或重新派生:
- Dusk — 靛蓝主色,蓝绿色强调色,近中性冷灰色。专注工具、编辑器、长时间会话应用。
- Driftwood — 深海洋蓝主色搭配暖沙中性色,陶土强调色。在深色模式下其中性色会转为冷色调。
- Meadow — 柔和鼠尾草绿主色,古金色强调色,暖骨白色中性色。是这套中最柔和的;给人宁静而非自信的感觉。
营销 / 落地页 — 浅色 + 深色,主打渐变
- Sunbloom — 精致的珊瑚/琥珀暖色调。平易近人的消费/创作者品牌。
- Tidewater — 蓝绿色/鼠尾草绿。金融科技、健康、B2B信任感。
- Obsidian & Gold — 近黑色 + 金属金色。高端、奢侈、代理机构。
- Paper & Ink — 暖纸色 + 墨黑色 + 一个陶土色强调色。博客、长篇内容、作品集。
数据可视化 — 色盲友好,暖/冷大地色系
- 分类: Lunar Valley ⭐ (默认) · Hearthstead · Vintage Warm · Glass Wall · Okabe-Ito (当CVD安全是硬性要求时使用)
- 顺序: Viridis ⭐ (默认) · Magma · Inferno · Plasma · ColorBrewer Blues · YlOrRd (均为感知均匀)
- 发散: Console & Window ⭐ (默认) · Alien Sun · Orchard Dusk · Coffee & Coolant — 均为暖↔冷,无红↔绿
终端 / TUI — 16-ANSI + 背景色/前景色/光标色/选中色
- Solarized Dark · Nord · Catppuccin Mocha · Catppuccin Latte (唯一浅色方案) · Dracula · Tokyo Night
→ 完整十六进制表: Carbon在 references/carbon.md 中,其他所有调色板在 references/palettes.md 中
语义角色(契约)
UI调色板填充这些角色。将意图映射到角色,再将角色映射到十六进制色值。
| 角色 | 含义 |
|---|---|
background | 应用/页面基础画布 |
surface | 卡片、面板、工作表 |
surface-elevated | 抬升表面(弹出框、模态框);深色模式下越亮 = 越抬升 |
border | 分隔线、输入边框、聚焦环 |
text-primary | 高强调前景 |
text-secondary | 柔和标签、提示、说明性文字 |
primary / primary-hover | 品牌动作色 + 其悬停状态 |
accent | 次要强调色,与主色区分 |
success / warning / error / info | 语义状态色(按西方惯例为绿色/琥珀色/红色/蓝色) |
然后,每个彩色角色需要一个三元组,因为一个十六进制色值无法完成三项工作。 一个被设计为承载的值并不自动适合用作文本,而实心填充作为表格密度下的徽章背景则过于刺眼。
| 令牌 | 工作 | Bootstrap 5.3 称其为 | Material 3 称其为 |
|---|---|---|---|
{c}-fill + {c}-on-fill | 按钮、激活的微件 | --bs-{c} + color-contrast() | primary + on-primary |
{c}-subtle + {c}-emphasis | 徽章/提示框背景 + 其标签 | --bs-{c}-bg-subtle + -text-emphasis | primary-container + on-primary-container |
{c}-subtle-border | 该背景周围的边框 | --bs-{c}-border-subtle | — |
link | 在 surface 上作为文本的品牌色调 | (v6中拆开) | — |
所有九个UI调色板的现成三元组都在 palettes.md 中,除了Carbon的,后者在 carbon.md 中。深色模式的填充色是浅色调,因此其标签是调色板中最深的中性色,而非白色。
数据可视化调色板则提供有序的颜色列表(分类 = 不同系列;顺序 = 低→高渐变;发散 = 暖↔冷加中性中点)。TUI方案提供16个ANSI插槽加4个特殊角色。
核心概念
- 在OKLCH中设计,而非HSL。 OKLCH是感知均匀的;HSL的“亮度”会欺骗人(同等L值的蓝色看起来比同等L值的黄色暗得多),因此即使是HSL的等距步长也会产生不均匀的色阶。
- 和谐: 选择一个方案(单色/类似/互补/三元…)并让一个颜色在饱和度和面积上占主导地位;将其他颜色去饱和。
- 色阶: 10–12步,亮度均匀步进,色度在中段达到峰值并在两端逐渐减小,以免浅色调显得褪色而深色调显得浑浊。
- 对比度: WCAG AA — 正文 ≥ 4.5:1,大号文本和UI/边框 ≥ 3:1。
- 浅色 vs 深色不是反转,且WCAG 2比率夸大了近黑色的对比度。 这两种失败模式及其修复方法均在下面的“常见陷阱”中;阈值和APCA步骤在 references/contrast.md 中。
- 色盲安全: 除了色相之外,还使用文本、图标或位置编码意义,因为约8%的男性无法仅凭色相进行区分。对于发散数据,使用暖↔冷(蓝/橙、蓝绿/玫瑰)而非红↔绿。
示例
示例:为SaaS仪表盘选择颜色
✅ 正确做法
用户:“我需要一个管理仪表盘的颜色,浅色和深色。”
→ 推荐Carbon(深石板蓝,深色优先,专为密集型数据UI设计)——默认值;
如果手工调校的浅色模式对等性比仪表盘套件更重要,则提供Graphite。
→ 从 carbon.md 复制其角色→十六进制表(两种模式)。
→ 按角色应用:background→surface→border→text,主色用于主要行动号召按钮,
success/warning/error用于状态徽章。确认 text-primary 在 background 上 ≥ 4.5:1。
❌ 反模式
→ 从Coolors调色板中选取四种色调并随意分配:#2b2d42 导航栏、#8d99ae 文本、
#edf2f4 背景、#ef233c 按钮。深色模式 = 反转十六进制色值。
为什么有效:角色映射的调色板可直接放入CSS变量中,并且通过构造即可访问。临时版本没有中性渐变、没有抬升层级、没有状态颜色,并且反转浅色调色板会产生纯黑色表面和褪色的品牌色调(参见常见陷阱:浅色 vs 深色不是反转)。
示例:状态徽章颜色
✅ 正确做法
.badge-error { background: var(--error); color: #fff; } /* 角色,而非硬编码的红色 */
❌ 反模式
.badge-error { background: #ff0000; color: #000; } /* 原始色相;#f00 在 #000 上 ≈ 5.2:1 但刺眼,
且无法主题化或切换到深色模式 */
为什么失败:硬编码色调会破坏主题化和深色模式,并且纯红色/纯黑色会导致光晕效应。
示例:选择图表调色板
✅ 正确做法
分类系列(≤8)→ Lunar Valley(默认),或当需要CVD安全时使用Okabe-Ito。
连续低→高 → Viridis(感知均匀,色盲安全)。
带有中点的带符号数据 → Console & Window(暖↔冷,中性中心)。
超过约8个分类颜色后,系列将无法区分——改为聚合为“其他”。
❌ 反模式
十二个分类系列使用UI调色板中的success/warning/error/info角色加上品牌色调着色;
盈利/亏损编码为绿色↔红色且无标签。
为什么有效:将数据的结构与正确的调色板家族匹配,并尊重可区分性限制。反模式复用了与系列标识冲突的UI状态角色,超过了约8色调的限制,并且为色盲观众编码了红色↔绿色而没有文本或图标备份。
常见陷阱
- 症状: 品牌色作为正文不可读。原因: 饱和的中色调(琥珀色、珊瑚色、蓝绿色)通常在其自身背景上无法达到4.5:1——填充色和文本色是同一渐变的步长。修复: 保持
fill和link作为单独的值;将文本步进到更深的色调直到通过。在此库中,只有Evergreen浅色调有差异(#059669在按钮标签上达到4.70:1,但在白色背景上作为链接时降至3.77:1,因此其link为#00875b),这正是拆分的意义所在。 - 症状: 状态徽章看起来正确,但在表格密度下显得刺眼。原因: 白色文本背后的实心
--error填充色对于按钮是正确的,但对于行级徽章来说过于响亮。修复: 使用{c}-subtle背景及其配对的{c}-emphasis标签。在该色调上复用状态色作为其自己的标签通常无法达到4.5:1——从 palettes.md 中获取配对值(Carbon的从 carbon.md 获取),而不是自行假设。 - 症状: 从12阶色阶生成的调色板仍然对比度失败。原因: 色阶映射并非对比度保证。Radix仅保证步进11和12对步进2的对比度,其他不做保证;步进9很少能承载4.5:1的按钮标签,步进8很少能作为控件边缘达到3:1。修复: 针对其实际背景解决这两个问题。在浅色模式下,承诺使用白色标签并将填充色步进到更深——向得分较高的标签方向解决会产生一个通过但看起来弱的苍白颜色。
- 症状: 在浅色模式下看起来正确的调色板在深色模式下感觉浑浊。原因: 中性色调被选择一次并继承。在低亮度下读作纸张的暖色调在低亮度下读作棕色。修复: 每种模式重新决定中性色调和色度;在非常低的色度下转为冷色调是通常的答案。Driftwood在 palettes.md 中做到了这一点(浅色色相64,深色色相224);Meadow的鼠尾草绿则不需要。
- 症状: 从Color Hunt、Coolors或趋势文章复制的调色板无法构建界面。原因: 画廊调色板是四种装饰性色调,没有中性渐变、没有深色墨迹和没有状态——30个最受欢迎的Color Hunt调色板中有16个无法用其任何一对颜色承载4.5:1的正文。修复: 将这些色调作为种子材料,并从中构建色阶(build-your own.md);Dusk、Driftwood和Meadow就是这样制作的。
- 症状: 次要/柔和文本("dimmed"、
text-secondary)在设计工具中看起来不错,但在应用中对比度失败。原因: 组件库提供了默认的柔和文本颜色(例如Mantine的dimmed),用于视觉层次而非对比度——通常落在~3.4:1左右,远低于4.5:1的AA标准。修复: 根据 contrast.md 选择并验证自己的text-secondary十六进制色值,而不是继承库默认值,并且每个主题重新检查——相同的覆盖在一个主题中可能通过,在另一个中可能失败。在着色的/抬升的表面(卡片、条纹行)上也要重新验证,而不仅仅是在平面画布上。 - 症状: 深色模式“通过WCAG”但难以阅读。原因: WCAG 2数学夸大了近黑色的对比度。修复: 使用APCA(Lc)而非4.5:1比率重新检查深色对。
- 症状: 深色主题看起来很平坦,抬升效果不可读。原因: 纯
#000背景 + 相同亮度的表面。修复: 将基础色提高到约#0d1117–#1e1e2e,并使每个抬升层级更亮。 - 症状: 色盲观众无法阅读图表。原因: 红色↔绿色编码或仅色相的意义。修复: 切换到暖↔冷发散调色板并添加标签/图标;对于分类数据使用Okabe-Ito安全集(在 palettes.md 中)。
- 症状: 尽管调色板定义了正确的文本颜色,图表文本仍然低对比度。原因: 图表库(Recharts、Mantine charts)使用其自己的内联
fill将坐标轴/图例/数值文本渲染为SVG,绕过了颜色令牌。修复: 直接针对库的文本元素(例如.recharts-wrapper text { fill: var(--text) })——CSS级联从未到达它。 - 症状: TUI颜色在某些终端上消失。原因: 硬编码的十六进制色值,或将重要文本放在亮黑色(插槽8)中。修复: 将意义绑定到ANSI插槽1–6,以便用户自己的主题渲染它,并将插槽8仅用于淡化强调。
- 症状: 调色板步进看起来不平滑/不均匀。原因: 在HSL/RGB中步进亮度。修复: 在OKLCH中重建色阶——使用 build-your-own.md 中的配方——或者切换到此库的预建OKLCH色阶(Dusk、Driftwood、Meadow)之一。
…
(原文截断用于翻译)