4 种全新 CSS 颜色功能的速览

Avatar of Chris Coyier
Chris Coyier

DigitalOcean 为您旅程的每个阶段提供云产品。 立即开始使用 价值 200 美元的免费积分!

我刚在我的 “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,您就可以获得更多鲜艳颜色的访问范围。

Screenshot of a super bright pink in a CodePen preview using the display-p3 CSS color syntax.
Safari DevTools 中的那条白线向我们展示了 Display-P3 的“额外”范围

开发工作室 Panic 早期就锁定了这个功能,并开始使用这些颜色作为“秘密武器”。

Jen Simmons 还介绍了如何使用它们,包括对不支持浏览器的回退。

资源

HWB 更适合“人类”,不过这也存在争议,并且它仍然基于 sRGB。

我不知道 hwb() 是什么 - 感谢 Stefan Judis 对此进行博客报道

我通常认为 HSL 是“适合人类”的 CSS 颜色格式(而且 非常适合编程控制),因为,好吧,操作 360° 的色相和 0-100% 的饱和度和亮度在某种程度上是有意义的。

但在 hwb() 中,我们有色相(我认为与 HSL 相同),然后是白度黑度。 Stefan

在颜色中添加白色和黑色会影响它的饱和度。 假设您在颜色中添加相同量的白色和黑色,颜色色调保持不变,但颜色会失去饱和度。 这适用于高达 50% 的白色和 50% 的黑色 (hwb(0deg 50% 50%),这会产生一种无彩色。

Showing six gradients going from red to black and the impact that change CSS color values in hwb has on the transition between colors.

Stefan 对此表示怀疑,认为这与 HSL 一样容易理解,我倾向于同意。 我可能只需要更习惯它,但它似乎比简单地改变亮度或饱和度更抽象

HWB 仅限于与所有旧颜色格式相同的颜色色域 (sRGB)。 这里没有解锁任何新颜色。

资源

LAB 就像 rgb(),但具有更广泛的色域。

div {
  background: lab(150% -400 400);
}

我喜欢 Eric Portis 对 LAB 的解释,当我四处询问时,他告诉我。

LAB 类似于 RGB,因为它有三个线性分量。 数字越低,表示该分量越少,数字越大,表示该分量越多。 因此,您可以使用 LAB 来指定有史以来最亮、最绿的绿色,它对每个人来说都是超级明亮和绿色的,但在具有更宽色域的显示器上会更亮和更绿。

所以,我们得到了所有额外的颜色,这很棒,但 sRGB 还有另一个问题(除了在颜色表达方面受到限制),它不是感知一致的。 Brian Kardell

sRGB 空间不是感知一致的。 相同的数学运动具有不同的感知效果程度,具体取决于您在颜色空间中的位置。 如果您想阅读设计师对此的体验,这里有一个 有趣的例子,它很好地说明了努力做到这一点的困难。

这里最典型的例子是,在 HSL 中,具有完全相同“亮度”的颜色实际上感觉完全不同。

但在 LAB 中,显然,它是感知一致的,这意味着以编程方式操作颜色是一项更合理的任务。 另一个好处是 LAB 颜色被指定为设备无关。 这是 Michelle Barker 的观点

LAB 和 LCH 在 规范 中被定义为设备无关颜色。 LAB 是一种可以在 Photoshop 等软件中访问的颜色空间,如果您希望颜色在屏幕上看起来与在 T 恤上印刷的颜色相同,则建议使用它。

资源

LCH 就像 hsl(),但具有更广泛的色域。

还记得我说过 HSL “适合人类”吗?因为它比 RGB 更易于理解? 更改色相、饱和度和亮度在逻辑上很有意义。 lch() 中也是如此,我们有亮度色度色相。 回到我和 Eric Portis 的谈话

LCH 更像 HSL:一个极坐标空间。 H = 色相 = 一个圆。 因此,执行数学运算以选择互补色(或您想要的任何转换)变得微不足道(只需添加 180 度 - 或任何值!)。

我认为您会选择 LCH,仅仅是因为您喜欢它的语法,或者因为它使您尝试执行的一些复杂编程变得更轻松 - 并且您了解到它可以免费表达 50% 的更多颜色。

我们也获得了感知一致性。 这是 Lea Verou 的观点,她似乎很兴奋,因为亮度实际上会有意义

在 HSL 中,亮度没有意义。颜色可以具有相同的亮度值,但感知亮度却大不相同。[...] 使用 LCH,任何具有相同亮度的颜色在感知上都具有相同的亮度,而任何具有相同色度的颜色在感知上都具有相同的饱和度。

新模型的另一个好处是,我们可以摆脱 CSS 颜色渐变中的“灰色死区”。我认为由于这种感知一致性,两种丰富的颜色不会变得轻浮,并在非丰富区域进行渐变。

Two gradients going from blue to pink, one on top of the other. The first uses the LCH CSS color syntax and the second use HSL. HSL has noticeable gray areas.
颜色模型中总会存在权衡,尤其是对于渐变而言。(演示

以下是一个小小的个人预测:我认为 lch() 很可能会成为设计师的最爱。很快就会出现大量的新的颜色选择,而总是选择不同的颜色太过困难和奇怪。LCH 似乎在脑力上是最划算的。

资源

“好的”

LAB 及其朋友似乎非常新,因为它们对于 CSS 来说是新的...但 LAB 是在 1940 年代发明的。在与 Adam Argyle 的对话中,他用了一个令人难忘的短语:所有颜色空间都有一个致命弱点。也就是说,它们在某些方面有点糟糕。对于 sRGB 来说,就是灰色死区问题,以及有限的色域。LAB 很好,但它确实有自己的弱点。例如,LAB 中的蓝到白的渐变通过紫色区域时会非常不自然。

2020 年 12 月,Björn Ottosson 说了一句“嘿,一个新的颜色空间出现了,”现在 OKLAB 存在了。显然,CSS 的掌权者认为这个颜色空间有足够的价值,因此 oklab()oklch() 都已经在规范中。我想我们应该关心它们,因为它们普遍更好,但不要引用我的话。

为什么 Display P3 使用 color() 函数,而其他函数不使用?

我真的不知道。我认为 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 颜色空间。

但我真的无法想象。这让我头晕,抱歉。