颜色的语言

RGB 是个谎言。不是说它错了,而是它从来不是为人眼设计的,它是为显示器设计的。

人眼对绿色最敏感,对蓝色最迟钝。但在 RGB 里,红绿蓝三个通道地位完全平等,每个通道各占 0–255。这就导致了一个问题:你以为自己在改变颜色,实际上改变的是显示器的发光强度,而人眼感受到的变化是非线性的。

感知均匀色彩空间

设计领域这几年流行谈 oklch,它的核心承诺是“感知均匀”——在这个色彩空间里,数值的变化量等于视觉感受的变化量。

oklch 用三个维度描述颜色:

维度 含义 范围
L(亮度) 感知亮度,0 是黑,1 是白 0 – 1
C(彩度) 颜色的鲜艳程度 0 – ~0.4
H(色相) 颜色在色轮上的位置 0° – 360°

这和 hsl 很像,但有一个关键区别:hsl 里亮度相同的颜色,感知上亮度并不相同——比如纯黄(hsl(60, 100%, 50%))看起来远比纯蓝(hsl(240, 100%, 50%))亮。oklch 修正了这个问题。

实际差异在哪里

最直观的差异体现在颜色渐变上。

srgb 色彩空间混合蓝色和橙色,中间会经过一片灰褐色的死区——因为两种颜色在 RGB 空间里的中间点,感知上偏暗且饱和度低。

oklch 混合同样的两种颜色,中间过渡始终保持饱和,从蓝到橙会经过一片鲜艳的紫色,视觉上更连续。

/* srgb 混合,可能出现灰色死区 */
background: linear-gradient(in srgb, #3b82f6, #f97316);

/* oklch 混合,过渡更饱和 */
background: linear-gradient(in oklch, #3b82f6, #f97316);

CSS Color Level 4 已经支持在 color-mix() 和渐变里指定色彩空间,主流浏览器都已经跟上。

但是

感知均匀并不意味着“总是更好看”。有时候你就是要那个灰色死区——比如一个需要低调过渡的界面背景。工具是工具,没有绝对的优劣。

更重要的问题是:颜色系统的选择,往往取决于你在什么层面上工作。

  • 系统设计:用 oklch 建立色板,可以保证不同色相的颜色在相同亮度下感知一致
  • UI 组件:用 hsl 或 CSS 变量足够,不需要过度精确
  • 数据可视化:感知均匀性至关重要,oklchlab 是更好的选择
  • 品牌色:通常由设计工具导出,用什么色彩空间主要看工具链支持情况

颜色作为信息

颜色的本质是信息载体。红色意味着警告,绿色意味着通过,蓝色意味着链接——这些不是颜色本身的属性,而是文化约定。

颜色本身没有意义。意义是人赋予的,是历史积累的,是上下文决定的。

这意味着颜色的“正确用法”永远是相对的。什么是好的颜色搭配?让目标用户在目标场景下完成目标任务的搭配,就是好的搭配。


回到那个谎言:RGB 是为显示器设计的,但我们在 RGB 里工作了几十年,已经形成了自己的一套直觉。换用 oklch 之后,这套直觉要重建,需要时间。

这不是理由,只是实情。