关于 HCL

HCL (Hue-Chroma-Luminance) 与 RGB 一样同属色彩空间的一种,因为最早由国际照明协会 CIE 提出,又被称作 CIELch(uv)。HCL 最普遍应用于程序生成的配色表 (color swatch) 或可视化数据图表配色。在 HCL 色彩空间中,当色相改变而 L 通道保持恒定时,对人眼而言,色彩「对比度」不变。

为什么 HCL 比 HSL 更好?

TL;DR

  • HSL 色彩空间中的明度 L 是相对计算机元件而言,而非人眼。L 通道与人眼对明度的感知(Luminance/Relative Luminance,后文以「感知明度」称呼)非线性匹配,HSL 中明度相等的两个颜色,人眼感知到的明度可能相去甚远(参见例子)。但产品的使用者是人类,用色彩进行标识应以人眼感知为准。
  • HCL 中只要两个颜色的 L 值(即感知明度)相等,颜色的对比度相等。
  • HCL 对颜色识别有障碍的视障人士更友好。即使有障碍,这些人能通过颜色的对比度区分颜色的不同,对比度越强,越容易区分。这里的「对比度」特指感知明度的对比。事实上在 Web 领域里,W3C 的 WCAG2.1 标准中提出了相关的可用性 (accessibility) 要求:文字前景色与背景色要达到一定程度的对比度1
  • 在决定配色阶段使用 HCL 色彩空间取色能够直接控制感知明度,更容易使产品配色达到较高的可用性。

细节

首先澄清几个名词:

  • 明度(Lightness):指 HSL 色彩空间中的 L 通道,简称 L。
  • 感知明度(Luminance,在 W3C 中又称为 Relative Luminance):用于量化人眼对光的明度的感知。 HCL 色彩空间中的 L 通道使用的是它,简称 Luma。需要与明度区分开来。
  • 对比度:两种颜色间感知明度的对比,公式参见下文
  • 色距(Chroma):HCL 中的 C 通道,可以理解为相对饱和度。

相比 HEX 或 RGB,许多设计师和前端工程师喜欢使用 HSL(Hue-Saturation-Lightness) 表示颜色,因为它的可读性更高,能够从数值中直观读出颜色的属性。如同样是三文鱼粉,HEX #fa8072 或 RGB 250, 128, 114 最多只能看出这是一个偏红的颜色, 而 hsl(6, 93%, 71%)可以看出这是一个色相为 6(在色环 6° 位置),饱和度为 93%,明度为 71% 的颜色。如果要基于这个颜色取补色,只需要对色相数值 +180° 为(186, 93%, 71%),如果需要取一系列同色系的相近色,只需要对饱和度或明度做细微更改即可,十分方便。

产品配色 2.0:使用 HCL 色彩空间替代 HSL 生成配色 - 二三事 - 图1

HSL 色相环

看上去很完美,但 HSL 有个致命的先天缺陷:它是基于 RGB2 模型创造的色彩空间。RGB 中的每个颜色是三色光通过加色法叠加而成——计算机或电视等屏幕的电子元件通过这种方法展示正确的颜色,当元件内一种色光达到极值,而另外两种色光为零时,就发出了正红、蓝或绿色光。但这并不是人眼感知光的方法。因此,HSL 中两个颜色如果明度相等,只是对发光元件而言的「相等」。对人眼来说,刺眼程度却大相径庭。举例而言:

虽然亮度都标为 50%,人眼感知正绿 hsl(120, 100%, 50%) 的感知明度为 80%,而正蓝 hsl(240, 100%, 50%) 的感知明度只有 44%,差距达到了 36%。

HCL 中的 L 通道与 HSL 的 L 通道不同,是基于人眼对亮度对感知而创造的。下图解释了人眼对两种色彩空间的色环内颜色的明度是如何感知的(下方灰色部分): HSL 的感知明度是非常不连贯的——讲人话的话就是,你在看左侧黄绿色部分时是不是觉得更刺眼,而蓝紫部分看起来温和多了?而右边色环的感知明度则始终保持连贯,视觉上更舒服。

产品配色 2.0:使用 HCL 色彩空间替代 HSL 生成配色 - 二三事 - 图2

HSL 色环与 HCL 色环在不同对比度 / 色度下的感知明度对比3

在实际应用中, HCL 的这一特性可以帮助各色人士更快速、友好地识别不同颜色标识和它传递的信息。

产品配色 2.0:使用 HCL 色彩空间替代 HSL 生成配色 - 二三事 - 图3

2012 年桑迪飓风来袭时 120 小时降雨量图。左侧图片:图表实际颜色;右侧图片:去色相后图表颜色的感知明度。45

左上图为图表使用的原始配色,均使用了高饱和色,颜色间的过渡无法正确传达信息(紫色到青色代表降雨量增加还是减少了?)。经过去色处理后,也能看出整个图表颜色的感知明度并不是渐变的,时高时低。不仅是视障人士,该图表即使对没有色盲的人群而言也不够直观。

左中是使用了 HCL 理论进行配色的图表,左下方是对颜色进一步降饱和后的版本。颜色渐变暗示的信息更易懂,从右侧的去色图中也能进一步确认颜色间进行了温和过渡,并确保不同颜色的过渡传达出了正确信息。

应用 HCL 到产品配色中

使用辅助工具

事实上,已经有不少帮助你使用 HCL 进行配色的工具存在了。

  • 可用性检查

    • Chrome 65+ devtools 在取色器里内置了符合 WCAG2.1 AA 与 AAA 标准的前、背景色对比度计算
    • color.review 同样提供两个颜色的感知明度对比计算。这是我想做但一直搁置,直到发现有人推出了→_→
    • Sketch: Cluse 同样是帮助检查颜色是否达到 AA 或 AAA 标准

硬核派:HSL/RGB 转换为 HCL

由于 HSL 是基于 RGB 色彩模型产生,色彩空间与 RGB 一致。但 HCL 属于另一种色彩空间,两者不一定能完全匹配。具体表现为:转换后颜色但色相、感知明度均存在,但颜色的色距不一定在 HCL 色彩空间范围内。

产品配色 2.0:使用 HCL 色彩空间替代 HSL 生成配色 - 二三事 - 图4

HCL 只能承载这么多颜色。纵轴为感知明度,平面圆心的角度为色相,圆半径为色距6

将 RGB 颜色转换为 HCL 需要通过 sRGB → linearRGB → CIEXyz → CIELab → CIELch,具体转换公式可以查看 W3C 给出的代码

硬核派:计算 HSL/RGB 的感知明度

⚠️ 前方公式高能,看见公式就头疼的话还是跳过吧。

将 HSL 转换为线性 RGB (linear RGB)

当 0 ≤ H < 360, 0 ≤ S ≤ 1 and 0 ≤ L ≤ 1 时,

参照下表得出 R’, G’, B’的值:

(R′,G′,B′)={(C,X,0),0°<=H<60°(X,C,0),60°<=H<120°(0,C,X),120°<=H<180°(0,X,C),180°<=H<240°(X,0,C),240°<=H<300°(C,0,X),300°<=H<360°}

(R8bit,G8bit,B8bit)=((R′+m),(G′+m),(B′+m))

如果最初是由 8-bit RGB 值转换为 HCL 那么从这里开始,否则无视;

(Rsrgb,Gsrgb,Bsrgb)=(R8bit/255,G8bit/255,B8bit/255)

进行校正:

R={Rsrgb<=0.03928,Rsrgb/12.92Rsrgb>0.03928,((Rsrgb+0.055)/1.055)2.4}

G={Gsrgb<=0.03928,Gsrgb/12.92Gsrgb>0.03928,((Gsrgb+0.055)/1.055)2.4}

B={Bsrgb<=0.03928,Bsrgb/12.92Bsrgb>0.03928,((Bsrgb+0.055)/1.055)2.4}

使用线性 RGB 计算颜色的感知明度

Luma=0.2126∗R+0.7152∗G+0.0722∗B

计算两个颜色的对比度

其中,分子中的 Luma1 是两个颜色中较浅色的感知明度,分母中的 Luma2 是较深色的感知明度。对比度范围在 1 到 21 之间,通常又写为 1:1 到 21:1。

C=(Luma1+0.05)/(Luma2+0.05)

H 保持不变,由以上可得 H, C, Luma。

延伸阅读

本篇使用公式、图片排版、脚注、目录、html 等均由 Typlog 内置 markdown 编辑器原生支持。喜欢写文章的同学欢迎看看 Typlog

  1. W3C. “How to Meet WCAG (Quick Reference).” How to Meet WCAG (Quickref Reference), 4 Oct. 2019, www.w3.org/WAI/WCAG21/quickref/#contrast-minimum.
  2. 本文提到的 RGB 色彩空间,均指 sRGB。
  3. Bednarz, Etienne. “HCL Utilities.” Art Station, www.artstation.com/artwork/ybGP9x.
  4. 原始图片来源: National Oceanic and Atmospheric Administration
  5. Stauffer, Reto. “Why HCL.” HCL Wizard, hclwizard.org/why-hcl/. Licensed under Creative Commons Attribution 3.0 Unported License.
  6. 图片来源: python-colorspace
    https://jessieji.com/2020/hcl-instead-of-hsl