CSS color functions, gradients, color spaces title. What's new in  CSS Colors Module Level 4 subtitle. A vibrant gradient behind artwork of a laptop and keyboard

CSS 颜色(级别 4)中的新函数、渐变和色调

作者头像Brian Smith阅读时间:10 分钟

越来越多的浏览器开始支持 CSS 颜色模块级别 4 规范中定义的功能,该规范包含多种在 CSS 中操作和显示颜色方法。让我们看一下颜色空间、如何在 CSS 中定义颜色、CSS 颜色模块级别 4 中的新增内容以及如何在项目中使用颜色函数和功能。

了解颜色空间

为了理解 CSS 中如何描述颜色,快速了解颜色空间将有所帮助。颜色空间是一个系统,用于根据定义的 颜色模型 对颜色进行分组。颜色空间提供了一种清晰一致的方式来描述颜色,并提供了一种将颜色转换为不同颜色空间的方法,同时仍然保持相同的视觉效果。

在 CSS 颜色模块级别 4 之前,CSS 中的颜色是在 RGB(指红色、绿色和蓝色)颜色空间和 色域(颜色的总范围)中定义的。

A cube representing the RGB color space with red, green, and blue at the corners

随着 HSL(指色调、饱和度和亮度)支持添加到 CSS 中,您可以使用与 RGB 模型相同的模型来定义颜色,但使用色调、饱和度和亮度。我们将在下一节中详细介绍 RGB 和 HSL。

在 CSS 中定义 RGB 颜色

要在 RGB 颜色空间中创建颜色,您可以以不同的方式混合红色、绿色和蓝色三种原色,以获得所需的色调。您可以将其视为立方体中一个点的坐标,其中每个轴代表一种原色。

css
.red {
  color: rgb(255 0 0);
}
.green {
  color: rgb(0 255 0);
}
.blue {
  color: rgb(0 0 255);
}
/* yellow is a mix of red and green */
.yellow {
  color: rgb(255 255 0);
}
/* cyan is a mix of green and blue */
.cyan {
  color: rgb(0 255 255);
}

要在 CSS 中定义 RGB 颜色,您可以选择使用颜色关键字(例如 redblue)、十六进制值(#ff0000)或 rgb() 函数 来定义红色、绿色和蓝色值,如以上示例所示。

截至 CSS 颜色模块级别 4,您不再需要使用 rgba() 来定义具有 alpha 通道的 RGB 颜色,因为 rgb() 支持使用斜杠 (/) 分隔的 alpha 值,如以下示例所示。此示例演示了如何使用关键字、十六进制值和 rgb() 函数定义相同的颜色,包括定义不透明度的示例。

css
.named-color {
  color: red;
}
.hex-color {
  color: #ff0000;
}
.rgb-color {
  color: rgb(255 0 0);
}
/* makes the color 50% transparent */
.rgba-semi-transparent {
  color: rgb(255 0 0 / 0.5);
}

使用 HSL 选择色调

在 CSS 颜色(级别 3)中添加 HSL 对许多开发者来说是一个受欢迎的特性,因为基于 色轮 来选择色调更直观。我们可以使用 conic-gradient() 函数和 hsl() 函数来制作色轮。制作此渐变在所有色调中循环的技巧在下面的 色调插值 部分中进行了描述。

css
#color-wheel {
  border-radius: 50%;
  background: conic-gradient(
    in hsl longer hue,
    hsl(0deg 100% 50%),
    hsl(360deg 100% 50%)
  );
}
/* For browsers that don't support hue interpolation methods */
@supports not (background: conic-gradient(in hsl longer hue)) {
  #color-wheel {
    background: conic-gradient(red, yellow, green, cyan, blue, magenta, red);
  }
}
html
<div id="color-wheel"></div>

如果我们将这两个代码片段组合在一起,就可以制作出一个在 RGB 颜色空间中所有可用色调中循环的色轮。

hsl() 函数的工作方式类似于 rgb() 函数,但接受色调作为色轮上的角度,以及饱和度和亮度作为值。与 rgb() 一样,您可以将 alpha 通道(用于透明度或不透明度)添加到 hsl() 中,这使得 hsla() 成为一个与 rgba() 相同的遗留函数。

css
.red-hsl {
  color: hsl(0 100% 50%);
}
.green-hsl {
  color: hsl(120 100% 50%);
}
/* Make the color 50% opaque */
.green-hsl {
  color: hsl(120 100% 50% / 0.5);
}

HSL 函数的另一个便利之处在于,您可以通过更改饱和度和亮度来制作颜色的变体,而不是尝试计算 RGB 值。例如,如果您为网站主题选择了特定的颜色,则可以修改该颜色的饱和度和亮度以创建仍然适合该主题的辅助颜色。这将在下面进行说明。

css
.button {
  color: hsl(200 100% 70%);
}
/* A darker version of the button color */
.button--secondary {
  color: hsl(200 100% 50%);
}
/* Lower saturation makes the button less vibrant */
.button--inactive {
  color: hsl(200 50% 70%);
}

CSS 颜色模块级别 4 中有哪些新内容?

此规范版本添加了许多新的颜色函数,这些函数使用不同的颜色表示方式,它们都允许您使用色调、亮度和饱和度等属性来指定颜色。新的颜色函数使您可以使用更鲜艳的颜色,这些颜色超出了 RGB 色域,因此在支持的显示器上可以获得更广泛的颜色范围。

支持更多颜色空间和色域

随着对更多空间和色域的支持,您不再局限于在 RGB 颜色空间中描述颜色;现在您可以使用 Display P3、CIELAB、Oklab 颜色空间。让我们快速了解一下这一切意味着什么。

Display P3 使用 P3 色域,它表示的颜色范围比 sRGB(标准 RGB)更广。它对于现代显示器中使用的更鲜艳的颜色很有用。但是,您需要注意为不支持该功能的设备的用户提供备用方案。

CIELAB 是一个均匀颜色空间 (UCS),它根据人眼感知颜色来定义颜色。此模型的主要目的是让颜色空间中两个点之间的相同颜色距离对观察者来说看起来同样不同。

Oklab 是一个较新的颜色空间,它使用与 CIELAB 相同的模型结构,但它是通过“对视觉上相似的颜色数据集进行数值优化”创建的,因此这些值旨在比 CIELAB 更准确。

与色轮、圆柱体或立方体不同,CIELAB 和 Oklab 颜色空间可以用三维空间来表示,看起来像这样。

A three-dimensional representation of the CIELAB color space with points showing the location of some colors in the space.

颜色新的函数表示法

新的颜色函数有助于描述我们在上一节中看到的颜色空间中的值。让我们看一下每个新的函数及其工作原理。

lab() 函数表示法使用亮度、红/绿度和黄/蓝度来描述 CIELAB 颜色,这些值位于颜色空间中的“a”轴和“b”轴上。

css
.lab-red {
  color: lab(87.6 125 104);
}
.lab-green {
  color: lab(87.8 -79 81);
}

lch() 函数表示法使用亮度、彩度和色调来描述 CIELAB 颜色。色调是色轮上表示颜色的角度。

css
.lch-red {
  color: lch(54.3 107 40.9deg);
}
.lch-green {
  color: lch(87.8 113 134deg);
}

oklab() 函数表示法使用亮度、红/绿度和黄/蓝度来描述 Oklab 颜色,这些值位于 Oklab 颜色空间中的“a”轴和“b”轴上。

css
.oklab-red {
  color: oklab(0.63 0.22 0.13);
}
.oklab-green {
  color: oklab(0.87 -0.2 0.18);
}

oklch() 函数表示法使用亮度、彩度和色调来描述 Oklab 颜色。

css
.oklch-red {
  color: oklch(0.93 0.39 28deg);
}
.oklch-green {
  color: oklch(0.87 0.29 142deg);
}

除了新的颜色空间之外,还有一个 hwb() 函数表示法用于 HWB 颜色,这些颜色使用色调、白度和黑度来定义。HWB 使用 RGB 颜色空间,与 HSL 类似,但考虑白度和黑度而不是饱和度和亮度。

css
.hwb-red {
  color: hwb(0deg 0% 0%);
}
.hwb-light-red {
  color: hwb(0deg 30% 0%);
}
.hwb-dark-red {
  color: hwb(0deg 0% 30%);
}
/* Cycle through the color wheel */
.hwb-green {
  color: hwb(120deg 0% 0%);
}
.hwb-blue {
  color: hwb(240deg 0% 0%);
}

最后,还有一个 color() 函数表示法,允许您在预定义的颜色空间中指定颜色。

css
.green-display-p3 {
  color: color(display-p3 0 1 0);
}
.blue-rec2020 {
  color: color(rec2020 0 0 1);
}
.blue-srgb {
  color: color(srgb 0 0 1);
}

您还可以将 color() 函数表示法与媒体查询结合使用,以指定备用颜色空间。

css
.green-display-p3 {
  color: color(display-p3 0 1 0);
}
@media (color-gamut: srgb) {
  .green-display-p3 {
    color: color(srgb 0 1 0);
  }
}

颜色函数的语法更改

rgb()hsl() 函数的语法已更改,目的是使其更容易使用。分隔值的逗号不再是必需的,您可以使用斜杠来为颜色指定 alpha 值。

css
/* old syntax */
rgb(255, 0, 0);
hsl(0, 100%, 50%);

/* new syntax */
rgb(255 0 0);
hsl(0 100% 50%);

/* new syntax with alpha channels */
rgb(255 0 0 / 0.5);
hsl(0 100% 50% / 0.5);

所有新的函数都使用以上类型的语法,值之间没有分隔逗号,并且使用斜杠将 alpha 通道与颜色值分隔开。

色调插值

借助新的颜色空间,其中一项不涉及深入研究颜色科学的优势是用于创建渐变。插值是指在两个已知值之间计算一个或多个值,因此,如果您有一个从红色到蓝色的渐变,那么插值就是您计算红色和蓝色之间的范围内哪些颜色的一种方式。在创建 linear-gradient() 或类似的 CSS 渐变时,您可以使用 in(用于插值),后跟渐变的颜色空间。

css
.hsl {
  background: linear-gradient(in hsl, blue, red);
}

比较不同颜色空间中的渐变

我们可以创建一个快速示例来比较不同颜色空间中的渐变。在下面的示例中,我们在标准 RGB 颜色空间中有一个从蓝色到红色的渐变,然后我们在不同的颜色空间中使用了相同的渐变。

css
.rgb {
  background: linear-gradient(to right, blue, red);
}

.hsl {
  background: linear-gradient(in hsl to right, blue, red);
}

.lch {
  background: linear-gradient(in lch to right, blue, red);
}

.lab {
  background: linear-gradient(in lab to right, blue, red);
}

.oklch {
  background: linear-gradient(in oklch to right, blue, red);
}

.oklab {
  background: linear-gradient(in oklab to right, blue, red);
}

这让我们很好地了解了渐变在不同颜色空间中的外观以及插值在每个颜色空间中的工作方式。

在渐变中使用色调插值模式

有一些 插值模式 可以控制在具有色调角度的颜色空间中,色调应在色轮上插值的哪个方向。

html
<div class="hsl in-function">
  <p>HSL</p>
</div>
<div class="hsl-named in-function">
  <p>HSL named</p>
</div>

<div class="hsl-longer in-function">
  <p>HSL (longer)</p>
</div>
<div class="hsl-named-longer in-function">
  <p>HSL named (longer)</p>
</div>

<div class="fallback">
  <p>Standard fallback</p>
</div>
css
/* From 39deg to 60deg, taking the shortest path around the color wheel */
.hsl {
  background: linear-gradient(
    to right in hsl,
    hsl(39deg 100% 50%),
    hsl(60deg 100% 50%)
  );
}
/* We can also use named colors */
.hsl-named {
  background: linear-gradient(to right in hsl, orange, yellow);
}

/* This gradient cycles back through 0deg around the color wheel */
.hsl-longer {
  background: linear-gradient(
    to right in hsl longer hue,
    hsl(39deg 100% 50%),
    hsl(60deg 100% 50%)
  );
}

/* The same effect can be achieved with named colors */
.hsl-named-longer {
  background: linear-gradient(to right in hsl longer hue, orange, yellow);
}

/* For browsers that don't support interpolation modes */
.fallback {
  background: linear-gradient(to right, blue, red);
}

浏览器支持

CSS 颜色模块级别 4 中描述的大多数语法在 Chrome 和 Safari 的最新版本中得到支持,对颜色函数的支持将在 Firefox 113 中发布。以上示例中指定颜色空间和插值模式的线性渐变在 Chrome 和 Safari 中得到支持,但在 Firefox 中尚未支持。您可以查看 MDN <color> 页面,以获取本文中介绍的其他功能的浏览器兼容性数据。

总结

以下是本文中介绍的所有内容的重点摘要。

  • 对于 RGB 颜色空间,hwb() 函数表示法允许您使用色调、白度和黑度来指定颜色。
  • 对于 CIELAB 颜色空间,您可以使用 lab()lch() 函数表示法。
  • 对于 Oklab(类似于 CIELAB 颜色空间,但更新了数据),您可以使用 oklab()oklch() 函数表示法。
  • 对于那些想要深入了解不同颜色空间的人来说,color() 允许您使用 color(srgb) 来表示标准 RGB,以及使用 color(display-p3) 来表示广色域显示器中使用的 Display P3。还有一些其他颜色空间适合专业人士使用,例如摄影师、视频专业人员和颜色科学研究人员。
    • color(rec2020): Rec2020 广播行业标准颜色空间
    • color(prophoto-rgb): 摄影师使用的 ProPhoto RGB 颜色空间
    • color(a98-rgb): Adobe RGB 颜色空间
    • color(xyz): CIE XYZ 颜色空间,其轴使用线性光强度来更好地预测颜色混合
    • color(srgb-linear): 线性化的 sRGB 颜色空间

下一步

CSS 颜色模块级别 5 描述了一个 color-mix() 函数式符号,它允许您使用指定的权重混合两种颜色。此函数已在多个浏览器中得到支持,因此您可以立即开始尝试使用它,但值得关注 MDN color-mix() 页面 以了解浏览器兼容性数据。在 color() 函数中,您可以使用使用 color(--my-color-space 0 0 0) 定义的自定义颜色空间,这些颜色空间是从使用 @color-profile 规则的外部文件加载的。

css
.plum-pink-mix {
  color: color-mix(in lch, plum, pink);
}

/* Custom color space */
@color-profile --example-color-space {
  src: url("https://example.org/my-color-profile.icc");
}
.header {
  background-color: color(--example-color-space 10% 20% 30%);
}

有用资源

关注 MDN 的最新资讯

订阅 MDN 新闻简报,不错过有关最新 Web 开发趋势、技巧和最佳实践的任何更新。