CSS 颜色模块 第5级

W3C 工作草案

更多关于该文档的信息
此版本:
https://www.w3.org/TR/2026/WD-css-color-5-20260113/
最新发布版本:
https://www.w3.org/TR/css-color-5/
编辑草案:
https://drafts.csswg.org/css-color-5/
先前版本:
历史:
https://www.w3.org/standards/history/css-color-5/
反馈:
CSSWG 问题库
编辑:
Chris Lilley (W3C)
Una Kravets (Google)
Lea Verou (特邀专家)
前任编辑:
Adam Argyle (Google)
为此规范建议编辑:
GitHub 编辑器
差异规范:
测试套件:
https://wpt.fyi/results/css/css-color/

摘要

此模块扩展了 CSS 颜色[css-color-4],以添加颜色修改函数、自定义颜色空间 (ICC 配置文件)、contrast-color()、light-dark() 和 device-cmyk()。

CSS 是一种用于描述结构化文档(例如 HTML 和 XML)在屏幕、纸张等媒介上渲染的语言。

本文档状态

本节描述本文件在发布时的状态。 当前 W3C 出版物列表 以及本技术报告的最新修订版 可在 W3C 标准和草案索引中查阅。

本文件由CSS 工作组作为工作草案 按照 推荐流程发布。 作为工作草案发布 并不意味着 W3C 及其成员的认可。

本文件为草案, 可能随时被更新、替换 或被其他文件废止。 此文件不应被引用为除“进行中的工作”之外的任何用途。

请通过在 GitHub 提交 issue(首选) 反馈意见,标题中请包含规范代码 “css-color”,格式如下: “[css-color] …评论摘要内容…”。 所有问题和评论均已存档。 另外,也可通过(已存档)公共邮件列表www-style@w3.org反馈。

本文件受2025年8月18日 W3C 流程文件管理。

本文件由遵循W3C 专利政策的组织产生。 W3C 维护着与本组成果相关的专利披露公开列表; 该页面同时包含专利披露的说明。 个人如实际知晓某专利并认为 包含核心声明 必须根据W3C 专利政策第6节披露相关信息。

1. 简介

本节内容不具有规范性。

此模块添加了新函数 contrast-color()color-mix()light-dark(), 并使用相对颜色语法扩展了现有函数。

它还扩展了 color() 函数, 以便不仅可以使用预定义的颜色空间, 还可以使用由 ICC 配置文件定义的自定义颜色空间 (包括校准的 CMYK) 在 CSS 中。

它还添加了 device-cmyk, 一种未校准 cmyk 颜色的表示形式。

2. <color> 语法

CSS中的颜色由 <color> 类型表示:

<color> = <color-base> | currentColor | <system-color> | 
      <contrast-color()> | <device-cmyk()>  | <light-dark()>

<color-base> = <hex-color> | <color-function> | <named-color> | <color-mix()> | transparent
<color-function> = <rgb()> | <rgba()> |
              <hsl()> | <hsla()> | <hwb()> |
              <lab()> | <lch()> | <oklab()> | <oklch()> |
              <alpha()> |
              <color()>

绝对颜色 是一个 <color> 其计算值具有绝对的色度解释。 这意味着该值不包括:

这些值也不能在 <color-mix()> 或相对颜色语法中使用。

解析为 sRGB 的颜色包括:

支持传统颜色语法的函数有:

<hsl()><hsla()><hwb()><lch()> 以及 <oklch()> 颜色函数 都是采用圆柱极坐标颜色表示方式,并使用 <色相> 角度; 其他颜色函数则采用矩形正交颜色表示方式。

3. 混合颜色:color-mix() 函数

Web 开发人员、设计工具和设计系统开发人员经常使用颜色函数来辅助扩展其组件颜色关系的设计。 随着支持多平台和多种用户偏好(例如 UI 中深色模式功能的增强)的设计系统的使用日益增多, 这种无需手动设置颜色,而是通过单一来源计算配色方案的方式变得更加有用。

LCH 颜色选择器
美国等值区域图

上图为一个在 CIE LCH 空间中操作的颜色选择器。 此处,一对颜色被用于在色度-亮度平面(色相恒定)上定义一个色阶。 下图为在等值区域图上使用的该色阶。

目前,Sass、HSL 值上的 calc() 或 PostCSS 被用于实现此目的。 然而,预处理器无法处理动态调整的颜色; 所有当前的解决方案都局限于 sRGB 色域以及 HSL 的感知局限性 (颜色在色轮中聚集在一起, 并且两种视觉上亮度不同的颜色, 例如黄色和蓝色,可能具有相同的 HSL 亮度)。

为了满足这个需求,color-mix() 函数接收一个或多个 <color> 规格的列表,并返回它们在指定 <color-space> 中,以指定比例混合的结果。

color-mix() = color-mix( <color-interpolation-method>? , [ <color> && <percentage [0,100]>? ]#)
测试

3.1. 用于混合的颜色空间

如果没有指定颜色插值方法,则假定为 Oklab。 否则,使用指定的颜色空间进行混合。

3.2. 百分比归一化

百分比需要在 0% 到 100% 的范围内。 明确禁止使用负百分比。 百分比通过归一化混合百分比进行归一化。

测试
这些语法形式都是等效的:
color-mix(in lch, purple 50%, plum 50%)
color-mix(in lch, purple 50%, plum)
color-mix(in lch, purple, plum 50%)
color-mix(in lch, purple, plum)
color-mix(in lch, plum, purple)
color-mix(in lch, purple 80%, plum 80%)

所有这些都会生成 purple 和 plum 的 50-50 混合, 在 lch 中: lch(51.51% 52.21 325.8) 即 rgb(68.51% 36.01% 68.29%)。

然而,这种形式 不是 一样的,因为 alpha 小于 1:

color-mix(in lch, purple 30%, plum 30%)

这会生成 lch(51.51% 52.21 325.8 / 0.6) 即 rgb(68.51% 36.01% 68.29% / 0.6)。

3.3. 计算 color-mix 的结果

计算 color-mix()
  1. 对传递给函数的混合项列表进行混合百分比归一化, 并将“强制归一化”标志设置为 true, 得到 itemsleftover

  2. 如果 leftover 为 100%, 则返回透明黑, 并转换为指定的插值<color-space>

  3. alpha mult1 - leftover, 其中 leftover 按 0 到 1 的数字解释。

  4. 如果 items 长度为 1, 则将 color 设为该唯一项的颜色, 并转换为指定插值<color-space>

    否则:

    1. item stack 为将 items 反转后得到的堆栈。 (因此,第一个 item 在堆栈顶部。)

    2. item stack 长度大于等于 2 时:

      1. item stack弹出两次, 分别得到 ab。 令 combined percentageab 的百分比之和。

      2. CSS Color 4 § 12. 颜色插值的描述, 以进度百分比 (b 的百分比) / combined percentage 插值 ab 的颜色。 如果指定的颜色空间是圆柱极坐标颜色空间, 那么<hue-interpolation-method> 控制色相的插值,详见CSS Color 4 § 12.4 色相插值。 如果未指定 <hue-interpolation-method>, 则默认为 shorter

      3. 用结果颜色和 combined percentage, 创建一个新的混合项, 并压入item stack

    3. color 设为 item stack 中唯一剩下的项的颜色。

  5. color 的 alpha 分量乘以 alpha mult

  6. 返回 color

注意:圆柱极坐标颜色空间中, 混合顺序是有依赖的, 因为“shorter”或“longer”的方向可能随着已执行的混合而改变。 此算法依照指定顺序依次混合每个颜色, 用前一次的结果与下一个颜色混合。 对于矩形正交颜色空间, 混合顺序无影响, 可简化操作。

测试
此示例生成 40% peru 和 60% palegoldenrod 的混合。
color-mix(in lch, peru 40%, palegoldenrod)

混合是在 lch 颜色空间中进行的。 这是一个俯视图,沿着中性 L 轴观察:

两个颜色的混合及混合输出。我们沿着 CIE L 轴观察 ab 平面。有两个轴,标记为 a 和 b,它们在原点交叉,该原点位于图的中心。
peru 和 palegoldenrod 在 CIE LCH 中的混合。 Peru 的色相角从正 a 轴测量,为 63.677 度, 而 palegoldenrod 的色相角为 98.834 度。 Peru 的色度或离中心中性轴的距离为 54.011, 而 palegoldenrod 的色度为 31.406。 所有可能的混合都位于曲线沿线。显示了 40%/60% 的混合。

计算如下:

此示例在 lch 颜色空间中生成青色和橄榄色的混合色, 其中每个 lch 分量为青色值的 65% 和橄榄色值的 35%。

注意:对色相和色度进行插值 使中间颜色的饱和度 与终点颜色一样饱和。

color-mix(in lch, teal 65%, olive);
两个颜色的混合及混合输出。 我们沿着 CIE L 轴观察 ab 平面。 有两个轴,标记为 a 和 b,它们在原点交叉,该原点位于图的中心。
teal 和 olive 的混合。 Teal 的色相角从正 a 轴测量,为 196.4524 度, 而 olive 的色相角为 99.5746 度。 Teal 的色度或离中心中性轴的距离为 31.6903, 而 olive 的色度为 56.8124。 混合位于虚线曲线沿线。显示了 65%/35% 的混合。

计算如下:

在本例中,两个百分比都为零,因此它们的总和也是零:
color-mix(in oklch, teal 0%, olive 0%);

因此,结果是在oklch颜色空间中的透明黑:
oklch(0% 0 none / 0)

3.4. 混合色彩空间对 color-mix 的影响

选择的混合颜色空间会对最终结果产生很大影响。

该示例是白色和黑色的 50% 混合, 在三个不同的颜色空间中。
color-mix(in lch, white, black);
color-mix(in xyz, white, black);
color-mix(in srgb, white, black);

计算如下:

LCH 中的混合给出 L 值为 50%, 一个完美的中灰,完全符合预期 (在 Lab 中混合也会产生相同的结果, 因为 LCH 和 Lab 的亮度轴是相同的)。

XYZ 中的混合结果过亮; XYZ 是线性光,但不是感知一致的。 sRGB 中的混合结果也稍微过亮; sRGB 既不是感知一致的,也不是线性光。

该示例生成 红色和天蓝色的混合, 在 xyz 颜色空间中, 混合结果为 75.23% 红色的值 (因此,24.77% 是天蓝色的值)。
color-mix(in xyz, rgb(82.02% 30.21% 35.02%) 75.23%, rgb(5.64% 55.94% 85.31%));

计算如下:

该示例是白色和蓝色的 50% 混合, 在三个不同的颜色空间中。

color-mix(in lch, white, blue);
color-mix(in oklch, white, blue);
color-mix(in srgb, white, blue);

计算如下:

该示例是两个颜色的混合, 在 hsl 颜色空间中, 其中一个颜色 超出了 sRGB 色域。
color-mix(in hsl, color(display-p3 0 1 0) 80%, yellow);

计算如下:

device-cmyk() 可以用于 color-mix(),但结果将取决于实现选择如何获得计算值。
color-mix(in lab, device-cmyk(0.091777 0.043303 0.312816 0.000000) 100%, yellow);

由于第一个颜色为100%,第二个颜色为0%,因此不会对混合结果产生任何影响。结果就是第一个颜色在CIE Lab中的计算值。

为了可视化结果,假设device CMYK值实际上将用SWOP 2006 coated进行打印。

假设实现使用ICC配置文件来获得lab()色值,在本例中使用FOGRA39 Coated配置文件:

现在假设另一个实现采用了简单的色彩转换算法,给出sRGB结果。

3.5. 非1透明度下 color-mix 的影响

到目前为止,所有 color-mix() 示例 都使用了完全不透明的颜色。 为了让例子简明, 预乘和反预乘步骤被省略, 因为此时实际上是乘以1再除以1, 故结果不会改变。

在通用情况下, 颜色分量可能不是1的alpha, 因此预乘、插值、反预乘这些步骤都不能省略。

这个例子是25%半透明红和75%半透明绿, 在sRGB中混合。 同时展示了正确(预乘)与错误(非预乘)的过程。
color-mix(in srgb, rgb(100% 0% 0% / 0.7) 25%, rgb(0% 100% 0% / 0.2));

计算如下:

错误的计算如下:

这是一个巨大的差别;正确和错误结果的ΔE2000为30.7!

当百分比归一化产生alpha乘数时,计算相同,最后多一步。

这个例子与上例类似, 25%半透明红和75%半透明绿, 在sRGB中混合。

但本例中百分比被设为第一个颜色20%、第二个颜色60%,总和为80%,所以alpha乘数为0.8。

混合百分比随后以100/80缩放:
20% * 100/80 = 25%
60% * 100/80 = 75%
得到和前例一样的最终混合比例。

color-mix(in srgb, rgb(100% 0% 0% / 0.7) 20%, rgb(0% 100% 0% / 0.2) 60%);

计算如下:

注意: 不要将插值后的 alpha 乘以 alpha 乘数然后再用于解乘。 如果混合百分比未缩放为 100%,这样做是正确的, 但实际上它们已缩放,因此这样做会使混合颜色调整两次。

4. 相对颜色

4.1. 相对颜色的处理模型

在本规范的先前级别中, 颜色函数只能以绝对方式指定颜色, 即直接指定所有颜色分量。

新的 相对颜色 语法 扩展了 现代颜色语法,允许通过颜色函数修改已有颜色: 如果指定了一个 原始颜色, 那么每个颜色分量 (以及 alpha 分量,如有指定) 可以直接指定, 或者取自原始颜色 (并可用 数学函数进行修改)。

原始颜色与相对颜色无需使用同一个颜色函数。

所需转换: 所有操作都在 相对颜色函数的颜色空间中进行; 如果原先指定的颜色空间原始颜色 使用了不同的颜色函数, 则需先将其转换为目标颜色函数, 以便各分量有意义的值, 且 分量关键字 指代的是相对颜色的颜色空间,而不是 原始颜色

如果相对颜色的 alpha 值被省略, 则默认为 原始颜色 的 alpha(而不是像绝对语法那样默认为 100%)。

当使用相对颜色语法时,颜色分量值,无论直接指定还是由颜色空间转换得到, 不会钳制到参考范围,而是保持原样。 这可以保留超出色域的值, 如果目标颜色空间能够表示这些值的话。

但是当使用相对颜色语法时,alpha 分量无论是直接指定 还是由颜色空间转换得到,都会被钳制到参考范围。

遗漏的分量处理方式同 CSS Color 4 § 12.2 缺失分量的插值: 会检查原始颜色空间和相对函数颜色空间中是否有 对应分量,然后将这些分量向前带入作为缺项。

虽然大多数 相对颜色语法的用法 都会在各自参数中使用 分量关键字, 但你也可以在任意位置使用它们。

在分量不在常规位置时需注意; 当百分比被解析为数字时, 不会有“自动缩放”来适应新的分量位置, 如果这些数字被用于不同位置。

没有相对 device-cmyk() 语法。

4.2. 相对颜色语法

下面列出了每个函数为适应相对颜色而进行的语法更改的精确细节, 但它们都遵循一个共同的结构:

分量关键字返回一个<number>,或 none; 如果它们最初被指定为<percentage><angle>, 则该<percentage> 将解析为<number>,并且该<angle> 将解析为范围 [0, 360] 内的度数<number>(这是规范单位)。

测试
例如,如果颜色是用 <percentage>指定的, 则在相同颜色空间中的 RCS 将使用解析后的 <number>形式:
html { --bluegreen:  oklab(54.3% -22.5% -5%); }
.overlay {
  background:  oklab(from var(--bluegreen) calc(1.0 - l) calc(a * 0.8) b);
}

在这个示例中,指定的百分比被解析为数值, 生成 oklab(0.543 -0.09 -0.02)。 结果颜色是 l = 1 - 0.543 = 0.457, a = -0.09 * 0.8 = -0.072, b 不变为 -0.02: oklab(0.457 -0.072 -0.02)。

例如,如果原始颜色的色调 <angle>以度数指定, 则相同颜色空间中的 RCS 将使用解析后的 <number>形式:
html { --base:  oklch(52.6% 0.115 44.6deg) }
.summary {
  background:  oklch(from var(--base) l c  calc(h + 90));
}

在这个示例中,结果颜色是 oklch(0.526 0.115 134.6)。

如果原始颜色的色调<angle>以其他单位指定, 如弧度或转数, 解析后得到的仍然是度数形式 <number>

通过在数学函数中使用组件关键字, 可以更高级地操作原始颜色
html { --color: green; }
.foo {
    --darker-accent: lch(from var(--color) calc(l / 2) c h);
}

在此示例中,通过将其亮度减半来使原始颜色变暗, 而不改变颜色的任何其他方面。

另请注意,原始颜色是一个颜色关键字 (因此是 sRGB), 但由于在 lch() 函数中使用,它会自动解释为 LCH 颜色。

例如,如果主题颜色指定为不透明, 但在特定情况下您需要它部分透明:
html { --bg-color:  blue; }
.overlay {
    background:  rgb(from var(--bg-color) r g b / 80%);
}

在此示例中,原始颜色的 r、g 和 b 分量保持不变, 通过使用从原始颜色中获取其值的关键字来指定它们, 但将不透明度设置为 80% 以使其略微透明, 而不管原始颜色的不透明度如何。

例如,一个超出 sRGB 色域的 Display P3 颜色 仍然可以表示, 因为它没有被裁剪。
--vivid-yellow:  color(display-p3 1 1 0);
--paler-yellow:  color(from var(--vivid-yellow) srgb r g calc(b + 0.5));

此处 --vivid-yellow 转换为 sRGB 后, 是 rgb(100% 100% -34.63%) 并且负蓝色分量未被裁剪。 RCS 计算的结果是 rgb(100% 100% 15.37%)

例如,尝试将原始颜色中 0.7 的 alpha 值加倍 会导致结果中的 alpha 值为 1,而不是 1.4。
--tan:  oklch(78% 0.06 75 / 0.7);
--deeper-tan:  oklch(from var(--tan) l c h / calc(alpha * 2));
例如,对颜色进行粗略的灰度处理:
--blue-into-gray: rgb(from var(--color)
                    calc(r * .3 + g * .59 + b * .11)
                    calc(r * .3 + g * .59 + b * .11)
                    calc(r * .3 + g * .59 + b * .11));

使用此方法,红色 将变为 rgb(76.5 76.5 76.5)石灰色 将变为 rgb(150.45 150.45 150.45), 而蓝色将变为 rgb(150.45 150.45 150.45)。 像深橄榄绿色这样更温和的颜色, 其 RGB 值为 rgb(85 107 47), 将变为 rgb(93.8 93.8 93.8)

(粗略是因为首先, 虽然这看起来像亮度计算, 但红、绿和蓝值是在伽马编码空间中操作的, 而不是线性光空间; 其次, 权重因子是用于已过时的 NTSC 颜色空间的, 而不是 sRGB。)

(另请注意,这只是为了说明语法; 一种更简单、更准确的灰度处理颜色的方法是使用 oklch() 函数, 因为该颜色空间对人类感知更准确:oklch(from var(--color) l 0 h) 保留亮度, 但将色度(决定颜色“鲜艳”程度的因素)归零。)

例如,

color: color(from color(srgb 0 0 0 / 60%) srgb alpha 0.6 0.6 / 0.9);

alpha 分量解析为<number>, 得到 0.6;因此结果颜色为 color(srgb 0.6 0.6 0.6 / 0.9)

然而,在第二个示例中,alpha 再次解析为 0.6, 由于 rgb() 语法中颜色分量范围为 0 到 255,因此会产生截然不同的颜色:

color: rgb(from rgb(0 0 0 / 60%) alpha 153 153 / 0.9);

结果为 rgb(0.6 153 153 / 0.9)不是 rgb(153 153 153 / 0.9)

在此示例中,消色差原始颜色缺少色相; 相对颜色也缺少色相, 这会影响使用该颜色的渐变。
html { --bg:  hsl(none 3% 50%); }
.foo {
    --darker-bg:  oklch(from var(--bg) calc(l * 0.8) c h);
}
.bar {
    background: linear-gradient(in Oklab to right,   var(--darker-bg),   #4C3);
}

--bg 转换为 OkLCh 后的值为 oklch(0.592 0.009 17.42) 但相似的色相分量被沿用 得到 oklch(0.592 0.009 none)。 然后这些值在相对函数中使用,得到 较暗的颜色 oklch(0.474 0.009 none)。

渐变中的浅绿色是 oklch(0.743 0.222 141.6), 因此,在插值时,另一种颜色采用该色相, 变为 oklch(0.474 0.009 141.6)。

因此,渐变将具有恒定的绿色色调。

如果实现未能执行此沿用操作, 灰色的 --darker-bg 将具有 0 的色相, 从而在渐变开始时产生不希望的微红色调。

正确的(上方)和不正确的(下方,微红色)渐变。
正确的(上方)和不正确的(下方,微红色)渐变。

但是,如果对缺失值进行计算,none 将被视为 0。

4.3. 相对 sRGB 颜色

sRGB 颜色的含义定义在 CSS Color 4 § 5 sRGB Colors 中。

现代颜色语法rgb()rgba() 函数的语法扩展如下:

<modern-rgb-syntax> = rgb( [ from <color> ]?
        [ <number> | <percentage> | none]{3}
        [ / [<alpha-value> | none] ]?  )
<modern-rgba-syntax> = rgba( [ from <color> ]?
        [ <number> | <percentage> | none]{3}
        [ / [<alpha-value> | none] ]?  )

相对颜色 语法下的 rgb()rgba() 函数内, 允许的 分量关键字 如下:

测试
在 sRGB 颜色空间中操作颜色分量:
rgb(from  indianred 255 g b)

这将获取 indianred 的 sRGB 值 (205 92 92) 并将红色分量替换为 255,得到 rgb(255 92 92)。

相对 sRGB 颜色语法适用于非旧版 RGB 句法形式。

例如,这种尝试将 rgba 旧版颜色语法与逗号一起使用的做法是错误的
rgba(from  darkblue 16, 32, b, 0.5 )
相反,应使用
rgb(from  darkblue 16 32 b / 0.5 )

这将获取 darkblue 的 sRGB 值 (0 0 139) 并替换红色、绿色和 alpha 分量,得到 rgb(16 32 139 / 0.5)

4.4. 相对 HSL 颜色

HSL 颜色的含义定义在 CSS Color 4 § 7 HSL Colors: hsl() and hsla() functions 中。

现代颜色语法hsl()hsla() 函数的语法扩展如下:

<modern-hsl-syntax> = hsl([from <color>]?
          [<hue> | none]
          [<percentage> | <number> | none]
          [<percentage> | <number> | none]
          [ / [<alpha-value> | none] ]? )
<modern-hsla-syntax> = hsla([from <color>]?
        [<hue> | none]
        [<percentage> | <number> | none]
        [<percentage> | <number> | none]
        [ / [<alpha-value> | none] ]? )

相对颜色 语法下的 hsl()hsla() 函数内, 允许的 分量关键字 如下:

测试
这将色相角度增加 180 度,得到互补色。
--accent:  lightseagreen;
--complement:   hsl(from var(--accent) calc(h + 180) s l);

lightseagreen 是 hsl(177deg 70% 41%),所以 --complement 是 hsl(357deg 70% 41%)

相对 HSL 颜色语法仅适用于非遗留的 HSL 语法形式。

4.5. 相对 HWB 颜色

HWB 颜色的含义定义在 CSS Color 4 § 8 HWB Colors: hwb() function 中。

hwb() 函数的语法扩展如下:

hwb() = hwb([from <color>]?
        [<hue> | none]
        [<percentage> | <number> | none]
        [<percentage> | <number> | none]
        [ / [<alpha-value> | none] ]? )

相对颜色 语法的 hwb() 函数中, 允许的 分量关键字 有:

测试

4.6. 相对 Lab 颜色

Lab 颜色的含义定义见 CSS Color 4 § 9.1 CIE Lab and LCH

lab() 函数的语法扩展如下:

lab() = lab([from <color>]?
        [<percentage> | <number> | none]
        [<percentage> | <number> | none]
        [<percentage> | <number> | none]
        [ / [<alpha-value> | none] ]? )

相对颜色 语法的 lab() 函数中, 允许的 分量关键字 有:

多种调整基色透明度的方法:

请注意,所有调整都是无损的,因为不会发生色域剪裁,因为 lab() 涵盖所有可见颜色。 这对基于 sRGB 的函数中的 alpha 调整(例如 'rgb()'、'hsl()' 或 'hwb()')是不成立的, 这些函数还会在计算 HSL 或 HWB 之前将颜色转换为 sRGB, 并且还会调整 alpha 透明度。

完全去除颜色饱和度以获得灰色,同时保持相同的亮度:
--mycolor:  orchid;
// orchid 是 lab(62.753 52.460 -34.103)
--mygray:  lab(from var(--mycolor) l 0 0)
// mygray 是 lab(62.753 0 0)rgb(59.515% 59.515% 59.515%)

4.7. 相对 Oklab 颜色

Oklab 颜色的含义定义见 CSS Color 4 § 9.2 Oklab and OKLCh

oklab() 函数的语法扩展如下:

oklab() = oklab([from <color>]?
          [<percentage> | <number> | none]
          [<percentage> | <number> | none]
          [<percentage> | <number> | none]
          [ / [<alpha-value> | none] ]? )

相对颜色 语法的 oklab() 函数中, 允许的 分量关键字 有:

4.8. 相对 LCH 颜色

LCH 颜色的含义定义见 CSS Color 4 § 9.1 CIE Lab and LCH

lch() 函数的语法扩展如下:

lch() = lch([from <color>]?
        [<percentage> | <number> | none]
        [<percentage> | <number> | none]
        [<hue> | none]
        [ / [<alpha-value> | none] ]? )

相对颜色 语法的 lch() 函数中, 允许的 分量关键字 有:

测试
lch(from peru calc(l * 0.8) c h) 生成的颜色比 peru 或 lch(62.2532% 54.0114 63.6769) 暗 20%,并保持其色度和色相不变。 结果为 lch(49.80256 54.0114 63.6769)
这将色相角度加 180 度,生成互补色。
--accent:  lightseagreen;
--complement:   lch(from var(--accent) l c calc(h + 180));

lightseagreen 是 lch(65.4937 39.4484 190.1013),因此 --complement 是 lch(65.4937 39.4484 370.1013)

完全去饱和颜色变为灰色,同时保持相同亮度:
--mycolor:  orchid;
// orchid 是 lch(62.753 62.571 326.973)
--mygray:  lch(from var(--mycolor) l 0 h);
// mygray 是 lch(62.753 0 326.973),即 rgb(59.515% 59.515% 59.515%)

但现在(由于色相被保留)再次 重新饱和

--mymuted:  lch(from var(--mygray) l 30 h);
// mymuted 是 lch(62.753 30 326.973),即 rgb(72.710% 53.293% 71.224%)

然而,不同于 HSL,操纵结果不能保证处于色域内。

在此示例中,目的是生成与原始颜色具有相同亮度和色度, 但色相角度相差 120 度的颜色。 原始颜色在 RGB 色域内, 但在 LCH 中旋转色相会生成色域外的颜色。
--mycolor:  lch(60% 90 320);
lch(from var(--mycolor) l c calc(h - 120));

这会生成一个高色度的青绿色, lch(60% 90 200) 即 color(srgb -0.6 0.698 0.772), 因此超出了 sRGB 色域(负红值)。 实际上,它也超出了 display-p3 色域: color(display-p3 -0.46 0.68 0.758), 甚至超出了 rec2020 色域: color(rec2020 -0.14 0.623 0.729)。

在 sRGB 色域内的最接近颜色为 lch(60.71% 37.56 201.1) 即 rgb(0% 64.2% 66.3%)。色度差异(37.5 代替 90)非常大。

图示 CIE CH 平面,显示相对颜色操作。 ab 轴有标记, 并在中间相交。 我们从中央亮度轴向下看。 sRGB 色域的最大色域显示为不规则的凸多边形。

此图显示了 CIE ab 平面中的 sRGB 色域。 小圆圈表示主要和次要颜色。 原始颜色(显示为大圆圈)在 sRGB 色域内; 但当 LCH 色相旋转 -120° 时变为 色域外(显示为灰色填充和红色边框)。 色域映射后的 结果色度较低。

在 HSL 中执行相同操作将返回一个色域内的结果。 但它在其他方面不尽如人意:

--mycolor:  lch(60% 90 320);
hsl(from var(--mycolor) calc(h - 120) s l);

在 HSL 中,--mycolor 是 hsl(289.18 93.136% 65.531%) 因此减去 120 度得出 hsl(169.18 93.136% 65.531%)。 将该结果转换回 LCH 时, lch(89.0345% 49.3503 178.714) 我们看到,由于 HSL 中的色相旋转, 亮度从 60% 增加到 89%, 色度从 90 降至 49, 而色相实际上改变了 141 度,而不是 120 度。

4.9. 相对 OkLCh 颜色

OkLCh 颜色的含义定义见 CSS Color 4 § 9.2 Oklab and OKLCh

oklch() 函数的语法扩展如下:

oklch() = oklch([from <color>]?
          [<percentage> | <number> | none]
          [<percentage> | <number> | none]
          [<hue> | none]
          [ / [<alpha-value> | none] ]? )

相对颜色 语法的 oklch() 函数中, 允许的 分量关键字 有:

测试

因为 OkLCh 既感知均匀又保持色度,并且各轴对应于更易理解的颜色属性,OkLCh 是颜色操作的一个很好的选择。

本例目标同样是生成一个新的颜色,具有相同亮度和色度,但主色(色相)相差 120 度。这里我们在 OkLCh 中进行操作。原色在 RGB 色域内,但在 OkLCh 中旋转色相,再次得到超出色域的颜色。
--mycolor:  lch(60% 90 320);
oklch(from var(--mycolor) l c calc(h - 120));

--mycolor 是 oklch(0.69012 0.25077 319.893)。色相减去 120 得到一个高色度蓝绿色, oklch(0.69012 0.25077 199.893) 超出 sRGB 色域,为 color(srgb -0.6018 0.7621 0.8448),红分量为负。将 OkLCh 色度减小以进入色域,可得 oklch(0.69012 0.1173 199.893)。OkLCh 色度从 0.251 减至 0.117。

4.10. 相对 Alpha 颜色

相对 alpha 颜色引用原始颜色,只修改 alpha 通道。alpha 通道的含义定义见 CSS Color 4 § 4.2 颜色透明度的表达:<alpha-value> 语法

本等级新增的 alpha() 函数语法如下:

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

相对颜色 语法的 alpha() 函数中, 允许的 分量关键字 有:

原始颜色的颜色分量不变, alpha 分量被替换或修改。 此函数返回值的颜色空间为原始颜色的颜色空间。

例如,本例的结果与原始颜色相同,但 alpha 改为 80%
--mycolor:  oklch(60% 0.25 315 / 0.3);
 alpha(from var(--mycolor) / 80%);
例如,本例的结果与原始颜色相同,但 alpha 是原始颜色的一半
--mycolor:  oklch(60% 0.25 315 / 0.8);
 alpha(from var(--mycolor) / calc(alpha * 0.5));

5. 定义预设和自定义颜色空间:color() 函数

color() 函数允许在特定的、给定的颜色空间中指定颜色(而不是大多数其他颜色函数运行所在的隐式 sRGB 颜色空间)。

在此层级,color() 函数扩展支持自定义颜色空间,除了来自CSS Color 4 § 10. 预定义颜色空间 的预定义空间外。

它还扩展支持相对颜色,而不仅仅是绝对颜色。

其语法如下:

color() = color( [from <color>]? <colorspace-params> [ / [ <alpha-value> | none ] ]? )
<colorspace-params> = [<custom-params> | <predefined-rgb-params> | <xyz-params>]
<custom-params> = <dashed-ident> [ <number> | <percentage> | none ]+
<predefined-rgb-params> = <predefined-rgb> [ <number> | <percentage> | none ]{3}
<predefined-rgb> = srgb | srgb-linear | display-p3 | a98-rgb | prophoto-rgb | rec2020
<xyz-params> = <xyz-space> [ <number> | <percentage> | none ]{3}

color 函数的参数指定了一个颜色,并明确列出颜色空间。

它可以表示一个 无效颜色,如下文所述,或一个 有效颜色

任何非 无效颜色 的颜色都是 有效颜色

颜色可以是 有效颜色,但仍然超出输出设备(屏幕、投影仪或打印机)可以显示的颜色范围。此时被称为 色域外

色域外的颜色其分量值小于 0 或 0%,或大于 1 或 100%。这些值并不无效;在显示时,它们会在计算值阶段使用相对比色法映射为色域内值(0/0% 到 1/100%)。

每个 有效颜色要么在输出设备的色域内(屏幕或打印机),要么是 色域外

5.1. 相对 Color-Function 颜色

在使用相对颜色语法、采用color()函数并用<custom-params>时,可用的分量关键字的数量和名称如下:

在使用相对颜色语法、采用color()函数并用<predefined-rgb-params>时,可用的分量关键字有:

在使用相对颜色语法、采用color()函数并用<xyz-params>时,可用的分量关键字有:

在采用<predefined-rgb-params><xyz-params>时, 又多了一个允许的分量关键字

参数形式如下:

测试
例如,在CIE XYZ D65颜色空间中使用相对颜色语法生成的颜色具有与基准颜色相同的色度,但亮度减少了一半:
--base:  color(display-p3 0.7 0.5 0.1);
--dark:  color(from var(--base) xyz-d65 calc(x/2) calc(y/2) calc(z/2));

原始颜色是color(xyz-d65 0.281 0.253 0.044),因此相对颜色是color(xyz-d65 0.14 0.126 0.022)。

5.2. 自定义颜色空间

CSS允许通过引用颜色配置文件来指定颜色。 例如,这可以用于校准的CMYK打印机、 或RGB颜色空间, 或任何已进行过特征化的彩色或单色输出设备。

本示例指定了四种校准颜色: 两种为自定义空间 (用于SWOP涂层CMYK印刷机, 和广色域的七色墨打印机), 另外两种为预定义空间 (ProPhoto RGB和display-p3 RGB空间)。 在每种情况下,数值参数范围为0.0到1.0 (而不是例如0到255)。
color: color(--swopc 0.0134 0.8078 0.7451 0.3019);
color: color(--indigo 0.0941 0.6274 0.3372 0.1647 0 0.0706 0.1216);
color: color(prophoto-rgb 0.9137 0.5882 0.4784);
color: color(display-p3 0.3804 0.9921 0.1412);

未使用预定义颜色空间的颜色 CSS Color 4 §  10. 预定义颜色空间,通过使用 <dashed-ident>来区分,并且还需要在样式表中某处提供一个匹配的 @color-profile规则, 以将名称与配置文件数据相关联。

测试
@color-profile --swopc {
  src: url('http://example.org/swop-coated.icc');}
@color-profile --indigo {
  src: url('http://example.org/indigo-seven.icc');}

5.3. 指定颜色配置文件: @color-profile at-rule

@color-profile规则定义并命名了一个颜色配置文件, 该配置文件可在稍后用于color()函数中指定颜色。

定义如下:

@color-profile = @color-profile [<dashed-ident> | device-cmyk] { <declaration-list> }
测试

<dashed-ident>提供了颜色配置文件的名称, 该名称将在CSS样式表中使用。 另一种情况是device-cmyk关键字, 这意味着如果此颜色配置文件有效, 将用于解析在device-cmyk中指定的颜色。

@color-profile规则接受本规范中定义的描述符。

名称: src
用于: @color-profile
值: <url>
初始值: n/a

src描述符指定用于检索颜色配置文件信息的URL。

如果定义了多个同名 @color-profile 规则, 以文档顺序最后一个为准,前面的都被忽略。

检索到的 ICC 配置文件是有效的前提为:

如果配置文件无效,则所有引用此配置文件的 CSS 颜色 都是无效颜色

获取外部色彩配置文件,给定一个 @color-profile 规则 rule获取样式资源,用 rule 的 URL, ruleOrDeclaration 设为 rule, destination 设为 "color-profile", CORS mode 设为 "cors", processResponse 步骤给定 response |/res| 和 null、failure 或字节流 byteStream: 若 byteStream 是字节流, 则应用从 |byteStream| 解析出的色彩配置文件。

注:ICC 配置文件的互联网媒体类型(MIME type)为 application/vnd.iccprofile

名称: rendering-intent
用于: @color-profile
取值: relative-colorimetric | absolute-colorimetric | perceptual | saturation
初始值: relative-colorimetric

色彩配置文件包含 “rendering intents”(渲染意图), 用于定义如何色域映射到比其自身色域更小的目标色域。 通常一个配置文件只包含一个意图, 若有多个, 则由 rendering-intent 描述符选择其中一个。

四种可能的渲染意图如下 [ICC]

relative-colorimetric
media-relative colorimetric 要求对于落在目标媒介色域内的源色, 需相对各自媒介白点保持不变。落在目标色域外的源色, 需用多种方法映射到色域边界颜色。

此渲染意图常与黑点补偿联用,即将源媒介黑点也映射到目标黑点。 该方法必须将源白点映射到目标白点。若启用黑点补偿,源黑点也必须映射到目标黑点。应采用适应性算法 以调整白点变化。源与目标色域内的颜色相对关系应尽量保留。目标色域之外的颜色相对关系可能会改变。

absolute-colorimetric
ICC-absolute colorimetric 要求对目标媒介色域内的源色, 参考采用白(理想漫反射体)保持不变。色域外的源色需用多种方法映射到色域边界。本法对色域内色彩匹配最准确,但若目标媒介白点比源白点低, 会导致高光剪裁。故一般只推荐应用于要求精准配色且不关注高光剪裁的场景。

此方法在颜色转换时必须禁用白点和黑点匹配。一般只用于测试,不推荐实际应用。

perceptual
本法常用于图像尤其是在源与目标差异较大(如屏幕图像用于印刷品)时。它会整体重新优化源图像的视觉效果以适应目标媒介,采用专有方法优化。此法允许源/目标色域内色彩都可变化,但应最大程度 保持原作的基本艺术意图,不对源图像错误校正。

注:v2 ICC 配置文件未规定 感知参考媒介,因而会产生兼容性问题。用 v2 ICC 配置文件时,除非已确认所用源与目标配置文件组合能产生所需结果, 通常更安全选用带黑点补偿的 media-relative colorimetric 渲染意图代替 perceptual。

该方法应在映射至目标设备色域时保留像素的相对色值,为避免色相突变和断点,像素值可能整体调整以尽量保留画面总体外观。

saturation
本方法为保持原作相对饱和度(色度)及纯色,但和 perceptual 类似也存兼容问题,且纯色保留不适用于参考媒介, v4 配置文件也不能彻底解决此问题。除非已确认用的源与目标配置文件能产生所需结果,否则不推荐用此渲染意图。 本法应尽量保持原像素相对饱和度(色度)值。超出色域的色彩应转换为保留饱和度但落入色域的色彩。
名称: components
用于: @color-profile
取值: <ident>#
初始值: n/a

色彩描述文件可以定义包含不同数量分量的颜色空间。 例如,青、洋红、黄、黑(CMYK)配置文件 有四个分量, 名称分别是 cyan、magenta、yellow 和 black。 而一种四分量加法屏幕描述文件 也许用四个分量, 名称为 r、g、y 和 b。

此描述符的值是由逗号分隔的<ident> 标记列表。 每个 <ident> 指定一个分量名, 顺序一致对应色彩文件中的顺序, 而记号数量总和就是分量总数。

此描述符声明有四个分量, 名为 cyan、magenta、yellow 和 black:
components: cyan, magenta, yellow, black

而此描述符选用更简短命名:

components: c,m,y,k
此描述符声明七个分量, 名称为 cyan、magenta、yellow、black、orange、green 和 violet:
components: cyan, magenta, yellow, black, orange, green, violet

如果某个分量名ASCII 不区分大小写匹配none, 此描述符无效, 因为该名会与缺失值记号冲突。

若某分量名与 CSS 数字常量冲突(见CSS Values 4 § 10.7.1 数值常量:e, pi), 该分量仍然有效, 但在 calc() 内该分量会被数字常量遮蔽, 结果可能异常。

此描述符不当将某分量命名为 pi, 导致相对颜色语法下的结果意外。
@color-profile --unwise {
  src: url(https://example.com/unwise);
  components: mi, pi, ni;
}
--base: color(--unwise 35% 20% 8%);
--accent: color(from var(--base) mi calc(pi * 2) calc(ni / 2));

这里 --accent 的分量值分别为 35%, 3.14159265358979 * 2 = 6.28318530717959, 4%。

5.4. CSS和打印: 使用校准的CMYK和其他印刷颜色空间

@color-profile 规则并不限于 RGB 色彩空间。 虽然屏幕通常直接以 RGB 显色, 打印设备则经常采用 CMYK 表示颜色。

使用青、洋红、黄、黑(CMYK)的四色印刷校准, 或者高保真宽色域印刷(如 CMYKOGV:青、洋红、黄、黑、橙、绿、紫), 也可以通过 CSS 实现, 只要你有匹配于所用油墨、纸张、总墨量和设备组合的 ICC 配置文件。

例如,采用 FOGRA39 特性数据, 按 ISO 12647-2:2004 / Amd 1:2007 标签轮转胶印, 以 115gsm 涂布纸和 300% 总墨量印刷 [FOGRA39]
@color-profile --fogra39 {
  src: url('https://example.org/Coated_Fogra39L_VIGC_300.icc');
}
.header {
  background-color:   color(--fogra39 0% 70% 20% 0%);
  }

这里 color() 函数首先写出我们取的 profile 名称, 然后依次给出青、洋红、黄和黑的百分比。

在本 profile 下,该 CMYK 结果为  lab(63.673303% 51.576902 5.811058) 即  rgb(93.124, 44.098% 57.491%)。

由于给定 CMYK 组合产生的实际颜色是可知的, 可以在屏幕上模拟印刷输出的效果(软打样)。

此外,任何涉及该颜色的操作 (抗锯齿、复合、渐变色等) 都能如常进行。

一组彩色方格。6 列(A~F)、4 行(1~4),

色卡,用于印刷和摄影行业的色彩保真校验。 每个色块都有人均测量 Lab 值。 矩形表示该 Lab 值,经转换为 sRGB 的效果; 圆形(几乎不可见)表示先将 Lab 经过 FOGRA51 [FOGRA51] ICC profile 转换为 CMYK, 再经同一ICC profile 反转回 Lab, 最后转为 sRGB 展示。

只有第3行第1列色块的圆圈较明显, 是因为颜色略超出所用 FOGRA51 CMYK 空间的色域。

下表显示了每个色块原始Lab与经CMYK往返后的Lab之间的DeltaE 2000值。DeltaE 2000超1即可察觉。

A B C D E F
1 0.06 0.07 0.03 0.04 0.06 0.17
2 0.03 0.75 0.05 0.06 0.03 0.02
3 1.9 0.04 0.06 0.05 0.02 0.05
4 0.03 0.08 0.03 0.03 0.04 0.80
此例采用 CGATS/SWOP TR005 2007 特性数据, 按 ISO 12647-2:2004 用 5级纸、300%墨限、GCR(中等灰成分替换)胶印。
@color-profile --swop5c {
  src: url('https://example.org/SWOP2006_Coated5v2.icc');
}
.header {
  background-color:   color(--swop5c 0% 70% 20% 0%);
}

本 profile 下,相同 CMYK 百分比得到的颜色为  lab(64.965217% 52.119710 5.406966) 即  rgb(94.903% 45.248% 59.104%)。

可以指定备用色, 例如配合媒体查询, 用于CMYK色彩在sRGB色域外时使用。

本例还是 FOGRA39 配置, 但指定了一种明亮绿色,不在 sRGB 色域内, 但属于 display-p3 色域。 在宽色域屏幕和打印设备上正常显示, sRGB 屏幕则使用较低饱和度的备用色。
@media (color-gamut: srgb) {
  .header {
    background-color:   rgb(8.154% 60.9704% 37.184%);
    }
}
@media print, (color-gamut: p3){
  .header {
    background-color:   color(--fogra39 90% 0% 90% 0%);
    }
}

该 CMYK 值对应 lab(56.596645% -58.995875 28.072154) 或 lch(56.596645% 65.33421077211648 154.5533771086801)。 若转为 sRGB,其为 rgb(-60.568% 62.558% 32.390%),红分量为负即色域外。

减少色度至合法色域内, 得  lch(56.596645% 51 154.5533771086801) 即  rgb(8.154% 60.9704% 37.184%) 并被手动指定为备用色。

在宽色域屏幕下,该色在 display-p3 色域内 (对应 display-p3(0.1658 0.6147 0.3533) )。

颜色不局限于四色油墨(CMYK)。如需宽色域,可以用七色油墨集。

此例采用 FOGRA55 beta 数据集 [FOGRA55] 实现 CMYKOGV 七色印刷。 其中四种油墨——黑、青、洋红、黄——保持与 FOGRA51 相同, 其余三色如下:

测试条件为 M1, 意味着纸张光学增白剂已计入, 光谱仪没有 UV 滤镜。

@color-profile --fogra55beta {
  src: url('https://example.org/2020_13.003_FOGRA55beta_CL_Profile.icc');
}
.dark_skin {
  background-color: 
  color(--fogra55beta 0.183596 0.464444 0.461729 0.612490 0.156903 0.000000 0.000000);
}
.light_skin {
  background-color: 
  color(--fogra55beta 0.070804 0.334971 0.321802 0.215606 0.103107 0.000000 0.000000);
}
.blue_sky {
  background-color: 
  color(--fogra55beta 0.572088 0.229346 0.081708 0.282044 0.000000 0.000000 0.168260);
}
.foliage {
  background-color: 
  color(--fogra55beta 0.314566 0.145687 0.661941 0.582879 0.000000 0.234362 0.000000);
}
.blue_flower {
  background-color: 
  color(--fogra55beta 0.375515 0.259934 0.034849 0.107161 0.000000 0.000000 0.308200);
}
.bluish_green {
  background-color: 
  color(--fogra55beta 0.397575 0.010047 0.223682 0.031140 0.000000 0.317066 0.000000);
}

5.5. 将 CMYK 颜色转换为 Lab

从校准的 CMYK 颜色空间到 Lab 的转换 通常是通过在 ICC 配置文件中查找 Lab 值来完成的。

5.6. 将 Lab 颜色转换为 CMYK

对于打印, Lab 颜色需要转换为打印机的颜色空间。

这通常是通过在 ICC 配置文件中查找 CMYK 值来完成的。

6. 未校准 CMYK 颜色:device-cmyk() 函数

有时,当某台打印机还未校准, 但通过实验或印刷样本手册已知某些油墨组合的输出效果时, 以设备相关的方式表达 CMYK 颜色会很有用。

注:由于实际结果颜色可能未知, CSS 处理器或许会尝试近似计算其值。 这种近似很可能与实际印品有明显差距。

device-cmyk() 函数允许作者采用这种方式指定颜色:

device-cmyk() = <legacy-device-cmyk-syntax> | <modern-device-cmyk-syntax>
<legacy-device-cmyk-syntax> = device-cmyk( <number>#{4} )
<modern-device-cmyk-syntax> = device-cmyk( <cmyk-component>{4} [ / [ <alpha-value> | none ] ]? )
<cmyk-component> = <number> | <percentage> | none

device-cmyk() 函数的参数按顺序分别指定青、品红、黄、黑分量, 可为介于 0 到 1 之间的数字, 或在现代语法下为 0%~100% 的百分比。 这两种写法可线性互换且完全等价。 小于 0/0% 或大于 1/100% 的值并不非法, 但会在计算值阶段钳制为 0/0% 或 1/100%。

现代语法下,第五个参数指定颜色的 alpha 分量。 其规则与 rgb() 函数的第四参数一致。 如省略,默认 100%

出于历史原因device-cmyk() 还支持旧版颜色语法

通常,基于印刷的应用会直接以 CMYK 存储所用颜色, 并以此格式送到打印机。 但这种颜色没有色度解释, 因此不能用于渐变、合成、混色等效果。

因此,设备 CMYK 颜色必须转为等价颜色。 这不像 HSL/HWB 到 RGB 的转换那样容易; 具体转换要依赖输出设备的具体特性。

  1. 如用户、作者或 UA 样式表 对 device-cmyk 有 @color-profile 定义, 且 src 描述符指定的资源可获取, 且该资源是有效的 CMYK ICC profile, 且 UA 能处理 ICC profile, 那么device-cmyk() 的计算值必须为该 CMYK 色的 Lab 值。
  2. 否则, device-cmyk() 的计算值必须为该 CMYK 颜色经如下“简单”算法转换的 sRGB 值。
例如,若无 @color-profile, 用以下“简单”转换,下面这几种方式得到的颜色是等价的。
color:  device-cmyk(0 81% 81% 30%);
color:  rgb(178 34 34);
color:  firebrick;
如果像示例样式表那样指定了@color-profile, 则下面这几种方式下,采用色度转换得到的颜色等价。
color:  device-cmyk(0 81% 81% 30%);
color:  lab(45.060% 45.477 35.459)
color:  rgb(70.690% 26.851% 19.724%);

简单算法的转换必然是近似值, 因为并不了解油墨色度、网点增大、RGB 空间色度等信息。

一组彩色方格。6 列(A~F)、4 行(1~4)。

色卡,用于印刷和摄影行业的色彩保真校对。 每块都有实测的均值 Lab 值。 矩形显示 Lab 转为 sRGB 的效果。 圆圈表示 Lab 先经 ICC profile 转成 CMYK,再用简单算法转为 sRGB。

下表显示各色块原始 Lab 和经过 CMYK 往返后的 Lab 的 DeltaE 2000。DeltaE 2000 超过 1 肉眼可见,5 以上肉眼即为另一色。

A B C D E F
1 11.33 9.36 5.66 7.52 12.39 21.58
2 6.40 8.79 11.77 17.16 11.91 3.97
3 12.1 17.00 3.38 1.94 18.08 14.97
4 1.89 6.56 7.85 8.76 9.82 10.29

6.1. 在未校准的 CMYK 和基于 sRGB 的颜色之间进行简单转换

简单地从 CMYK 转换为 RGBA

简单地从 RGBA 转换为 CMYK

7. 响应使用的颜色方案:light-dark() 函数

系统颜色能够响应当前使用的 color-scheme 值。 light-dark() 函数向作者公开了相同的功能。

light-dark() = light-dark( <color>, <color> )

如果 使用的颜色方案light 或未知, 则该函数计算为第一个颜色的计算值; 如果 使用的颜色方案dark,则计算为第二个颜色的计算值。

测试

8. 动态指定具有足够对比度的文本颜色:contrast-color() 函数

当动态创建颜色时,将其用作背景色时,指定一个能提供足够对比度的文本颜色通常是一个挑战。 contrast-color() 函数在指定颜色用作纯色背景上的文本颜色时,会自动提供一个保证颜色对比度的颜色。

注意:易读性是一个复杂的问题,足够的颜色对比度只是其中的一部分。 拥有一对具有足够对比度的颜色并不能保证文本一定易读, 因为这还取决于多种因素,例如字体、文本大小、 周围颜色等。

contrast-color() = contrast-color( <color> )

contrast-color() 解析为 whiteblack, 以当输入颜色用作纯色背景时,能为文本产生最大颜色对比度的那个为准。 如果 whiteblack 产生相同的对比度, 则解析为 white

用于确定输出浅色还是深色的精确颜色对比度算法在此级别由用户代理 (UA) 定义。

注意:此规范的未来版本预计将引入更多对所使用的对比度算法、用例以及返回颜色的控制。

建议用户代理不要简单地使用 WCAG 2.1 第 1.4.3 节 对比度 (最低) 的对比度算法来决定浅色和深色,因为它存在几个已知问题。 但是,此函数返回的颜色仍应满足 WCAG 2.1 第 1.4.3 节 对比度 (最低) 对 AA 大号文本的要求,因为许多作者需要满足强制执行此要求的法律规定。

测试

9. 颜色插值

9.1. 插值的颜色空间

<color-interpolation-method> 已扩展为允许使用 自定义颜色空间

<color-space> = <rectangular-color-space> | <polar-color-space> | <custom-color-space>
<rectangular-color-space> = srgb | srgb-linear | display-p3 | display-p3-linear | a98-rgb | prophoto-rgb | rec2020 | lab | oklab | <xyz-space>
<polar-color-space> = hsl | hwb | lch | oklch
<custom-color-space> = <dashed-ident>
<hue-interpolation-method> = [ shorter | longer | increasing | decreasing ] hue
<color-interpolation-method> = in [ <rectangular-color-space> | <polar-color-space> <hue-interpolation-method>? | <custom-color-space> ]

<dashed-ident> 必须已在有效的 @color-profile 规则中声明, 否则 <color-interpolation-method> 无效。

10. 解析 <color>

10.1. 解析 color-mix()

如果所有 <color> 参数都能解析为各自色彩空间中的对应颜色, 计算值就是混合后的颜色, 位于指定的混合色彩空间中, 并按 CSS Color 4 §  14. 解析 <color> 值 的规则解析。 否则(如果函数中用到了 currentColor), 计算值为 color-mix() 函数, 其中每个 <color> 参数根据 CSS Color 4 §  14. 解析 <color> 值 进行解析, 从而保证继承到子元素。

测试

10.2. 解析相对颜色语法值

如果所有 <color> 参数都能解析为各自色彩空间的对应颜色, 计算值就是指定 RCS 色彩空间中的绝对 <color> 值, 并根据 CSS Color 4 §  14. 解析 <color> 值 进行解析。

测试

否则(如果 currentColor 在函数中使用), 计算值为相对颜色语法函数, 其源 <color> 参数根据 CSS Color 4 §  14. 解析 <color> 值 的方法解析, 以此保持继承到子元素。

测试

10.3. 解析 device-cmyk

计算值和使用值 是指定的设备特定 CMYK 颜色, (其分量为 <number>,而不是 <percentage>) 与指定的 alpha 分量配对 (作为 <number>,而不是 <percentage>; 如果未指定,则默认为不透明)。

实际值 可能根据操作而有所不同; 对于支持 CMYK 的设备,可以呈现为 CMYK 颜色; 对于与非 CMYK 颜色的混合或在非 CMYK 设备上渲染时, 必须按 § 6 未校准的 CMYK 颜色:device-cmyk() 函数 中的规定进行转换。

例如,
 device-cmyk(0% 70% 20% 0%)

具有指定值和实际值

 device-cmyk(0 0.7 0.2 0)

如果实现支持 ICC 配置文件并安装了合适的配置文件, 则使用的值将是

 lab(63.673% 51.577 5.811)

注意:与所有颜色一样,使用值不可通过脚本获取。

11. 序列化

本节扩展了 CSS Color 4 §  15. 序列化 <color> 值,增加了对 color-mix()device-cmyk() 和相对色彩函数结果的序列化支持。

在本节中,规范中使用的字符串及其对应字符如下。

字符串 字符
" " U+0020 空格
"," U+002C 逗号
"-" U+002D 连字符-减号
"." U+002E 句号
"/" U+002F 斜杠

字符串“.”应作为小数点分隔符使用, 无论地区如何,并且不应使用千位分隔符。

通常情况下, 如果结果的 alpha 值正好为 1, 它将在序列化时省略; 默认隐含值为 1(完全不透明)。

11.1. 序列化 color-mix()

color-mix() 函数声明值的序列化结果为字符串 "color-mix(in ", 后跟全部小写的指定 <color-space>, 再跟 ", ", 再跟第一个指定颜色, 再跟一个空格, 再跟第一个百分比的序列化结果(见下述), 再跟 ", ", 再跟第二个指定颜色, 再跟第二个百分比的序列化结果(见下述), 最后加 ")"。

第一个百分比的序列化规则如下:

第二个百分比的序列化规则如下:

注意:calc() 值视为未知, 因此永远不会等于 50%, 也不会和其它值相加正好等于 100%。

例如,下面这个声明的序列化结果:
color-mix(in oklab, teal, peru 40%)

结果为字符串 "color-mix(in oklab, teal 60%, peru)"。

下面这个声明的序列化结果:

color-mix(in oklab, teal 50%, peru 50%)

结果为字符串 "color-mix(in oklab, teal, peru)"。

下面这个声明的序列化结果:

color-mix(in oklab, teal 70%, peru 70%)

结果为字符串 "color-mix(in oklab, teal 70%, peru 70%)" 因为这其实归一化后是 50%/50%,但这只在归一化后得知。

color-mix() 函数结果的序列化, 取决于混合中是否用到 currentColor 关键字。 如有,则按声明值序列化, 这样子元素 color 属性不同值时能正确继承混色。 否则, 是一个 <color>, 序列化方式参考 CSS Color 4 §  15. 序列化 <color> 值。 具体格式根据 "in" 后所指定颜色空间:

混合色彩空间 序列化形式
srgb color(srgb r g b)
srgb-linear color(srgb-linear r g b)
display-p3 color(display-p3 r g b)
a98-rgb color(a98-rgb r g b)
prophoto-rgb color(prophoto-rgb r g b)
rec2020 color(rec2020 r g b)
hsl color(srgb r g b)
hwb color(srgb r g b)
xyz-d65 color(xyz-d65 x y z)
xyz-d50 color(xyz-d50 x y z)
xyz color(xyz-d65 x y z) ¹
lab lab(l a b)
lch lch(l c h)
oklab oklab(l a b)
oklch oklch(l c h)
¹
因为 xyz 只是 xyz-d65 的别名
测试

对回传的最小精度与 CSS Color 4 §  15. 序列化 <color> 值 中指定的精度相同。

颜色混合的结果
color-mix(in lch, peru 40%, palegoldenrod)

序列化为字符串 "lch(79.7256 40.448 84.771)", 而颜色混合的结果

color-mix(in srgb, peru 40%, palegoldenrod)

序列化为字符串 "color(srgb 0.8816 0.7545 0.4988)"。

11.2. 序列化原始颜色

用作另一个颜色函数中原始颜色的已声明值的颜色,其组件值的序列化为:

  1. 对于 rgb()rgba()hsl()hsla()

注:无论是现代语法还是旧版语法,序列化规则一致。

  1. 对于 hwb()lab()lch()oklab()oklch()

  1. 对于 color()

11.3. 序列化相对颜色函数

相对颜色的声明值序列化为:

  1. 对于 rgb()rgba()hsl()hsla()

  1. 对于 hwb()lab()lch()oklab()oklch()

  1. 对于 color()

例如,下面的声明值序列化结果为
OkLcH(from peru  l    c  h)

即字符串 "oklch(from peru l c h)"

例如,下例声明值序列化结果为
rgb(from red calc(r / 2) g calc(30%));

即字符串 "rgb(from red calc(0.5 * r) g calc(30%))",而其计算值序列化为 "color(srgb 0.5 0 0.3)"。

例如,下例声明值序列化为
hsl(from hsl(none 10% 50%) h s l);

即字符串 "hsl(from hsl(none 10% 50%) h s l)",计算值为 "color(srgb 0.55 0.45 0.45)"。

例如,下例声明值序列化为
hsl(from hsl(127.9 302% 25.33%) h s l);

即字符串 "hsl(from hsl(127.9 302% 25.33%) h s l)",计算值为 "color(srgb -0.511666 1.018266 -0.310225)"。

下例HTML(注意元素的color属性):
<div id="example" 
  style="background-color: rgb(from currentcolor r g calc(b / 2)); 
  color: blue;">
</div>

background-color 的声明值序列化为 "rgb(from currentcolor r g calc(b / 2))",其计算值序列化为 "color(srgb 0 0 0.5)"

相对颜色函数结果的序列化, 取决于 currentColor 是否为原始颜色。 是则序列化为声明值, 这样子元素 color 属性不同值时能正确继承。 否则, 是其已解析值, 即<color>, 按 CSS Color 4 §  15. 序列化 <color> 值 规则。

具体格式取决于相对颜色的色彩空间:

混合色彩空间 序列化形式
srgb color(srgb r g b)
srgb-linear color(srgb-linear r g b)
display-p3 color(display-p3 r g b)
a98-rgb color(a98-rgb r g b)
prophoto-rgb color(prophoto-rgb r g b)
rec2020 color(rec2020 r g b)
hsl color(srgb r g b)
hwb color(srgb r g b)
xyz-d65 color(xyz-d65 x y z)
xyz-d50 color(xyz-d50 x y z)
xyz color(xyz-d65 x y z)
lab lab(l a b)
lch lch(l c h)
oklab oklab(l a b)
oklch oklch(l c h)
测试

往返的最低精度 与 CSS 颜色 4 § 15.5 序列化 color() 函数的值 中指定的精度相同。

序列化
lch(from peru calc(l * 0.8) calc(c * 0.7) calc(h + 180)) 

的结果是字符串 "lch(49.80224 37.80819 243.6803)"

11.4. 序列化自定义颜色空间

color() 组件值的保留精度, 因此序列化值中保留的有效数字位数, 在本规范中未定义, 但对于 CMYK 颜色空间,必须至少足以进行八位精度的值回传; 这将导致至少保留两位小数, 除非已省略了末尾的零。

以下颜色的序列化值是

@color-profile --swop5c {src: url('https://example.org/SWOP2006_Coated5v2.icc');
}
.header {
background-color:    color(--swop5c  0% 70.0% 20.00% .0%);
}

字符串 "color(--swop5c 0 0.7 0.2 0)"

11.5. 序列化 device-cmyk

device-cmyk() 值的序列化形式 取自计算值,并使用 device-cmyk() 这种形式, 函数名全部小写。

分量值用十进制序列化, 作为<number>。 各分量之间必须用单一 ASCII 空格字符 " " 分隔。

分量值的小数部分若全为零必须省略; 如果小数部分全部为零, 小数点也必须省略。

下面颜色的序列化结果为

  device-cmyk(0 81% 81% 30%)

是字符串 "device-cmyk(0 0.81 0.81 0.3)"

device-cmyk() 分量值所保留的精度, 以及序列化值的有效数字位数, 本规范未作要求, 但至少要能保证 八位精度值往返不丢失; 这通常意味着至少两位小数, 除非末尾有零被省略。 数值必须向正无穷方向舍入,不可截断。

1 的 alpha 不需要单独序列化。 非 1 的 alpha 必须显式序列化, 且字符串 " / " (一个 ASCII 空格、斜杠、再一个空格) 必须用来分隔 黑色("k")分量值 和 alpha 值。

12. API 接口

12.1. CSSColorProfileRule 接口

CSSColorProfileRule 接口表示 @color-profile 规则。

[Exposed=Window]
interface CSSColorProfileRule : CSSRule {
  readonly attribute CSSOMString name ;
  readonly attribute CSSOMString src ;
  readonly attribute CSSOMString renderingIntent ;
  readonly attribute CSSOMString components ;
};
name, 类型为 CSSOMString,只读
name 属性获取时必须返回 一个包含关联规则中定义的 颜色 配置文件name 序列化的 CSSOMString 对象。
src, 类型为 CSSOMString,只读
renderingIntent, 类型为 CSSOMString,只读
components, 类型为 CSSOMString,只读
其余的属性在获取时必须返回包含 与关联规则关联的描述符的序列化 CSSOMString 对象。 如果未在关联规则中指定描述符, 则该属性必须返回一个空字符串。

13. 默认样式规则

以下样式表是说明性的,而非规范性的。此样式表可由实现作为其默认 HTML 系列文档样式的一部分。

/* 传统桌面用户代理的超链接颜色 */
:link { color: LinkText; }
:visited { color: VisitedText; }
:active { color: ActiveText; }

/* device-cmyk 的合理、保守的默认值 */
@color-profile device-cmyk {
  src: url('https://drafts.csswg.org/css-color-4/ICCprofiles/Coated_Fogra39L_VIGC_300.icc');
}

14. 颜色转换示例代码

本节为非规范性内容。

device-cmyk 的简单转换非常直观:

function naive(cmyk) {
  // 天真地将 CMYK 数组
  // 转换为 sRGB
  let [cyan, magenta, yellow, black] = cmyk;
    let red = 1 - Math.min(1, cyan * (1 - black) + black);
    let green = 1 - Math.min(1, magenta * (1 - black) + black);
    let blue = 1 - Math.min(1, yellow * (1 - black) + black);
    return [red, green, blue];
}

15. 安全性考虑

本规范为 CSS 增加了按需下载 ICC 配置文件的能力。ICC 配置文件不包含可执行代码,因此不会带来额外的安全风险。

16. 隐私性考虑

截至目前,本规范未收到新的隐私性相关问题报告。

17. 可访问性考虑

本规范为用户自定义色(包括动态色)文本背景增加了确保对比度充分的机制。

18. 变更记录

18.1. 2025 年 3 月 18 日工作草案

18.2. 2024 年 2 月 29 日工作草案

18.3. 2022 年 6 月 28 日工作草案

18.4. 2022 年 4 月 28 日工作草案

18.5. 2021 年 12 月 15 日工作草案

18.6. 2021 年 6 月 1 日工作草案

18.7. 2020 年 6 月 10 日初稿

18.8. 相比 CSS Color 4 的主要变更

与 CSS Color 4 相比,一个重大变化是 CSS 颜色已不限于预定义的 RGB 色空间(如 sRGB、display-p3)。

为此增加了如下新特性:

  1. color() 函数由 @color-profile at 规则扩展,用于支持设备相关的有 profile 色,包括校准型 CMYK。
  2. device-cmyk() 函数,用于指定输出设备无校准的(设备相关的)CMYK 颜色。

此外,全新 color-mix() 函数允许在指定色空间将两色混合得到新色。

符合性

文档约定

符合性要求通过描述性断言和 RFC 2119 术语的组合来表达。关键字“必须”、“禁止”、“需要”、“应”、“不应”、“推荐”、“可以”和“可选”在本文件的规范部分中应按照 RFC 2119 的描述进行解释。然而,为了可读性,这些词在本规范中不会全部以大写字母形式出现。

本规范的所有文本均为规范性内容,除非明确标记为非规范性部分、示例和注释。[RFC2119]

本规范中的示例以“例如”开头,或与规范性文本分开设置 class="example",例如:

这是一个信息性示例。

信息性注释以“注释”开头,并与规范性文本分开设置 class="note",例如:

注释,这是一条信息性注释。

建议是规范性部分,样式设计为引起特别注意,并与其他规范性文本分开设置 <strong class="advisement">,例如: 用户代理必须提供可访问的替代方案。

测试

与本规范内容相关的测试可能会记录在像这样的“测试”块中。任何此类块均为非规范性内容。


符合性类别

本规范的符合性定义了三类符合性类别:

样式表
一个 CSS 样式表
渲染器
一个 用户代理(UA),其解释样式表的语义并渲染使用它们的文档。
创作工具
一个 用户代理(UA),其编写样式表。

如果样式表中使用的所有语法声明都符合该模块定义的通用 CSS 语法及各个特性的语法,则样式表符合本规范。

如果渲染器除了按照适用的规范解释样式表外,还通过正确解析并相应地渲染文档来支持本规范定义的所有特性,则该渲染器符合本规范。然而,由于设备的限制而无法正确渲染文档的 UA 并不因此而不符合规范。(例如,UA 并不要求在单色显示器上渲染颜色。)

如果创作工具编写的样式表在语法上符合通用 CSS 语法及该模块中定义的各个特性,并且符合该模块描述的样式表的所有其他符合性要求,则该创作工具符合本规范。

部分实现

为了让作者可以利用前向兼容的解析规则来分配回退值,CSS 渲染器必须将任何不支持的 at-rules、属性、属性值、关键字和其他语法结构视为无效并适当地忽略。特别是,用户代理不得在单个多值属性声明中选择性忽略不支持的组件值并保留支持的值:如果任何值被视为无效(因为不支持的值必须如此),CSS 规定整个声明应被忽略。

不稳定和专有特性的实现

为了避免与未来稳定的 CSS 特性发生冲突,CSS 工作组建议遵循最佳实践来实现不稳定的特性和专有扩展

非实验性实现

一旦规范进入候选推荐阶段,就可以进行非实验性实现,实施者应发布任何符合 CR 级别特性的非前缀实现,前提是可以证明该实现按照规范正确实现。

为了建立和维护 CSS 在不同实现中的互操作性,CSS 工作组要求非实验性 CSS 渲染器在发布任何 CSS 特性的非前缀实现之前向 W3C 提交一个实现报告(如有必要,还包括该实现报告使用的测试用例)。提交给 W3C 的测试用例将由 CSS 工作组进行审查和修正。

有关提交测试用例和实现报告的进一步信息,请访问 CSS 工作组的网站 https://www.w3.org/Style/CSS/Test/。问题应提交到 public-css-testsuite@w3.org 邮件列表。

索引

本规范定义的术语

引用定义的术语

参考文献

规范性引用

[CSS-CASCADE-5]
Elika Etemad;Miriam Suzanne;Tab Atkins Jr.。CSS 层叠与继承第 5 级(CSS Cascading and Inheritance Level 5)。2022 年 1 月 13 日。CR。链接:https://www.w3.org/TR/css-cascade-5/
[CSS-COLOR-4]
Chris Lilley;Tab Atkins Jr.;Lea Verou。CSS 色彩模块第 4 级(CSS Color Module Level 4)。2025 年 4 月 24 日。CRD。链接:https://www.w3.org/TR/css-color-4/
[CSS-COLOR-ADJUST-1]
Elika Etemad 等。CSS 色彩调整模块第 1 级(CSS Color Adjustment Module Level 1)。2025 年 12 月 16 日。CR。链接:https://www.w3.org/TR/css-color-adjust-1/
[CSS-SYNTAX-3]
Tab Atkins Jr.;Simon Sapin。CSS 语法模块第 3 级(CSS Syntax Module Level 3)。2021 年 12 月 24 日。CRD。链接:https://www.w3.org/TR/css-syntax-3/
[CSS-VALUES-4]
Tab Atkins Jr.;Elika Etemad。CSS 数值与单位模块第 4 级(CSS Values and Units Module Level 4)。2024 年 3 月 12 日。WD。链接:https://www.w3.org/TR/css-values-4/
[CSS-VALUES-5]
Tab Atkins Jr.;Elika Etemad;Miriam Suzanne。CSS 数值与单位模块第 5 级(CSS Values and Units Module Level 5)。2024 年 11 月 11 日。WD。链接:https://www.w3.org/TR/css-values-5/
[CSSOM-1]
Daniel Glazman;Emilio Cobos Álvarez。CSS 对象模型(CSSOM)。2021 年 8 月 26 日。WD。链接:https://www.w3.org/TR/cssom-1/
[FETCH]
Anne van Kesteren。Fetch 标准。Living Standard。链接:https://fetch.spec.whatwg.org/
[ICC]
ICC.1:2022(配置文件版本 4.4.0.0)。2022 年 5 月。链接:http://www.color.org/specification/ICC.1-2022-05.pdf
[INFRA]
Anne van Kesteren;Domenic Denicola。Infra 标准。Living Standard。链接:https://infra.spec.whatwg.org/
[RFC2119]
S. Bradner。RFC 文件需求级别关键词(Key words for use in RFCs to Indicate Requirement Levels)。1997 年 3 月。最佳实践(Best Current Practice)。链接:https://datatracker.ietf.org/doc/html/rfc2119
[WEBIDL]
Edgar Chen;Timothy Gu。Web IDL 标准。Living Standard。链接:https://webidl.spec.whatwg.org/

参考资料

[FOGRA39]
ISO 12647-2:2004 / Amd 1,依据 ISO 12647-2 的胶印商用及特种印刷,纸型1或2(光面或哑光涂布115 g/m²),网线 60/cm。2006年。链接:https://www.color.org/chardata/FOGRA39.xalter
[FOGRA51]
ISO 12647-2:2013,网点分色输出、打样及印刷品生产的工艺控制,第2部分:胶印工艺,PS 1,高级涂布纸,115 g/m²,适度荧光底材。2015年。链接:https://registry.color.org/cmyk-registry/fogra51
[FOGRA55]
基于 CMYKOGV 的色域交换空间。2021年。链接:https://fogra.org/en/research/prepress-technology/multiprimary-printing-13003

属性索引

未定义属性。

@color-profile 描述符

名称 初始值
components <ident># n/a
rendering-intent relative-colorimetric | absolute-colorimetric | perceptual | saturation relative-colorimetric
src <url> n/a

IDL 索引

[Exposed=Window]
interface CSSColorProfileRule : CSSRule {
  readonly attribute CSSOMString name ;
  readonly attribute CSSOMString src ;
  readonly attribute CSSOMString renderingIntent ;
  readonly attribute CSSOMString components ;
};