oklab()
函数符 oklab() 在 Oklab 颜色空间中表示给定的颜色,该颜色空间试图模仿人眼感知颜色的方式。
Oklab 是一个感知颜色空间,可用于:
- 将图像转换为灰度,而不改变其亮度。
- 修改颜色的饱和度,同时保持用户对色相和亮度的感知。
- 创建平滑均匀的颜色渐变(例如,在
<canvas>元素中手动插值时)。
oklab() 在 Oklab 颜色空间中使用笛卡尔坐标系——a 轴和 b 轴。它可以表示比 RGB 更广泛的颜色范围,包括宽色域和 P3 颜色。如果你想要一个使用色度和色相的极坐标颜色系统,请使用 oklch()。
语法
/* Absolute values */
oklab(40.1% 0.1143 0.045);
oklab(59.69% 0.1007 0.1191);
oklab(59.69% 0.1007 0.1191 / 0.5);
/* Relative values */
oklab(from green l a b / 0.5)
oklab(from #123456 calc(l + 0.1) a b / calc(alpha * 0.9))
oklab(from hsl(180 100% 50%) calc(l - 0.1) a b)
值
下面描述了绝对颜色和相对颜色的允许值。
绝对值语法
oklab(L a b[ / A])
参数如下:
L-
一个介于
0和1之间的<number>,一个介于0%和100%之间的<percentage>,或关键字none(在此情况下等同于0%)。此值指定颜色的感知亮度。数字0对应0%(黑色),数字1对应100%(白色)。 a-
一个介于
-0.4和0.4之间的<number>,一个介于-100%和100%之间的<percentage>,或关键字none(在此情况下等同于0%)。此值指定颜色沿 Oklab 颜色空间中a轴的距离,该轴定义了颜色的绿色程度(朝-0.4移动)或红色程度(朝+0.4移动)。请注意,这些值是有符号的(允许正值和负值)并且理论上是无界的,这意味着你可以设置超出±0.4(±100%)限制的值。在实践中,值不能超过±0.5。 b-
一个介于
-0.4和0.4之间的<number>,一个介于-100%和100%之间的<percentage>,或关键字none(在此情况下等同于0%)。此值指定颜色沿 Oklab 颜色空间中b轴的距离,该轴定义了颜色的蓝色程度(朝-0.4移动)或黄色程度(朝+0.4移动)。请注意,这些值是有符号的(允许正值和负值)并且理论上是无界的,这意味着你可以设置超出±0.4(±100%)限制的值。在实践中,值不能超过±0.5。 A可选-
一个
<alpha-value>,表示颜色的 alpha 通道值,其中数字0对应0%(完全透明),1对应100%(完全不透明)。此外,关键字none可用于明确指定无 alpha 通道。如果未明确指定A通道值,则默认为 100%。如果包含该值,则其前面需要有一个斜杠(/)。
备注:有关 none 的效果,请参阅缺失的颜色分量。
相对值语法
oklab(from <color> L a b[ / A])
参数如下:
from <color>-
在定义相对颜色时,总是包含关键字
from,其后跟着一个<color>值,表示源颜色。这是相对颜色所基于的原始颜色。源颜色可以是任何有效的<color>语法,包括另一个相对颜色。 L-
一个介于
0和1之间的<number>,一个介于0%和100%之间的<percentage>,或关键字none(在此情况下等同于0%)。此值表示输出颜色的亮度。数字0对应0%(黑色),数字1对应100%(白色)。 a-
一个介于
-0.4和0.4之间的<number>,一个介于-100%和100%之间的<percentage>,或关键字none(在此情况下等同于0%)。此值表示输出颜色沿 Oklab 颜色空间中a轴的距离,该轴定义了颜色的绿色程度(朝-0.4移动)或红色程度(朝+0.4移动)。请注意,这些值是有符号的(允许正值和负值)并且理论上是无界的,这意味着你可以设置超出±0.4(±100%)限制的值。在实践中,值不能超过±0.5。 b-
一个介于
-0.4和0.4之间的<number>,一个介于-100%和100%之间的<percentage>,或关键字none(在此情况下等同于0%)。此值表示输出颜色沿 Oklab 颜色空间中b轴的距离,该轴定义了颜色的蓝色程度(朝-0.4移动)或黄色程度(朝+0.4移动)。请注意,这些值是有符号的(允许正值和负值)并且理论上是无界的,这意味着你可以设置超出±0.4(±100%)限制的值。在实践中,值不能超过±0.5。 A可选-
一个
<alpha-value>,表示输出颜色的 alpha 通道值,其中数字0对应0%(完全透明),1对应100%(完全不透明)。此外,关键字none可用于明确指定无 alpha 通道。如果未明确指定A通道值,则默认为源颜色的 alpha 通道值。如果包含该值,则其前面需要有一个斜杠(/)。
定义相对颜色输出通道分量
在 oklab() 函数内部使用相对颜色语法时,浏览器会将源颜色转换为等效的 Oklab 颜色(如果尚未指定)。颜色被定义为三个不同的颜色通道值——l(亮度)、a(绿/红轴)和 b(蓝/黄轴)——外加一个 alpha 通道值(alpha)。这些通道值在函数内部可用,用于定义输出颜色的通道值。
l通道值解析为一个介于0和1(含)之间的<number>。a和b通道各自解析为一个介于-0.4和0.4(含)之间的<number>。alpha通道值解析为一个介于0和1(含)之间的<number>。
在定义相对颜色时,输出颜色的不同通道可以用几种不同的方式表示。下面,我们将通过一些示例来说明这些方式。
在下面的前两个示例中,我们使用了相对颜色语法。然而,第一个示例输出的颜色与源颜色相同,第二个示例输出的颜色则完全不基于源颜色。它们并没有真正创建相对颜色!你不太可能在真实的代码库中使用这些,而是可能会直接使用绝对颜色值。我们包含这些示例是为了让你初步了解相对 oklab() 语法。
让我们从源颜色 hsl(0 100% 50%)(等同于 red)开始。以下函数输出与源颜色相同的颜色——它使用源颜色的 l、a 和 b 通道值(0.627966、0.22488 和 0.125859)作为输出通道值。
oklab(from hsl(0 100% 50%) l a b)
此函数的输出颜色为 oklab(0.627966 0.22488 0.125859)。
下一个函数对输出颜色的通道值使用绝对值,输出了一个完全不同于源颜色的新颜色:
oklab(from hsl(0 100% 50%) 42.1% 0.165 -0.101)
在上述情况下,输出颜色为 oklab(0.421 0.165 -0.101)。
以下函数创建了一个基于源颜色的相对颜色:
oklab(from hsl(0 100% 50%) l -0.3 b)
此示例:
- 将
hsl()源颜色转换为等效的oklab()颜色——oklab(0.627966 0.22488 0.125859)。 - 将输出颜色的
L和b通道值设置为源oklab()等效颜色的L和b通道值——这些值分别为0.627966和0.125859。 - 将输出颜色的
a通道值设置为一个不基于源颜色的新值:-0.3。
最终输出的颜色是 oklab(0.627966 -0.3 0.125859)。
备注:如上所述,如果输出颜色使用的颜色模型与源颜色不同,源颜色会在后台被转换为与输出颜色相同的模型,以便能够以兼容的方式表示(即使用相同的通道)。
在本节我们目前看到的示例中,源颜色和输出颜色的 alpha 通道都没有被明确指定。当未指定输出颜色的 alpha 通道时,它默认为与源颜色 alpha 通道相同的值。当未指定源颜色的 alpha 通道时(且它不是相对颜色),它默认为 1。因此,上述示例中的源和输出 alpha 通道值均为 1。
让我们看一些指定源和输出 alpha 通道值的示例。第一个示例将输出 alpha 通道值指定为与源 alpha 通道值相同,而第二个示例则指定一个与源 alpha 通道值无关的不同输出 alpha 通道值。
oklab(from hsl(0 100% 50% / 0.8) l a b / alpha)
/* Computed output color: oklab(0.627966 0.22488 0.125859 / 0.8) */
oklab(from hsl(0 100% 50% / 0.8) l a b / 0.5)
/* Computed output color: oklab(0.627966 0.22488 0.125859 / 0.5) */
在下面的示例中,hsl() 源颜色再次被转换为等效的 oklab() 颜色——oklab(0.627966 0.22488 0.125859)。然后将 calc() 计算应用于 L、a、b 和 A 值,最终得到输出颜色 oklab(0.827966 0.14488 -0.0741406 / 0.9)。
oklab(from hsl(0 100% 50%) calc(l + 0.2) calc(a - 0.08) calc(b - 0.2) / calc(alpha - 0.1))
备注:因为源颜色通道值被解析为 <number> 值,所以在使用它们进行计算时,你必须给它们加上数字,即使在通道通常接受 <percentage>、<angle> 或其他值类型的情况下也是如此。例如,将 <percentage> 添加到 <number> 是行不通的。
正式语法
<oklab()> =
oklab( [ from <color> ]? [ <percentage> | <number> | none ] [ <percentage> | <number> | none ] [ <percentage> | <number> | none ] [ / [ <alpha-value> | none ] ]? )
<alpha-value> =
<number> |
<percentage>
示例
调整亮度
以下示例展示了改变 oklab() 函数的亮度、a 轴和 b 轴值的效果。
HTML
<div data-color="red-dark"></div>
<div data-color="red"></div>
<div data-color="red-light"></div>
<div data-color="green-dark"></div>
<div data-color="green"></div>
<div data-color="green-light"></div>
<div data-color="blue-dark"></div>
<div data-color="blue"></div>
<div data-color="blue-light"></div>
CSS
[data-color="red-dark"] {
background-color: oklab(0.05 0.4 0.4);
}
[data-color="red"] {
background-color: oklab(0.5 0.4 0.4);
}
[data-color="red-light"] {
background-color: oklab(0.95 0.4 0.4);
}
[data-color="green-dark"] {
background-color: oklab(5% -100% 0.4);
}
[data-color="green"] {
background-color: oklab(50% -100% 0.4);
}
[data-color="green-light"] {
background-color: oklab(95% -100% 0.4);
}
[data-color="blue-dark"] {
background-color: oklab(0.05 -0.3 -0.4);
}
[data-color="blue"] {
background-color: oklab(0.5 -0.3 -0.4);
}
[data-color="blue-light"] {
background-color: oklab(0.95 -0.3 -0.4);
}
结果
调整不透明度
以下示例展示了改变 oklab() 函数的 A(alpha)值的效果。red 和 red-alpha 元素与 #background-div 元素重叠,以演示不透明度的效果。将 red-alpha 元素的不透明度设为 0.4 使其看起来比 red 元素更透明。
HTML
<div id="background-div">
<div data-color="red"></div>
<div data-color="red-alpha"></div>
</div>
CSS
[data-color="red"] {
background-color: oklab(0.628 0.225 0.126);
}
[data-color="red-alpha"] {
background-color: oklab(0.628 0.225 0.126 / 0.4);
}
结果
调整颜色轴
此示例演示了将 oklab() 函数的 a 和 b 值分别设置为 a 轴和 b 轴的端点和中点的效果。a 轴从绿色(-0.4)到红色(0.4),b 轴从黄色(-0.4)到蓝色(0.4)。
HTML
<div data-color="red-yellow"></div>
<div data-color="red-zero"></div>
<div data-color="red-blue"></div>
<div data-color="zero-yellow"></div>
<div data-color="zero-zero"></div>
<div data-color="zero-blue"></div>
<div data-color="green-yellow"></div>
<div data-color="green-zero"></div>
<div data-color="green-blue"></div>
CSS
我们使用 CSS 的 background-color 属性,沿着 a 轴和 b 轴改变 oklab() 颜色函数的 a 和 b 值,展示了每种情况下的最大值、中点值和最小值的影响。
/* a-axis max, variable b-axis */
[data-color="red-yellow"] {
background-color: oklab(0.5 0.4 0.4);
}
[data-color="red-zero"] {
background-color: oklab(0.5 0.4 0);
}
[data-color="red-blue"] {
background-color: oklab(0.5 0.4 -0.4);
}
/* a-axis center, variable b-axis */
[data-color="zero-yellow"] {
background-color: oklab(0.5 0 0.4);
}
[data-color="zero-zero"] {
background-color: oklab(0.5 0 0);
}
[data-color="zero-blue"] {
background-color: oklab(0.5 0 -0.4);
}
/* a-axis min, variable b-axis */
[data-color="green-yellow"] {
background-color: oklab(0.5 -0.4 0.4);
}
[data-color="green-zero"] {
background-color: oklab(0.5 -0.4 0);
}
[data-color="green-blue"] {
background-color: oklab(0.5 -0.4 -0.4);
}
结果
左列位于 b 轴的黄色端(-0.4),右列位于蓝色端(0.4)。顶行显示了 a 轴红色端(-0.4)的颜色,底行则是绿色端(0.4)。中间的行和列位于各自轴的中点,中间的单元格是灰色;它不含红色、绿色、黄色或蓝色,两个轴的值都为 0。
沿 a 轴和 b 轴的线性渐变
此示例包含线性渐变,以演示 oklab() 函数的值沿 a 轴(从红到绿)和 b 轴(从黄到蓝)的变化过程。在每个渐变图像中,一个轴保持不变,而另一个轴的值从低到高变化。
CSS
/* a-axis gradients */
[data-color="red-to-green-yellow"] {
background-image: linear-gradient(to right, oklab(50% 0.4 0.4), oklab(50% -0.4 0.4));
}
[data-color="red-to-green-zero"] {
background-image: linear-gradient(to right, oklab(50% 0.4 0), oklab(50% -0.4 0));
}
[data-color="red-to-green-blue"] {
background-image: linear-gradient(to right, oklab(50% 0.4 -0.4), oklab(50% -0.4 -0.4));
}
/* b-axis gradients */
[data-color="yellow-to-blue-red"] {
background-image: linear-gradient(to right, oklab(50% 0.4 0.4), oklab(50% 0.4 -0.4));
}
[data-color="yellow-to-blue-zero"] {
background-image: linear-gradient(to right, oklab(50% 0 0.4), oklab(50% 0 -0.4));
}
[data-color="yellow-to-blue-green"] {
background-image: linear-gradient(to right, oklab(50% -0.4 0.4),oklab(50% -0.4 -0.4));
}
结果
将 oklab() 用于相对颜色
此示例为三个 <div> 元素设置了不同的背景颜色。中间的元素使用了未经修改的 --base-color,而左右两边的元素则使用了该 --base-color 的提亮和变暗版本。
这些变体是使用相对颜色定义的——将 --base-color 自定义属性传递给一个 oklab() 函数,然后通过一个 calc() 函数修改输出颜色的亮度通道以达到预期效果。亮色变体的亮度通道增加了 0.15(15%),而暗色变体的亮度通道减少了 0.15(15%)。
CSS
:root {
--base-color: orange;
}
#one {
background-color: oklab(from var(--base-color) calc(l + 0.15) a b);
}
#two {
background-color: var(--base-color);
}
#three {
background-color: oklab(from var(--base-color) calc(l - 0.15) a b);
}
结果
输出如下:
规范
| 规范 |
|---|
| CSS 颜色模块第五版 # 相对 Oklab |
| CSS 颜色模块第四版 # ok-lab |
浏览器兼容性
加载中…
另见
<color>数据类型,查看所有颜色表示法的列表lab()和oklch()颜色函数- 使用相对颜色
- CSS 颜色模块
- 用于图像处理的感知颜色空间(位于 bottosson.github.io,2023 年)
- OKLAB 色轮(位于 observablehq.com)