color()

Baseline 2023
新推出

自 ⁨2023 年 5 月⁩起,此功能可在最新的设备和浏览器版本上使用。此功能可能无法在旧版设备或浏览器上使用。

color() 函数式表示法允许在一个特定的、指定的颜色空间中指定颜色,而不是大多数其他颜色函数所操作的隐式 sRGB 颜色空间。

可以使用 color-gamut CSS 媒体特性检测对特定颜色空间的支持。

语法

css
/* Absolute values */
color(display-p3 1 0.5 0);
color(display-p3 1 0.5 0 / .5);

/* Relative values */
color(from green srgb r g b / 0.5)
color(from #123456 xyz calc(x + 0.75) y calc(z - 0.35))

下面描述了绝对颜色和相对颜色的允许值。

绝对值语法

color(colorspace c1 c2 c3[ / A])

参数如下:

颜色空间

一个 <ident>,表示以下预定义颜色空间之一:srgbsrgb-lineardisplay-p3a98-rgbprophoto-rgbrec2020xyzxyz-d50xyz-d65

c1, c2, c3

每个值都可以写成 <number><percentage>,或关键字 none(在这种情况下等同于 0)。这些值表示颜色空间的组件值。使用 <number> 值时,通常 01 表示颜色空间的边界。允许超出该范围的值,但它们将超出给定颜色空间的色域。使用百分比值时,100% 表示 10% 表示 0

A 可选

一个 <alpha-value>,表示颜色的 alpha 通道值,其中数字 0 对应 0%(完全透明),1 对应 100%(完全不透明)。此外,关键字 none 可用于明确指定无 alpha 通道。如果未明确指定 A 通道值,则默认为 100%。如果包含该值,则其前面需要有一个斜杠(/)。

备注:有关 none 的效果,请参阅缺失的颜色分量

相对值语法

color(from <color> colorspace c1 c2 c3[ / A])

参数如下:

from <color>

在定义相对颜色时,总是包含关键字 from,其后跟着一个 <color> 值,表示源颜色。这是相对颜色所基于的原始颜色。源颜色可以是任何有效的 <color> 语法,包括另一个相对颜色。

颜色空间

一个 <ident>,表示输出颜色的颜色空间,通常是以下预定义颜色空间之一:srgbsrgb-lineardisplay-p3a98-rgbprophoto-rgbrec2020xyzxyz-d50xyz-d65

c1, c2, c3

每个值都可以写成 <number><percentage>,或关键字 none(在这种情况下等同于 0)。这些值表示输出颜色的组件值。使用 <number> 值时,通常 01 表示颜色空间的边界。允许超出该范围的值,但它们将超出给定颜色空间的色域。通常,使用百分比值时,100% 表示 10% 表示 0

A 可选

一个 <alpha-value>,表示输出颜色的 alpha 通道值,其中数字 0 对应 0%(完全透明),1 对应 100%(完全不透明)。此外,关键字 none 可用于明确指定无 alpha 通道。如果未明确指定 A 通道值,则默认为源颜色的 alpha 通道值。如果包含该值,则其前面需要有一个斜杠(/)。

定义相对颜色输出通道分量

color() 函数内部使用相对颜色语法时,浏览器会将原始颜色转换为指定颜色空间中的等效颜色(如果尚未指定)。颜色被定义为三个不同的颜色通道值加上一个 alpha 通道值 (alpha)。这些通道值在函数内部可用,用于定义输出颜色通道值。

  • 原始颜色的三个颜色通道值被解析为 <number>。对于预定义颜色空间,根据指定的颜色空间,这些值将是以下之一:

    • rgb:基于 RGB 的颜色空间 srgbsrgb-lineardisplay-p3a98-rgbprophoto-rgbrec2020 的颜色通道值。

    • xyz:基于 CIE XYZ 的颜色空间 xyzxyz-d50xyz-d65 的颜色通道值。

      注意:每个值通常在 01 之间,但如上所述,它们可能超出这些界限。

      注意:在带有基于 XYZ 颜色空间的 color() 函数中引用 rgb 值,在带有基于 RGB 颜色空间的 color() 函数中引用 xyz 值,或引用任何其他字符都是无效的。函数内部可用的原始颜色通道值必须与指定的颜色空间类型匹配。

  • alpha:颜色的透明度值,解析为介于 01(包括 01)之间的 <number>

在定义相对颜色时,输出颜色的不同通道可以用几种不同的方式表示。下面,我们将通过一些示例来说明这些方式。

下面前两个示例中,我们使用相对颜色语法。然而,第一个输出与原始颜色相同的颜色,第二个输出的颜色根本不基于原始颜色。它们并没有真正创建相对颜色!你不太可能在实际代码库中使用这些,而可能会直接使用绝对颜色值。我们包含了这些示例,作为学习相对 color() 语法的一个起点。

让我们从原始颜色 hsl(0 100% 50%)(等同于 red)开始。虽然你不太可能编写以下函数,因为它们输出与原始颜色相同的颜色,但这演示了如何将原始颜色通道值用作输出通道值:

css
color(from hsl(0 100% 50%) srgb r g b)
color(from hsl(0 100% 50%) xyz x y z)

这些函数的输出颜色分别为 color(srgb 1 0 0)color(xyz-d65 0.412426 0.212648 0.0193173)

接下来的函数对输出颜色通道值使用绝对值,输出与原始颜色完全不同的颜色:

css
color(from hsl(0 100% 50%) srgb 0.749938 0 0.609579)
/* Computed output color: color(srgb 0.749938 0 0.609579) */

color(from hsl(0 100% 50%) xyz 0.75 0.6554 0.1)
/* Computed output color: color(xyz-d65 0.75 0.6554 0.1 */

以下函数对输出颜色通道值使用两个原始颜色通道值(分别为 rb,以及 xy),但对另一个输出通道值(分别为 gz)使用新值,从而在每种情况下创建基于原始颜色的相对颜色:

css
color(from hsl(0 100% 50%) srgb r 1 b)
/* Computed output color: color(srgb 1 1 0) */

color(from hsl(0 100% 50%) xyz x y 0.5)
/* Computed output color: color(xyz-d65 0.412426 0.212648 0.5) */

注意:如上所述,如果输出颜色使用的颜色模型与原始颜色不同,则原始颜色会在后台转换为与输出颜色相同的模型,以便以兼容的方式表示(即使用相同的通道)。例如,在上述第一个例子中,hsl() 颜色 hsl(0 100% 50%) 转换为 color(srgb 1 0 0),在第二个例子中转换为 color(xyz 0.412426 0.212648 0.5)

在本节我们目前看到的示例中,源颜色和输出颜色的 alpha 通道都没有被明确指定。当未指定输出颜色的 alpha 通道时,它默认为与源颜色 alpha 通道相同的值。当未指定源颜色的 alpha 通道时(且它不是相对颜色),它默认为 1。因此,上述示例中的源和输出 alpha 通道值均为 1

让我们看一些指定源和输出 alpha 通道值的示例。第一个示例将输出 alpha 通道值指定为与源 alpha 通道值相同,而第二个示例则指定一个与源 alpha 通道值无关的不同输出 alpha 通道值。

css
color(from hsl(0 100% 50% / 0.8) srgb r g b / alpha)
/* Computed output color: color(srgb 1 0 0 / 0.8) */

color(from hsl(0 100% 50% / 0.8) xyz x y z / 0.5)
/* Computed output color: color(xyz-d65 0.412426 0.212648 0.0193173 / 0.5) */

以下示例使用 calc() 函数计算输出颜色的新通道值,这些值相对于原始颜色通道值:

css
color(from hsl(0 100% 50%) srgb calc(r - 0.4) calc(g + 0.1) calc(b + 0.6) / calc(alpha - 0.1))
/* Computed output color: color(srgb 0.6 0.1 0.6 / 0.9)  */

color(from hsl(0 100% 50%) xyz calc(x - 0.3) calc(y + 0.3) calc(z + 0.3) / calc(alpha - 0.1))
/* Computed output color: color(xyz-d65 0.112426 0.512648 0.319317 / 0.9) */

备注:因为源颜色通道值被解析为 <number> 值,所以在使用它们进行计算时,你必须给它们加上数字,即使在通道通常接受 <percentage><angle> 或其他值类型的情况下也是如此。例如,将 <percentage> 添加到 <number> 是行不通的。

正式语法

<color()> = 
color( [ from <color> ]? <colorspace-params> [ / [ <alpha-value> | none ] ]? )

<colorspace-params> =
<custom-params> |
<predefined-rgb-params> |
<xyz-params>

<alpha-value> =
<number> |
<percentage>

<custom-params> =
<dashed-ident> [ <number> | <percentage> | none ]+

<predefined-rgb-params> =
<predefined-rgb> [ <number> | <percentage> | none ]{3}

<xyz-params> =
<xyz-space> [ <number> | <percentage> | none ]{3}

<predefined-rgb> =
srgb |
srgb-linear |
display-p3 |
display-p3-linear |
a98-rgb |
prophoto-rgb |
rec2020 |
rec2100-pq |
rec2100-hlg |
rec2100-linear

<xyz-space> =
xyz |
xyz-d50 |
xyz-d65

示例

在 color() 中使用预定义颜色空间

以下示例展示了改变 color() 函数的亮度、a 轴和 b 轴值所产生的效果。

HTML

html
<div data-color="red-a98-rgb"></div>
<div data-color="red-prophoto-rgb"></div>
<div data-color="green-srgb-linear"></div>
<div data-color="green-display-p3"></div>
<div data-color="blue-rec2020"></div>
<div data-color="blue-srgb"></div>

CSS

css
[data-color="red-a98-rgb"] {
  background-color: color(a98-rgb 1 0 0);
}
[data-color="red-prophoto-rgb"] {
  background-color: color(prophoto-rgb 1 0 0);
}
[data-color="green-srgb-linear"] {
  background-color: color(srgb-linear 0 1 0);
}
[data-color="green-display-p3"] {
  background-color: color(display-p3 0 1 0);
}
[data-color="blue-rec2020"] {
  background-color: color(rec2020 0 0 1);
}
[data-color="blue-srgb"] {
  background-color: color(srgb 0 0 1);
}

结果

在 color() 中使用 xyz 颜色空间

以下示例展示了如何使用 xyz 颜色空间来指定颜色。

HTML

html
<div data-color="red"></div>
<div data-color="green"></div>
<div data-color="blue"></div>

CSS

css
[data-color="red"] {
  background-color: color(xyz 45 20 0);
}

[data-color="green"] {
  background-color: color(xyz-d50 0.3 80 0.3);
}

[data-color="blue"] {
  background-color: color(xyz-d65 5 0 50);
}

结果

在 color() 中使用 color-gamut 媒体查询

此示例展示了如何使用 color-gamut 媒体查询来检测对特定颜色空间的支持,并使用该颜色空间来指定颜色。

HTML

html
<div></div>
<div></div>
<div></div>

CSS

css
@media (color-gamut: p3) {
  div {
    background-color: color(display-p3 1 0 0);
  }
}

@media (color-gamut: srgb) {
  div:nth-child(2) {
    background-color: color(srgb 1 0 0);
  }
}

@media (color-gamut: rec2020) {
  div:nth-child(3) {
    background-color: color(rec2020 1 0 0);
  }
}

结果

在 color() 中使用相对颜色

此示例为三个 <div> 元素设置了不同的背景颜色。中间的元素使用了未经修改的 --base-color,而左右两边的元素则使用了该 --base-color 的提亮和变暗版本。

这些变体使用相对颜色定义 — --base-color 自定义属性被传递给 color() 函数,并且输出颜色的 gb 通道通过 calc() 函数进行修改,以达到所需的效果。亮化的颜色在这些通道上增加了 15%,而暗化的颜色则从这些通道上减去了 15%。

CSS

css
:root {
  --base-color: orange;
}

#one {
  background-color: color(
    from var(--base-color) display-p3 r calc(g + 0.15) calc(b + 0.15)
  );
}

#two {
  background-color: var(--base-color);
}

#three {
  background-color: color(
    from var(--base-color) display-p3 r calc(g - 0.15) calc(b - 0.15)
  );
}

/* Use @supports to add in support old syntax that requires r g b values
   to be specified as percentages (with units) in calculations.
   This is required for Safari 16.4+ */
@supports (color: color(from red display-p3 r g calc(b + 30%))) {
  #one {
    background-color: color(
      from var(--base-color) display-p3 r calc(g + 15%) calc(b + 15%)
    );
  }

  #three {
    background-color: color(
      from var(--base-color) display-p3 r calc(g - 15%) calc(b - 15%)
    );
  }
}

结果

输出如下:

规范

规范
CSS 颜色模块第五版
# 颜色函数
CSS 颜色模块第五版
# 相对颜色函数
CSS 颜色模块第四版
# 颜色函数

浏览器兼容性

另见