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 #0000FF 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 通道值的
<alpha-value>
,其中数字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 通道值的
<alpha-value>
,其中数字0
对应0%
(完全透明),1
对应100%
(完全不透明)。此外,可以使用关键字none
显式指定没有 alpha 通道。如果未显式指定A
通道值,则默认为原色的 alpha 通道值。如果包含,则该值前面带有斜杠 (/
)。
定义相对颜色输出通道组件
在 oklab()
函数内使用相对颜色语法时,浏览器会将原色转换为等效的 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)
。应用于 L
、a
、b
和 A
值的 calc()
计算,生成输出颜色 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()
函数的亮度、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="redyellow"></div>
<div data-color="redzero"></div>
<div data-color="redblue"></div>
<div data-color="zeroyellow"></div>
<div data-color="zerozero"></div>
<div data-color="zeroblue"></div>
<div data-color="greenyellow"></div>
<div data-color="greenzero"></div>
<div data-color="greenblue"></div>
CSS
使用 CSS background-color
属性,我们沿着 a 轴和 b 轴改变 oklab()
颜色函数的 a
和 b
值,显示每种情况下最大值、中点值和最小值的效果。
/* a-axis max, variable b-axis */
[data-color="redyellow"] {
background-color: oklab(0.5 0.4 0.4);
}
[data-color="redzero"] {
background-color: oklab(0.5 0.4 0);
}
[data-color="redblue"] {
background-color: oklab(0.5 0.4 -0.4);
}
/* a-axis center, variable b-axis */
[data-color="zeroyellow"] {
background-color: oklab(0.5 0 0.4);
}
[data-color="zerozero"] {
background-color: oklab(0.5 0 0);
}
[data-color="zeroblue"] {
background-color: oklab(0.5 0 -0.4);
}
/* a-axis min, variable b-axis */
[data-color="greenyellow"] {
background-color: oklab(0.5 -0.4 0.4);
}
[data-color="greenzero"] {
background-color: oklab(0.5 -0.4 0);
}
[data-color="greenblue"] {
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="redtogreen-yellow"] {
background-image: linear-gradient(to right, oklab(50% 0.4 0.4), oklab(50% -0.4 0.4));
}
[data-color="redtogreen-zero"] {
background-image: linear-gradient(to right, oklab(50% 0.4 0), oklab(50% -0.4 0));
}
[data-color="redtogreen-blue"] {
background-image: linear-gradient(to right, oklab(50% 0.4 -0.4), oklab(50% -0.4 -0.4));
}
/* b-axis gradients */
[data-color="yellowtoblue-red"] {
background-image: linear-gradient(to right, oklab(50% 0.4 0.4), oklab(50% 0.4 -0.4));
}
[data-color="yellowtoblue-zero"] {
background-image: linear-gradient(to right, oklab(50% 0 0.4), oklab(50% 0 -0.4));
}
[data-color="yellowtoblue-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 颜色模块级别 5 # relative-Oklab |
CSS 颜色模块级别 4 # ok-lab |
浏览器兼容性
BCD 表格仅在浏览器中加载
另请参阅
- 有关所有颜色表示法的列表,请参阅
<color>
数据类型 lab()
和oklch()
颜色函数- 使用相对颜色
- CSS 颜色 模块
- 用于图像处理的感知色彩空间 在 bottosson.github.io 上(2023)
- OKLAB 色彩环 在 observablehq.com 上