我刚在我的 “CSS3 之后有什么新变化?” 文章中谈到了最近和可能将来的 CSS 颜色变化。 奇怪的是,变化很多。 定义颜色的新方法和即将出现的方法与我们现在拥有的方法一样多,甚至更多。 我想我们快速浏览一下。
首先,一个重要的提醒。 这些东西太复杂了。 我几乎不明白。 但是这里有一些方面
- 在所有即将到来的变化之前,我们只拥有 RGB 作为颜色模型,并且所有内容都与之相关。
- 我们有不同的“颜色空间”以不同的方式处理它(例如,
rgb()
函数将 RGB 颜色模型映射为具有线性坐标的立方体,hsl()
函数将 RGB 颜色模型映射为圆柱体),但它们都是 sRGB 色域。 - 随着即将到来的变化,我们获得了新的颜色模型以及 (!) 我们获得了以不同方式映射该颜色模型的新函数。 所以我想这有点像双重三重打击。
我个人无法向您讲解所有细枝末节 - 我写这篇文章是因为我敢肯定有很多人像我一样,想知道为什么您应该关心这些,而这是我试图理解为什么我应该关心所有这些。
Display-P3 是一个可以打开更多鲜艳颜色范围的功能,这些颜色以前无法表达。
body {
background: color(display-p3 1 0.08 0); /* super red! */
}
事实证明,现代显示器可以显示更多颜色,特别是更鲜艳的颜色,但我们只是没有办法使用经典的 CSS 颜色语法(如 HEX、RGB 和 HSL)来定义这些颜色。 太奇怪了,对吧?! 但是,如果您使用 Display-P3,您就可以获得更多鲜艳颜色的访问范围。

开发工作室 Panic 早期就锁定了这个功能,并开始使用这些颜色作为“秘密武器”。
🌈 除了 WebGL 之外,p3 颜色现在也是 Panic 网站秘密武器堆栈中重要的一部分。 嘘,不要告诉任何人,但您应该在 iMac Pro 屏幕上查看此页面! https://#/glrhPNuCdR
— Panic (@panic) 2019 年 5 月 24 日
Jen Simmons 还介绍了如何使用它们,包括对不支持浏览器的回退。
Display P3 颜色。 在浏览器中设计。 太棒了。
— Jen Simmons (@jensimmons) 2022 年 1 月 5 日
让我向您展示如何切换到 P3,找到一种颜色,然后为旧版浏览器找到一种回退颜色。 所有这些都在 Safari Web Inspector 中完成。(打开声音以听我解释!) pic.twitter.com/AaKhrn2s3e
资源
- 使用 Display-P3 在 CSS 中实现广色域颜色(WebKit 博客)
- 网络上不断扩展的颜色色域(Ollie Williams)
HWB 更适合“人类”,不过这也存在争议,并且它仍然基于 sRGB。
我不知道 hwb()
是什么 - 感谢 Stefan Judis 对此进行博客报道。
我通常认为 HSL 是“适合人类”的 CSS 颜色格式(而且 非常适合编程控制),因为,好吧,操作 360° 的色相和 0-100% 的饱和度和亮度在某种程度上是有意义的。
但在 hwb()
中,我们有色相(我认为与 HSL 相同),然后是白度和黑度。 Stefan
在颜色中添加白色和黑色会影响它的饱和度。 假设您在颜色中添加相同量的白色和黑色,颜色色调保持不变,但颜色会失去饱和度。 这适用于高达 50% 的白色和 50% 的黑色 (
hwb(0deg 50% 50%
),这会产生一种无彩色。

Stefan 对此表示怀疑,认为这与 HSL 一样容易理解,我倾向于同意。 我可能只需要更习惯它,但它似乎比简单地改变亮度或饱和度更抽象。
HWB 仅限于与所有旧颜色格式相同的颜色色域 (sRGB)。 这里没有解锁任何新颜色。
资源
- HWB 颜色选择器
- hwb() – 适合人类的颜色表示法?(Stefan Judis)
rgb()
,但具有更广泛的色域。
LAB 就像 div {
background: lab(150% -400 400);
}
我喜欢 Eric Portis 对 LAB 的解释,当我四处询问时,他告诉我。
LAB 类似于 RGB,因为它有三个线性分量。 数字越低,表示该分量越少,数字越大,表示该分量越多。 因此,您可以使用 LAB 来指定有史以来最亮、最绿的绿色,它对每个人来说都是超级明亮和绿色的,但在具有更宽色域的显示器上会更亮和更绿。
所以,我们得到了所有额外的颜色,这很棒,但 sRGB 还有另一个问题(除了在颜色表达方面受到限制),它不是感知一致的。 Brian Kardell
sRGB 空间不是感知一致的。 相同的数学运动具有不同的感知效果程度,具体取决于您在颜色空间中的位置。 如果您想阅读设计师对此的体验,这里有一个 有趣的例子,它很好地说明了努力做到这一点的困难。
这里最典型的例子是,在 HSL 中,具有完全相同“亮度”的颜色实际上感觉完全不同。
HSL 与 LAB:: 亮度 💡
— Adam Argyle (@argyleink) 2019 年 12 月 3 日
来自我们棘手的颜色调查的相同颜色,但这次我显示了 LAB 版本的相同颜色。 请注意,LAB 的亮度值与我们的调查结果多么接近!
🎨 颜色空间并不都相同,伙计们! https://#/AIEs0amdWY pic.twitter.com/xkEguq3KZG
但在 LAB 中,显然,它是感知一致的,这意味着以编程方式操作颜色是一项更合理的任务。 另一个好处是 LAB 颜色被指定为设备无关。 这是 Michelle Barker 的观点
LAB 和 LCH 在 规范 中被定义为设备无关颜色。 LAB 是一种可以在 Photoshop 等软件中访问的颜色空间,如果您希望颜色在屏幕上看起来与在 T 恤上印刷的颜色相同,则建议使用它。
资源
-
lab()
(MDN) - 使用 RGB、HSL、HWB、LAB 和 LCH 的现代 CSS 颜色指南(Michelle Barker)
hsl()
,但具有更广泛的色域。
LCH 就像 还记得我说过 HSL “适合人类”吗?因为它比 RGB 更易于理解? 更改色相、饱和度和亮度在逻辑上很有意义。 lch()
中也是如此,我们有亮度、色度和色相。 回到我和 Eric Portis 的谈话
LCH 更像 HSL:一个极坐标空间。 H = 色相 = 一个圆。 因此,执行数学运算以选择互补色(或您想要的任何转换)变得微不足道(只需添加 180 度 - 或任何值!)。
我认为您会选择 LCH,仅仅是因为您喜欢它的语法,或者因为它使您尝试执行的一些复杂编程变得更轻松 - 并且您了解到它可以免费表达 50% 的更多颜色。
我们也获得了感知一致性。 这是 Lea Verou 的观点,她似乎很兴奋,因为亮度实际上会有意义
在 HSL 中,亮度没有意义。颜色可以具有相同的亮度值,但感知亮度却大不相同。[...] 使用 LCH,任何具有相同亮度的颜色在感知上都具有相同的亮度,而任何具有相同色度的颜色在感知上都具有相同的饱和度。
新模型的另一个好处是,我们可以摆脱 CSS 颜色渐变中的“灰色死区”。我认为由于这种感知一致性,两种丰富的颜色不会变得轻浮,并在非丰富区域进行渐变。

以下是一个小小的个人预测:我认为 lch()
很可能会成为设计师的最爱。很快就会出现大量的新的颜色选择,而总是选择不同的颜色太过困难和奇怪。LCH 似乎在脑力上是最划算的。
资源
lch()
(MDN)- CSS 中的 LCH 颜色:是什么、为什么以及如何使用? (Lea Verou)
- LCH 颜色选择器
“好的”
LAB 及其朋友似乎非常新,因为它们对于 CSS 来说是新的...但 LAB 是在 1940 年代发明的。在与 Adam Argyle 的对话中,他用了一个令人难忘的短语:所有颜色空间都有一个致命弱点。也就是说,它们在某些方面有点糟糕。对于 sRGB 来说,就是灰色死区问题,以及有限的色域。LAB 很好,但它确实有自己的弱点。例如,LAB 中的蓝到白的渐变通过紫色区域时会非常不自然。
2020 年 12 月,Björn Ottosson 说了一句“嘿,一个新的颜色空间出现了,”现在 OKLAB 存在了。显然,CSS 的掌权者认为这个颜色空间有足够的价值,因此 oklab()
和 oklch()
都已经在规范中。我想我们应该关心它们,因为它们普遍更好,但不要引用我的话。
color()
函数,而其他函数不使用?
为什么 Display P3 使用 我真的不知道。我认为 CSS 的 color()
函数比较新,而 Safari 只是把它放进去而已。我不知道 Display P3 是否会获得自己的专用函数,或者我们是否应该开始使用 CSS 的 color()
函数,或者其他什么方法。
/* This is how you use Display P3 */
color(display-p3 1 0.08 0);
/* But this doesn't work */
color(oklch 42.1% 0.192 328.6);
/* You gotta do this instead 🤷♀️ */
oklch(42.1% 0.192 328.6);
/* But you can use the color space within a gradient... */
background-image: linear-gradient(
to right
in oklch,
lch(50% 100 100),
lch(50% 100 250)
);
相对颜色语法非常有用。
有一种非常酷的功能叫做“相对颜色语法”,你可以用它基本上分解 CSS 颜色,同时将其转换为另一种格式。假设你有最著名的 CSS HEX 颜色,fog dog,你想把它转换成 HSL
body {
background: hsl(from #f06d06 h s l);
}
也许这在目前并没有那么有用,但是,现在我们可以向它添加 alpha!实际上没有其他方法可以向现有的 HEX 颜色添加 alpha,所以这有点大。
body {
background: hsl(from #f06d06 h s l / 0.5);
}
但我也可以修改它。假设我想在添加不透明度之前先对 fog dog 进行一些饱和度调整,因为较低的不透明度会自然地使它变暗,我想抵消这种效果。我可以对那里隐含的变量使用 calc()
body {
background: hsl(from #f06d06 h calc(s + 20%) l / 0.5);
}
太酷了。我相信我们会看到一些惊人的事情从这里诞生。当然,它并不局限于 HSL。我只是在使用 HSL,因为它现在对我来说很舒服。如果我想用 LCH 修改命名颜色 red
,也可以。
body {
background: lch(from red l calc(c + 15) h / 0.25);
}
当与 自定义属性 结合使用时,这些东西将非常有用。
不再有专门用于 alpha 的特殊函数。
明确一点:CSS 颜色函数中的 alpha 值前面没有逗号 - 而是使用正斜杠。
/* Old! */
rgb(255, 0, 0);
rgba(255, 0, 0, 0.5);
/* New! */
rgb(255 0 0);
rgb(255 0 0 / 0.5);
hsl(0deg 40% 40%)
hsl(0deg 40% 40% / 90%) /* can be percentage rather than 0.9 or whatever */
/* The New color stuff ONLY has the single base function, no alpha secondardy function */
lab(49% 39 80)
lab(49% 39 80 / 0.25)
/* Display P3, with the color function, essentially works the same way with the slash */
color(display-p3 1 0.08 0 / 0.25);
你甚至可以定义自己的 CSS 颜色空间。
但我真的无法想象。这让我头晕,抱歉。
我个人对
lch()
非常兴奋,并且会在它获得更广泛的浏览器支持后立即开始使用它。此外,oklab()
和oklch
不仅已在规范中,而且自TP 137
以来也已在 Safari 中得到支持。还有。
非常有见地,谢谢
“实际上没有其他方法可以向现有的 HEX 颜色添加 alpha...”
我认为我们已经能够很长时间地使用隐含的第四个通道了
#f06d0688
将为您提供具有透明度的颜色。00 表示完全透明,ff 表示完全不透明。哇,这太疯狂了
是的,使用四字节十六进制已经有一段时间了。但在此之前,没有办法在自定义属性中将 alpha 添加到声明的十六进制颜色中,例如。你可以使用 rgb/hsl 颜色函数和自定义属性。
这也让我很困惑。我一直在使用 RGBa 好几百年了。我是不是误解了什么?
还要注意,你可以使用简写,例如
#fc08
(rgba),它会输出为#ffcc0088
(rrggbbaa)我偶然发现了这一点。我很沮丧,想在不将 HEX 转换为 rgb 并添加 A 的情况下实现透明度,所以我就在十六进制代码的末尾添加了 44,然后就有了透明度!很快,我发现它也适用于短代码!
#fff8
与#ffffff88
的效果相同。我不知道这是什么时候开始的,但我一直在使用它!我认为有一篇文章解释为什么我们需要 display-p3,以及为什么我们不能再用 RGB 表达所有颜色会很棒。
为什么我们有颜色配置文件,以及为什么我们不能都期待
#FFF
是最白的白色,而#F00
是最红的红色等等。“Stefan 表达了一些怀疑,认为这比 HSL 更难理解,我倾向于同意。我可能只是需要更多地习惯它,但它似乎比简单地改变亮度或饱和度更抽象。”
你可以把 HWB 想象成一个孩子玩水彩颜料。
你喜欢什么颜色?选择一个颜料管 (H)。
你想让它更亮吗?添加更多白色 (W)。
你想让它更暗吗?添加更多黑色 (B)。
你把白色和黑色等量混合在一起了吗?好吧,现在你必须用它来画你的可爱兔子灰色了,抱歉。
与 HSL 相比,我认为 HWB 实际上更具体,因此更容易理解。
似乎颜色属性需要一个标准的颜色配置文件,该配置文件定义了一个颜色空间。将 srgb 作为属性会造成混淆,但它是被继承的。
Hsl、rgb、lab… 这些都是描述颜色空间中的一个点的方法,而不是配置文件本身。