OKLCH & OKLAB
来源
OKLAB 和 OKLCH 颜色空间是由 @Björn Ottosson 于 2020 年创建的,它们被创建的主要原因是为了解决 LAB 和 LCH 的问题,即解决色调偏移的错误,所以它们又称为 LAB 和 LCH 的修正版本。@Björn 撰写了一篇优秀的文章,详细介绍了为什么创造它们,以及它们的实现细节。
OKLAB 是一种基于 CIELAB 颜色空间的颜色模型,通过对不同光源下的颜色重新调整,尽可能减少颜色失值。而 OKLCH 则是在 OKLAB 的基础上发展而来的颜色类型,它增加了颜色的饱和度和色调信息,使得在设计中能够更好的进行颜色变化和搭配。
在 CSS 中,OKLAB 和 OKLCH 是相对较新的颜色类型,与传统的 RGB 相比,差异主要在于以下几个方面。
- 颜色空间不同 :OKLAB 和 OKLCH 是基于 CIELAB 颜色空间的颜色类型,而 RGB 是基于 sRGB 颜色空间的颜色类型,这也决定了它们在表达颜色时的差异。
- 更加准确的色彩表达 :由于 OKLAB 和 OKLCH 对不同光源下的颜色进行重新调整,它们能更加准确地表达颜色,为设计师提供更多的选择和更好的设计效果。
- 更广泛的颜色空间范围 :相比传统的 sRGB 颜色空间的颜色,OKLAB 和 OKLCH 能够表达更广泛的颜色,包括在鲜艳度、色彩鲜艳度和对比度方面表现更佳。
- 更灵活的颜色调整 :OKLCH 在 OKLAB 的基础上增加了颜色的浓度和色调信息,可以在设计中更加灵活且准确的表达颜色,比如通过色调调整来改变颜色的暖度和冷度值。
OKLAB
语法:
oklab(L a b)
或oklab(L a b / A)
四个值的含义:
L
用来指定感知明度(亮度),它介于0 ~ 1
之间的数字(<number>
)或介于0% ~ 100%
之间的百分比(<percentage>
)。此处数值0
(或0%
)代表黑色,1
(或100%
)代表白色。需要注意的是,使用百分比值时,取0
值时也需要带上单位%
,即0%
,而且当值小于0%
时,必须在计算值时被钳制解析为0%
;大于100%
的值被钳制解析为100%
。a
指定了在 OKLAB 空间中沿a
轴的距离,即颜色中绿或红的程度,它的值是介于-0.4 ~ 0.4
之间的数字(<number>
)或介于0% ~ 100%
之间的百分比(<percentage>
),其中0% = 0
,100% = 0.4
,-100% = -0.4
。b
指定了在 OKLAB 空间中沿b
轴的距离,即颜色中蓝或黄的程度,它的值是介于-0.4 ~ 0.4
之间的数字(<number>
)或介于0% ~ 100%
之间的百分比(<percentage>
),其中0% = 0
,100% = 0.4
,-100% = -0.4
。A
用来指定颜色的透明度,即颜色的 Alpha 通道的值,它的值是介于0 ~ 1
之间的数字(<number>
)或介于0% ~ 100%
之间的百分比值(<percentage>
)。
.element {
--color-1: oklab(40.101% 0.1147 0.0453);
--color-2: oklab(59.686% 0.1009 0.1192);
--color-3: oklab(0.65125 -0.0320 0.1274);
--color-4: oklab(66.016% -0.1084 0.1114);
--color-5: oklab(72.322% -0.0465 -0.1150);
--color-6: oklab(42.1% 41% -25%);
--color-7: oklab(21% -.4 2.5 / 50%);
--color-8: oklab(21% .4 -2.5 / .5);
}
OKLCH
语法:
oklch(l c h)
或oklch(l c h / A)
四个值的含义:
L
和oklab()
函数中的L
完全相同,指定了感知明度(亮度),它介于0 ~ 1
之间的数字(<number>
)或介于0% ~ 100%
之间的百分比(<percentage>
)。C
指的是色度(颜色饱和度),用于衡量色度(即“颜色的数量”),它介于0 ~ 0.4
之间的数字(<number>
)或介于0% ~ 100%
之间的百分比,其中0% = 0
,100% = 0.4
。它的最小值为0
(或0%
),如果提供的值为负值,则在计算值时会将其解析为0
(或0%
),而其最大值在理论上无界限,实际上却有一个限制(不超过0.5
),但这取决于屏幕的颜色色域(P3 颜色会比 sRGB 具有更大的值),每个色调的最大色度不同。对于 P3 和 sRGB,该值始终低于0.37
。H
指的是色相角度,它的解释类似于 HSL 和 LCH 中的H
,但不会以相同的方式将色相映射到角度上。它的值可以是数字(<number>
)或百分比(<percentage>
),其中0% = 0deg
,100% = 360deg
,并且在实际使用的时候,不需要显式设置角度单位,即deg
。0deg
度沿着正a
轴指向紫红色(如360deg
、720deg
);90deg
沿正b
轴指向芥末黄;180deg
沿着负a
轴指向蓝绿色;270deg
沿着负b
轴指向天蓝色。A
用来指定颜色的透明度,即颜色的 Alpha 通道的值,它的值是介于0 ~ 1
之间的数字(<number>
)或介于0% ~ 100%
之间的百分比值(<percentage>
)。
:root {
--color-1:oklch(40.101% 0.12332 21.555);
--color-2:oklch(59.686% 0.15619 49.7694);
--color-3:oklch(0.65125 0.13138 104.097);
--color-4:oklch(0.66016 0.15546 134.231);
--color-5:oklch(72.322% 0.12403 247.996);
--color-6:oklch(42.1% 48.25% 328.4);
}
选择 OKLCH 为下一代 WEB 颜色
更好的可读性
这个是相对于 十六进制、RGB、LAB、OKLAB 来说的
通过阅读代码,可以大概理解其所指的颜色:
- 观察
L
知道其明亮程度 - 通过
C
知道其鲜艳程度 - 观察
H
可以知道其大概是一个什么颜色, 对于 H 可以通过彩虹记忆法:红、橙、黄、绿、青、蓝、紫,为每个字母分配约50%
(这个会有点偏差)
颜色修改教简单
比如让一个颜色暗度减少(类似于 less 的 darken 方法),就可以减低 L
来实现
颜色域的转换
可以使用相同的颜色函数处理 sRGB 和 P3 宽色域颜色
.button {
background: oklch(50% 0.37 150);
}
@media (color-gamut: p3) {
.button {
background-color: oklch(50% 0.37 150);
}
}
OKLCH Polyfill
OKLCH 目前已经得到主流浏览器的支持了,但是对于老版本浏览器,还是需要做额外的处理
目前有两个支持 oklch()
的 Polyfill:
- 非常流行的
postcss-preset-env
- 用 Rust 编写的非常快速的 Lightning CSS
对于一个 css 文件,可以执行以下命令,生成 Polyfill 的代码
lightningcss --minify --bundle --targets '>= 0.25%' input.css -o output.css