image

oklch是一种基于oklab的色彩空间,使用圆锥坐标系表示颜色,并且具有更好的视觉一致性和更直观的色相、饱和度控制。oklch色彩空间最早是在2020年由Maxwell Pretzlaff在他的硕士论文中发布的。在此之前,我跟大家随便聊聊它的前世今生是怎样的。

什么是色彩空间?

颜色的数量化表示可以通过使用色彩空间来实现。色彩空间是一种数学模型,它将颜色的三个方面(亮度、色相和饱和度)映射到一个数学空间中,常见的色彩空间 RGB、CMYK。

什么是1976 CIE Lab色彩空间?

CIELAB是CIE于1976年推出的一种色彩空间,其全称为CIELAB 1976。CIELAB是CIE(国际照明委员会)为了提供一种独立于特定设备的颜色描述方式,而设计出来的一种基于人眼感知的颜色空间。

image

人眼对不同波长光的响应是由视锥细胞和视杆细胞来完成的。视锥细胞可以感知较亮的光强度和色彩,而视杆细胞则能够感知较暗的光强度。不同波长的光会在视锥细胞中引起不同程度的光感受器的刺激,从而使人眼感知到不同的颜色。

所以呢,Lab 是一种设备无关的颜色空间,可以描述任何颜色,包括人眼无法感知的颜色。Lab 由三个坐标轴组成,分别是亮度轴 L、绿红轴 a 和蓝黄轴 b。它的计算方式基于三个标准刺激值(X、Y、Z),这些值由 CIE 1931 标准色度函数定义,然后将它们转换为相对 XYZ 三色刺激值。

什么是1931 色度函数?

那么,1931的色度函数是怎么来的,要追溯到CIE XYZ色彩空间,是从1920年代后期W. David Wright和John Guild做的一系列实验中得出的。

后来,在1931年,是国际照明委员会(CIE)发布的CIE 1931标准色度函数的一组标准,用于描述人眼在不同波长和强度的光下的色觉特性。该标准是通过大量实验测定得出的,用于描述三种基本色的相对响应值,这三种基本色是红(R)、绿(G)和蓝(B)。

image

为了描述人眼对不同波长光的响应,科学家们通过实验方法,对大量被试者的视觉感知数据进行统计和分析,得到了一组标准的相对光谱响应函数,即色度函数。这些色度函数可以用来计算颜色空间中的色度坐标,比如CIE XYZ色度空间中的X、Y、Z三个坐标。

CIE标准色度系统主要包括以下三个部分:

  1. 标准观察者:CIE标准观察者是根据实验数据统计得到的一组标准人眼对不同波长光的响应函数,它们对应于不同亮度水平下人眼的平均感光性。CIE 1931标准色度函数采用了两个标准观察者的光谱敏感度函数,一个是2度视场的标准观察者,另一个是10度视场的标准观察者。

  2. 标准光源:CIE标准光源是一组标准化的光源,它们的光谱分布和亮度都是事先定义好的。其中最常用的是CIE标准光源D65和D50,它们分别对应于自然日光和标准荧光灯光。

  3. 色度坐标系统:CIE标准色度系统定义了一种通过数值来表示颜色的方式,其中最常用的是CIE1931色度图和CIE1976色度图。CIE1931色度图使用了三个坐标表示颜色,即x、y和z,它们与标准观察者的三种原色(红、绿、蓝)有关。CIE1976色度图则使用了两个坐标,即a_和b_,它们描述了颜色的色相、明度和饱和度。

总的来说,色度函数是用于描述人眼对不同波长光的相对感知强度的函数。它是根据人眼的生理特性以及对不同波长光的响应,通过实验方法确定的一组标准函数,用于计算颜色空间中的色度坐标。

需要注意的是,虽然CIE 1931标准色度函数提供了一种描述颜色的标准,但实际上,人眼对颜色的感知是非常复杂的。人眼在感知颜色时不仅受到光线波长的影响,还受到亮度、对比度、周围环境等多种因素的影响。很多数据的产生都是基于特定的实验环境得到的,因此,颜色的描述和计算还需要考虑更多的因素。

什么是OKlab?

OkLab是一种新的颜色空间。它是由Alexei Boronine在2019年提出的,旨在解决Lab颜色空间的缺点,例如不均衡的颜色分布和对人眼不敏感的特性。OkLab旨在提供更加平衡的颜色分布,更好的感知均匀度,以及更加准确地反映人眼感知的特点,从而在各种颜色处理应用中提供更好的结果。

什么是OKlch?

OKlch是在OKlab的基础上进行了极坐标变换,将颜色的坐标表示从直角坐标系转换为极坐标系,方便对色相和色度的处理。为什么叫OK的前缀呢,因为它很OK(“It is called the Oklab color space, because it is an OK Lab color space.“ )

LCH分别代表什么?

L/Predictable Lightness 是感知亮度,是一个从白色到黑色的0%-100%的百分比。 C/Chroma 是色度,也可以说是颜色的数量,理论上是无限的值,但实际操作中不超过0.4。表示的从灰度到高饱和度的区间。 H 是0-360的色相环。 A 是0-1或0%-100%的透明度。

OKlch跟hsv和hsl的区别?

首先我们复习下什么是hsv,hsv是一种基于颜色的三个特性:色调(Hue)、饱和度(Saturation)和亮度(Value)的表示方法。它是一种圆锥形的颜色空间,HSV的表示方法比RGB更加直观,它可以直接调整颜色的亮度和饱和度,更符合人眼对颜色的感知。

  • 那我们为什么还需要OKlch呢?

image

其中最大的区别是,HSL将亮度(明度)与色相和饱和度分开考虑,而OKLCH是将亮度、色相和饱和度作为三个正交的维度进行描述的。这使得在OKLCH中更容易进行颜色的调整,而不会影响亮度。

此外,oklch对亮度、色度和饱和度的计算方式也与HSL不同,这些差异主要是由于oklch使用了更先进的颜色模型。oklch使用的色度测量方式基于类似于CIELUV的模型,而HSL使用一种相对较简单的RGB色彩模型来计算颜色的饱和度和亮度。

关于一个对比hsv和oklab,hsv梯度是相当不均匀的,不同的色调有明显的明度差异。黄色、品红和青色看起来比红色和蓝色要轻得多。

image

OKlch有什么应用呢?

同样是通过改变色相,单一参数,来平行换色,oklch可以保证对比度是差不多一致的。

image

再比如说色板的生成,通过oklch生成的色板更加人眼的视觉梯度。

image

OKlch工具

再推荐两个实用的OKlch工具,一个是转换器,可以方便从其他色彩空间转换过来。而是色板生成器, 可以更方便观察色板的梯度以及检查文字的对比度,那随便提下,感知对比度算法。

image

image

什么是感知对比度?

感知对比度算法通常被用于设计中,以确保文本和图像具有足够的对比度,从而使其易于阅读和理解。 通过最后这个色板生成工具显示的文字对比度可知,从某种程度上,我们控制了感知明度,也保证了感知对比度。 我们来看下核心的一句代码:

  • 计算像素的亮度
    luminance = 0.2126 * r + 0.7152 * g + 0.0722 * b

这个公式将三个通道的值按照一定的比例进行加权平均,得到一个亮度值,反映了这个像素的亮度大小。然后遍历所有的像素,并计算相邻像素之间的感知亮度差,然后对这些差值求平均,得到了一张图像的感知对比度。

这个加权原理是根据人眼对不同颜色的感知灵敏度来设计的。在这个加权原理中,红、绿、蓝三种颜色的权重分别为0.2126、0.7152和0.0722,这是根据CIE 1931标准色度函数中对应的红、绿、蓝三种颜色的响应值来确定的。

CIE 1931标准色度函数是通过一系列实验测定得出的,它描述了人眼在看到不同波长的光时的响应情况。在标准色度函数中,红、绿、蓝三种颜色的相对响应值分别为0.64、0.33和0.03,这也是确定加权原理中各种颜色的权重的基础。

不同的对比度

对于较小字体(小于 18 磅的常规字体或 14 磅的加粗字体),指定至少 4.5:1 的对比度 对于较大字体(18 磅及以上的常规字体或 14 磅及以上的加粗字体),指定至少 3.0:1 的对比度

 wcag2Parms = validateWCAG2Parms(wcag2);
    switch (wcag2Parms.level + wcag2Parms.size) {
        case "AAsmall":
        case "AAAlarge":
            out = readability >= 4.5;
            break;
        case "AAlarge":
            out = readability >= 3;
            break;
        case "AAAsmall":
            out = readability >= 7;
            break;
    }
    return out;

总结下

OKlch有什么优点呢?

  1. 独立的色相和饱和度:在 OKLCH 中,色相和饱和度是独立的,这意味着你可以改变其中一个属性而不影响另一个。这使得它在调整色彩时更加灵活。
  2. 更加自然的色相:相比于 HSL 和 HSV 等色彩空间,OKLCH 中的色相更加自然,更符合人类对于色彩的感知。
  3. 更加均匀的色彩分布:OKLCH 色彩空间中的色彩分布更加均匀,这使得在 OKLCH 空间中进行色彩计算更加精确。
  4. 相对亮度更加准确:OKLCH 色彩空间中的 L 属性对应于人类对亮度的感知,相对于 HSL 和 HSV 等色彩空间,其计算更加准确,更符合人类对亮度的感知。

当然目前的生态系统支持的不够,只有在Safari 15.4中得到支持。

.button:hover {
  background: oklch(from var(--button-color) calc(l + 10%) c h)
}

如果你想设计更好的颜色系统,OKlch将会是你新的不二之选。