1. 简介
本节不具规范性。
本模块新增了 contrast-color()、 color-mix() 和 light-dark() 这几个新函数, 并通过 相对颜色语法 扩展了已有函数。
它还扩展了 color() 函数, 使其不仅能使用预定义的颜色空间, 还可以使用 CSS 中通过 ICC 配置文件定义的自定义颜色空间 (包括校准 CMYK)。
同时还新增了 device-cmyk, 即未校准的 cmyk 颜色的表示方式。
2. <color> 语法
在 CSS 中,颜色由 <color> 类型表示:
<color> = <color-base> | currentColor | <system-color> |
<contrast-color()> | <device-cmyk()> | <light-dark-color>
<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>。 即它的值不是:
-
currentColor(依赖于 color 属性的值)
-
<system-color> (依赖于色彩模式)
-
<light-dark-color>(依赖于色彩模式)
-
<contrast-color()>(依赖于色彩模式)
-
<device-cmyk()>(没有色度学基础)
这些值也不能用在 <color-mix()> 或相对颜色语法里。
解析为 sRGB 的颜色有:
支持传统颜色语法 的函数有:
<hsl()>、<hsla()>、<hwb()>、<lch()> 以及 <oklch()> 这些 颜色函数 是用圆柱极坐标色彩表示方式,并用 <hue> 角度; 其他 颜色函数 则采用 直角正交色彩 表示方式。
3. 混合颜色:color-mix() 函数
Web开发者、设计工具和设计系统开发者 经常使用颜色函数来帮助扩展组件色彩关系的设计。 随着支持多平台和多用户偏好的设计系统使用的增加, 例如 UI 的深色模式能力提升, 自动计算配色,无需手动指定颜色, 能让方案统一输出,从一处自动生成所有色板,变得更为实用。

目前通常使用 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, purple50 % , plum50 % ) color-mix ( in lch, purple50 % , plum) color-mix ( in lch, purple, plum50 % ) color-mix ( in lch, purple, plum) color-mix ( in lch, plum, purple) color-mix ( in lch, purple80 % , plum80 % )
所有这些写法都会得到 purple 和 plum 各占一半的 lch 混合色: lch(51.51% 52.21 325.8),即 rgb(68.51% 36.01% 68.29%)。
但下例则不同,其中 alpha 小于 1:
color-mix ( in lch, purple30 % , plum30 % )
该例结果为 lch(51.51% 52.21 325.8 / 0.6),即 rgb(68.51% 36.01% 68.29% / 0.6)。
3.3. color-mix 的结果计算
-
对传入函数的 混合项 列表, 归一化混合百分比, 启用“强制归一化”标志, 最终令 items 和 leftover 得到结果。
-
如果 leftover 为 100%, 返回指定插值 <color-space> 下的 透明黑。
-
令 alpha mult 为
1 - leftover, 并将 leftover 视为 0 到 1 间的数字。 -
如果 items 长度为 1, 则 color 设为唯一混合项的颜色, 并转换到指定插值 <color-space>。
否则:
-
把 items 反转成 栈 item stack。 (即原队列第一个为栈顶。)
-
当 item stack 长度大于等于 2 时:
-
从 item stack 弹出 两项,分别为 a 和 b。 combined percentage 设为 a 与 b 百分比之和。
-
按照 CSS Color 4 § 12. 色彩插值, 以 progress 百分比
(b 百分比) / combined percentage)插值 a 与 b 的色值。 若指定插值空间为 圆柱极坐标色彩空间, 则 <hue-interpolation-method> 控制 色相插值,方法见 CSS Color 4 § 12.4 色相插值。 若未指定 <hue-interpolation-method> ,默认使用 shorter。
-
-
color 设为 item stack 最后仅存混合项的颜色。
-
-
把 color 的 alpha 分量乘以 alpha mult。
-
返回 color。
注意: 在 圆柱极坐标色彩 空间下, 混合顺序会影响结果, 因为“顺时针还是逆时针”绕色环方向取决于前面混合产生的结果。 本算法按指定顺序逐个混色, 每次用中间结果与后一个混合。 若用正交色彩空间, 顺序不影响结果, 可以简化处理流程。
测试
- color-mix-basic-001.html (在线测试) (源码)
- color-mix-missing-components.html (在线测试) (源码)
- color-mix-non-srgb-001.html (在线测试) (源码)
- color-computed-color-mix-function.html (在线测试) (源码)
- color-invalid-color-mix-function.html (在线测试) (源码)
- color-valid-color-mix-function.html (在线测试) (源码)
- color-mix-out-of-gamut.html (在线测试) (源码)
- 2d.fillStyle.colormix.html (在线测试) (源码)
- 2d.fillStyle.colormix.currentcolor.html (在线测试) (源码)
- 2d.strokeStyle.colormix.html (在线测试) (源码)
color-mix ( in lch, peru40 % , palegoldenrod)
混色空间为lch。 下图为俯瞰中性色轴 L 的可视化:
计算流程如下:
-
peru 为 lch(62.253% 54.011 63.677)
-
palegoldenrod 为 lch(91.374% 31.406 98.834)
-
混合明度 = 62.253 * 40/100 + 91.374 * (100-40)/100 = 79.7256
-
混合色度 = 54.011 * 40/100 + 31.406 * (100-40)/100 = 40.448
-
混合色相 = 63.677 * 40/100 + 98.834 * (100-40)/100 = 84.771
-
混合结果为 lch(79.7256% 40.448 84.771)
注意: 色相和色度分量插值 可保持中间色与端点色一样饱和。
color-mix ( in lch, teal65 % , olive);
计算如下:
-
sRGB teal (#008080) 为 lch(47.9855% 31.6903 196.4524)
-
sRGB olive (#808000) 为 lch(52.1496% 56.8124 99.5746)
-
混合明度 = 47.9855 * 0.65 + 52.1496 * 0.35 = 49.4429
-
混合色度 = 31.6903 * 0.65 + 56.8124 * 0.35 = 40.4830
-
混合色相 = 196.4524 * 0.65 + 99.5746 * 0.35 = 162.5452
-
混合结果为 lch(49.4429% 40.4830 162.5452)
-
呈蓝绿色调: rgb(7.7377% 52.5730% 37.3213%)
color-mix ( in oklch, teal0 % , olive0 % );
因此在oklch 空间下的结果是透明黑:
oklch(0% 0 none / 0)
color-mix ( in oklab, teal, olive, blue);
计算如下:
-
teal (#008080) 是 oklab(54.31% -0.0896 -0.0236)
-
olive (#808000) 是 oklab(58.07% -0.0428 0.1191)
-
blue (#0000FF) 是 oklab(45.20% -0.0325 -0.3115)
-
混合明度 = (54.31 + 58.07 + 45.20) / 3 = 52.53%
-
混合 a = (-0.0896 + -0.0428 + -0.0325) / 3 = -0.0550
-
混合 b = (-0.0236 + 0.1191 + -0.3115) / 3 = -0.0720
-
混合结果为 oklab(52.53% -0.0550 -0.0720)
3.4. 混合颜色空间对 color-mix 的影响
所选的混色空间会对最终结果产生很大影响。
color-mix ( in lch, white, black); color-mix ( in xyz, white, black); color-mix ( in srgb, white, black);
计算如下:
-
sRGB white (#FFF) 为 lch(100% 0 0)
-
sRGB black (#000) 为 lch(0% 0 0)
-
LCH 混合为 lch(50% 0 0)
-
XYZ 混合为 lch(76% 0 0)
-
sRGB 混合为 lch(53.4% 0 0)
LCH 混合结果 L 为 50%, 正好是预期的标准灰色 (Lab 混合亦同,因为 LCH 和 Lab 明度轴一致)。
XYZ 混合得到的结果太亮; XYZ 虽为线性光,但感知非均匀。 sRGB 混合结果也略偏亮; sRGB 既非感知均匀,也非线性光。
color-mix ( in xyz, rgb ( 82.02 % 30.21 % 35.02 % ) 75.23 % , rgb ( 5.64 % 55.94 % 85.31 % ));
计算如下:
-
rgb(82.02% 30.21% 35.02%) 为 lch(52% 58.1 22.7),即 X=0.3214, Y=0.2014, Z=0.0879。
-
rgb(5.64% 55.94% 85.31%) 为 lch(56% 49.1 257.1),即 X=0.2070, Y=0.2391, Z=0.5249。
-
混合后 X=(0.3214 * 0.7523) + (0.2070 * (1 - 0.7523)) = 0.29306。
-
混合后 Y=(0.2014 * 0.7523) + (0.2391 * (1 - 0.7523)) = 0.21074。
-
混合后 Z=(0.0879 * 0.7523) + (0.5249 * (1 - 0.7523)) = 0.19614。
-
混合结果为 lch(53.0304% 38.9346 352.8138),即 rgb(72.300% 38.639% 53.557%)
本例为白色与蓝色在三种不同颜色空间下的 50% 混合。
color-mix ( in lch, white, blue); color-mix ( in oklch, white, blue); color-mix ( in srgb, white, blue);
计算如下:
-
white 是 rgb(100% 100% 100%) 即 lch(100% 0 none) 也是 oklch(100% 0 none)
-
blue 是 rgb(0% 0% 100%) 即 lch(29.5683% 131.201 301.364) 也是 oklch(45.201% 0.31321 264.052)
-
lch 混合为 lch(64.7841% 65.6008 301.364),带紫色调
-
oklch 混合为 oklch(72.601% 0.15661 264.052)
-
sRGB 混合为 rgb(50% 50% 100%),同样略带紫色调
color-mix ( in hsl, color ( display-p30 1 0 ) 80 % , yellow);
计算如下:
-
color(display-p3 0 1 0) 是 color(srgb -0.5116 1.01827 -0.3107),超出 sRGB 色域
-
转换为 hsl 后 hsl(127.879 301.946 25.334)
-
yellow hsl(60 100% 50%)
-
混合色相:127.879 × 0.8 + 60 × 0.2 = 114.3032
-
混合饱和度:301.946 × 0.8 + 100 × 0.2 = 261.5568
-
混合亮度:25.334 × 0.8 + 50 × 0.2 = 30.2672
-
混合结果为 hsl(114.3032 261.5568 30.2672) 即 color(srgb -0.3387 1.0943 -0.48899)
color-mix ( in lab, device-cmyk ( 0.091777 0.043303 0.312816 0.000000 ) 100 % , yellow);
由于第一个颜色为100%, 第二个颜色为0%,完全不影响混合结果。 因此结果即为第一个颜色在 CIE Lab 空间的计算值。
为了可视化结果, 假设该设备 CMYK 实际为 SWOP 2006 coated 印刷色。
-
device-cmyk(0.091777 0.043303 0.312816 0.000000) 对应 lab(91.44% 4.142 20.52)
如果实现用 ICC 配置文件获取 lab() 颜色, 本例假设采用 FOGRA39 Coated 配置:
-
device-cmyk(0.091777 0.043303 0.312816 0.000000) 为 lab(91.840596 -3.559090 20.449159)
-
其与原始印刷色的 deltaE 2000 为 8.17,肉眼明显可见。
若另一个实现用 简单颜色转换算法, 得到 sRGB 结果:
-
device-cmyk(0.091777 0.043303 0.312816 0.000000) 为 rgb(90.8223% 95.6697% 68.7184%) 即 lab(94.02% -12.31 31.79)
-
其与原始印刷色的 deltaE 2000 为 14.3,极为明显。
3.5. 非1透明度对 color-mix 的影响
到目前为止,所有 color-mix() 示例 都使用了完全不透明的颜色。 为了简化示例, 省略了预乘和反预乘步骤, 因为这些步骤只需乘以1除以1,结果没变化。
一般情况下, 颜色可能存在非1的 alpha 分量, 此时预乘、插值、反预乘 这些步骤都不能省略。
color-mix ( in srgb, rgb ( 100 % 0 % 0 % /0.7 ) 25 % , rgb ( 0 % 100 % 0 % /0.2 ));
计算如下:
-
rgb(100% 0% 0% / 0.7) 预乘后为 [0.7, 0, 0]
-
rgb(0% 100% 0% / 0.2) 预乘后为 [0, 0.2, 0]
-
预乘后插值结果为 [0.7 * 0.25 + 0 * (1 - 0.25), 0 * 0.25 + 0.2 * (1 - 0.25), 0 * 0.25 + 0 * (1 - 0.25)] 即 [0.175, 0.150, 0]
-
插值后的 alpha 为 0.7 * 0.25 + 0.2 * (1 - 0.25) = 0.325
-
反预乘得 [0.175 / 0.325, 0.150 / 0.325, 0 / 0.325] 即 [0.53846, 0.46154, 0]
-
最终混合色为 color(srgb 0.53846 0.46154 0 / 0.325)
错误计算如下:
-
插值结果为 [1 * 0.25 + 0 * (1 - 0.25), 0 * 0.25 + 1 * (1 - 0.25), 0 * 0.25 + 0 * (1 - 0.25)] 即 [0.25, 0.75, 0]
-
故错误混合色为 color(srgb 0.25 0.75 0 / 0.325)
二者差异极大,正确与错误结果的 ΔE2000 可达 30.7!
当百分比归一化后生成 alpha 乘数时, 只需在末尾多一步即可完成计算。
但本例中百分比写作 第一色 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 % );
计算如下:
-
rgb(100% 0% 0% / 0.7) 预乘后为 [0.7, 0, 0]
-
rgb(0% 100% 0% / 0.2) 预乘后为 [0, 0.2, 0]
-
预乘后插值结果为 [0.7 * 0.25 + 0 * (1 - 0.25), 0 * 0.25 + 0.2 * (1 - 0.25), 0 * 0.25 + 0 * (1 - 0.25)] 即 [0.175, 0.150, 0]
-
插值后的 alpha 为 0.7 * 0.25 + 0.2 * (1 - 0.25) = 0.325
-
反预乘得 [0.175 / 0.325, 0.150 / 0.325, 0 / 0.325] 即 [0.53846, 0.46154, 0]
-
最终混合色为 color(srgb 0.53846 0.46154 0 / 0.325)
-
有 0.8 的 alpha 乘数, 混合结果 alpha 实际为 0.325 * 0.8 = 0.260 则混合色实际为 color(srgb 0.53846 0.46154 0 / 0.260)
注意: 不要用归一化后的 alpha 直接反预乘。 那样只有在混合权重不缩放到100%时才正确, 本算法权重总要归一化,所以那样会被重复修正。
4. 相对色彩
4.1. 相对色彩处理模型
本规范此前版本的颜色函数, 只能通过直接指定全部色彩分量的方式,仅指定绝对色。
新增的 相对色彩 语法 扩展了 现代颜色语法, 允许用颜色函数对已有颜色做修改: 如果指定了 原色, 那么每个色彩分量 (若有 alpha 分量也可控制), 可以直接指定, 也可从原色中取 (也可以配合 数学函数做运算)。
原色与相对色不必使用相同的颜色函数。
必需转换: 所有运算都在 相对色函数的颜色空间下进行; 若 原始指定颜色空间 与 原色 用的颜色空间不同, 需要先转换进目标函数, 让每个分量都有意义, 分量关键字 所指向的分量属于相对色的色彩空间, 而不是 原色的空间。
若相对色未指定 alpha, 则 alpha 默认为 原色的值 (不再默认 100%,而像绝对语法那样)。
使用相对色彩语法时, 颜色分量的值, 无论直接指定还是由空间转换得来, 不会被限定在参考区间,而是原样保留。 这使得若目标空间支持,可保留超出色域的值。
但使用相对色彩语法时, alpha 分量的值, 无论直接指定还是由空间转换得来, 会被限定在参考区间。
缺失分量的处理方式与 CSS Color 4 § 12.2 缺失分量插值一致: 会先在原色空间与函数目标空间查找对应分量 并传递为缺失分量。
绝大部分 相对色彩语法的用法 都会用 分量关键字 填对应参数,也可用于其它位置。
注意若分量关键字出现在非常规位置; 若百分比最终要转成数值, 那么这些数不会被“魔法比例缩放”, 直接套用可能产生误差。
不支持相对 device-cmyk() 语法。
4.2. 相对颜色语法
下面列出了各函数为兼容 相对颜色 所做的精确定义更改, 但它们都遵循一个通用结构:
-
可以在函数开头用一个 原色, 以 from <color> 值的形式指定。 这包括可选的 alpha 分量(若被指定)。
-
若未指定原色,则该函数不是相对颜色语法。
-
若指定了 原色, 剩余的参数可以像平常一样直接指定, 也可以作为一个 分量关键字 指向被转换到该相对颜色的 原色 的某一分量。 数学函数 也可以使用这些关键字 对 原色的 分量做动态修改。
-
相对颜色 语法并不改变参数是必需还是可选。
-
不过,作为 原色 的颜色 可以使用现代或传统语法。
这些 分量关键字 返回一个 <number>,或 none; 若它们原本是以 <percentage> 或 <angle> 指定, 则该 <percentage> 会被解析为 <number>, 而 <angle> 会被解析为以度为单位的 <number> (这是其 规范单位),范围为 [0, 360]。
测试
- relative-color-with-zoom.html (live test) (source)
- relative-currentcolor-a98rgb-01.html (live test) (source)
- relative-currentcolor-lch-01.html (live test) (source)
- relative-currentcolor-rgb-01.html (live test) (source)
- relative-currentcolor-displayp3-01.html (live test) (source)
- relative-currentcolor-oklab-01.html (live test) (source)
- relative-currentcolor-rgb-02.html (live test) (source)
- relative-currentcolor-hsl-01.html (live test) (source)
- relative-currentcolor-oklch-01.html (live test) (source)
- relative-currentcolor-xyzd50-01.html (live test) (source)
- relative-currentcolor-hsl-02.html (live test) (source)
- relative-currentcolor-prophoto-01.html (live test) (source)
- relative-currentcolor-xyzd65-01.html (live test) (source)
- relative-currentcolor-hwb-01.html (live test) (source)
- relative-currentcolor-rec2020-01.html (live test) (source)
- relative-currentcolor-lab-01.html (live test) (source)
- relative-currentcolor-rec2020-02.html (live test) (source)
- relative-currentcolor-visited-getcomputedstyle.html (live test) (source)
- alpha-color-computed.html (live test) (source)
- alpha-color-parsing-invalid.html (live test) (source)
- alpha-color-parsing-valid.html (live test) (source)
- color-computed-relative-color.html (live test) (source)
- color-invalid-relative-color.html (live test) (source)
- color-valid-relative-color.html (live test) (source)
- relative-color-out-of-gamut.html (live test) (source)
html{ --bluegreen : oklab ( 54.3 % -22.5 % -5 % ); } .overlay{ background : oklab ( fromvar ( --bluegreen) calc ( 1.0 - l) calc ( a *0.8 ) b); }
在此例中,指定的百分比被解析为数值, 得到 oklab(0.543 -0.09 -0.02)。 得到的 RCS 颜色的 l = 1 - 0.543 = 0.457, a = -0.09 * 0.8 = -0.072, b 保持为 -0.02: oklab(0.457 -0.072 -0.02)。
html{ --base : oklch ( 52.6 % 0.115 44.6 deg ) } .summary{ background : oklch ( fromvar ( --base) l ccalc ( h +90 )); }
在此例中,得到的 RCS 颜色为 oklch(0.526 0.115 134.6)。
若原色的色相 <angle> 使用其他单位指定(例如弧度或圈数), 解析得到的 <number> 仍然会是以度为单位的数值。
html{ --color : green; } .foo{ --darker-accent : lch ( fromvar ( --color) calc ( l /2 ) c h); }
在此例中,原色 的亮度被减半而变暗, 其余颜色属性保持不变。
另请注意,原色 是一个颜色关键字 (因此为 sRGB), 但由于它被用在 lch() 函数中, 它会被自动解释为 LCH 颜色。
html{ --bg-color : blue; } .overlay{ background : rgb ( fromvar ( --bg-color) r g b /80 % ); }
在此例中,原色 的 r、g、b 分量不变, 通过关键字从 原色 获取它们的值, 但不透明度被设为 80%,使其略显透明, 无论 原色 的不透明度如何。
--vivid-yellow : color ( display-p31 1 0 ); --paler-yellow : color ( fromvar ( --vivid-yellow) srgb r gcalc ( b +0.5 ));
此处 --vivid-yellow 在被转换为 sRGB 后为 rgb(100% 100% -34.63%), 负的 blue 分量不会被限定(clamp)。 RCS 计算的结果为 rgb(100% 100% 15.37%)
--tan : oklch ( 78 % 0.06 75 /0.7 ); --deeper-tan : oklch ( fromvar ( --tan) l c h /calc ( alpha *2 ));
--blue-into-gray : rgb ( fromvar ( --color) calc ( r *.3 + g *.59 + b *.11 ) calc ( r *.3 + g *.59 + b *.11 ) calc ( r *.3 + g *.59 + b *.11 ));
使用此方法, red 会变为 rgb(76.5 76.5 76.5), lime 会变为 rgb(150.45 150.45 150.45), 而 blue 会变为 rgb(150.45 150.45 150.45)。 一个较为中等的颜色,例如 darkolivegreen, 其 RGB 值为 rgb(85 107 47), 会变为 rgb(93.8 93.8 93.8)。
(粗略原因有二: 首先,尽管这看似亮度计算, 但红绿蓝值在这里是在伽玛编码空间中处理的,而非线性光空间; 其次,所用的权重系数是过时的 NTSC 颜色空间的,而非 sRGB。)
(另注:此示例仅用于说明语法; 更简单且更准确的灰度化方法是使用 oklch() 函数, 因为该色彩空间对人类感知更准确: oklch(from var(--color) l 0 h) 保持亮度不变, 但将色度归零,从而决定颜色的“鲜艳度”。)
例如,
color : color ( fromcolor ( srgb0 0 0 /60 % ) srgb alpha0.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 ( fromrgb ( 0 0 0 /60 % ) alpha153 153 /0.9 );
其结果为 rgb(0.6 153 153 / 0.9) 而不是 rgb(153 153 153 / 0.9)。
html{ --bg : hsl ( none3 % 50 % ); } .foo{ --darker-bg : oklch ( fromvar ( --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) 但类比的色相分量会被传递(carried forward), 得到 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() 函数中, 允许的 分量关键字 有:
测试
rgb ( from indianred255 g b)
这会取 indianred 的 sRGB 值(205 92 92)并将红分量替换为 255,得到 rgb(255 92 92)。
相对 sRGB 颜色语法仅适用于非传统的 RGB 语法形式。
rgb ( from darkblue16 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 中定义。
The grammar of the modern color syntax hsl() and hsla() functions is extended as follows:
<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() 函数中, 允许的 分量关键字 有:
-
h 是一个 <number> ,对应于 原色 在(必要时转换到)sRGB 后的 HSL 色相,以度为单位, 并被规范化到 [0, 360] 区间。90 等同于 90deg。
-
s 和 l 是对应于 原色 在(必要时转换到)sRGB 后的 HSL 饱和度和明度的 <number>。100 等同于 100%。
Tests
lightseagreen 的值为 hsl(177deg 70% 41%),因此 --complement 为 hsl(357deg 70% 41%)--accent : lightseagreen; --complement : hsl ( fromvar ( --accent) calc ( h +180 ) s l);
相对 HSL 颜色语法仅适用于非传统的 HSL 语法形式。
4.5. 相对 HWB 颜色
HWB 颜色的含义在 CSS Color 4 § 8 HWB Colors: hwb() function 中定义。
The grammar of the hwb() function is extended as follows:
hwb() = hwb([from <color>]?
[<hue> | none]
[<percentage> | <number> | none]
[<percentage> | <number> | none]
[ / [<alpha-value> | none] ]? )
在 相对颜色 语法的 hwb() 函数中,允许的 分量关键字 有:
-
h 是一个 <number> ,对应于 原色 在(必要时转换到)sRGB 后的 HWB 色相,以度为单位, 并被规范化到 [0, 360] 区间。90 等同于 90deg。
-
w 和 b 是对应于 原色 在(必要时转换到)sRGB 后的 HWB 白度和黑度的 <number>。100 等同于 100%。
4.6. 相对 Lab 颜色
Lab 颜色的含义在 CSS Color 4 § 9.1 CIE Lab and LCH 中定义。
The grammar of the lab() function is extended as follows:
lab() = lab([from <color>]?
[<percentage> | <number> | none]
[<percentage> | <number> | none]
[<percentage> | <number> | none]
[ / [<alpha-value> | none] ]? )
在 相对颜色 语法的 lab() 函数中,允许的 分量关键字 有:
-
l 是对应于 原色 在(必要时转换到)CIE Lab 后的 CIE 明度的 <number>。100 等同于 100%。
-
a 和 b 是对应于 原色 在(必要时转换到)CIE Lab 后的 a 和 b 轴的 <number>。125 等同于 100%,而 -125 等同于 -100%。
-
lab(from var(--mycolor) l a b / 100%) 将 var(--mycolor) 的 alpha 设为 1.0,而不管其原本为何值。
-
lab(from var(--mycolor) l a b / calc(alpha * 0.8)) 将 var(--mycolor) 的 alpha 降低为其原值的 80%。
注意所有这些调整都是无损的,因为不会发生色域裁剪(gamut clipping),因为 lab() 覆盖了所有可见颜色。 对于基于 sRGB 的函数(例如 'rgb()', 'hsl()', 或 'hwb()')的 alpha 调整并非如此, 因为它们还需要先转换到 sRGB 来计算 HSL 或 HWB,然后才能调整 alpha。
--mycolor : orchid; // orchid islab ( 62.753 52.460 -34.103 ) --mygray:lab ( fromvar ( --mycolor) l0 0 ) // mygray islab ( 62.753 0 0 ) which isrgb ( 59.515 % 59.515 % 59.515 % )
4.7. 相对 Oklab 颜色
Oklab 颜色的含义在 CSS Color 4 § 9.2 Oklab and OkLCh 中定义。
The grammar of the oklab() function is extended as follows:
oklab() = oklab([from <color>]?
[<percentage> | <number> | none]
[<percentage> | <number> | none]
[<percentage> | <number> | none]
[ / [<alpha-value> | none] ]? )
在 相对颜色 语法的 oklab() 函数中,允许的 分量关键字 有:
-
l 是对应于 原色 在(必要时转换到)Oklab 后的 Oklab 明度的 <number>。1.0 等同于 100%。
-
a 和 b 是对应于 原色 在(必要时转换到)Oklab 后的 a 和 b 轴的 <number>。0.4 等同于 100%,而 -0.4 等同于 -100%。
4.8. 相对 LCH 颜色
LCH 颜色的含义在 CSS Color 4 § 9.1 CIE Lab and LCH 中定义。
The grammar of the lch() function is extended as follows:
lch() = lch([from <color>]?
[<percentage> | <number> | none]
[<percentage> | <number> | none]
[<hue> | none]
[ / [<alpha-value> | none] ]? )
在 相对颜色 语法的 lch() 函数中,允许的 分量关键字 有:
-
l 是对应于 原色 在(必要时转换到)CIE LCH 后的 CIE 明度的 <number>。100 等同于 100%。
-
h 是对应于 原色 在(必要时转换到)CIE LCH 后的色相,以度为单位, 并被规范化到 [0, 360] 区间的 <number>。90 等同于 90deg。
lightseagreen 为 lch(65.4937 39.4484 190.1013),因此 --complement 为 lch(65.4937 39.4484 370.1013)--accent : lightseagreen; --complement : lch ( fromvar ( --accent) l ccalc ( h +180 ));
--mycolor : orchid; // orchid islch ( 62.753 62.571 326.973 ) --mygray:lch ( fromvar ( --mycolor) l0 h) // mygray islch ( 62.753 0 326.973 ) which isrgb ( 59.515 % 59.515 % 59.515 % )
但现在(因为保留了色相)再把色度恢复(re-saturating):
--mymuted : lch ( fromvar ( --mygray) l30 h); // mymuted islch ( 62.753 30 326.973 ) which isrgb ( 72.710 % 53.293 % 71.224 % )
然而,与 HSL 不同,LCH 中的操作并不保证总是在色域内(in-gamut)。
--mycolor : lch ( 60 % 90 320 ); lch ( fromvar ( --mycolor) l ccalc ( 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 平面示意图,显示相对颜色操作。 图中标注了 a 和 b 轴,并在中间交叉。 我们沿中央的明度轴向下观察。 sRGB 色域的最大范围显示为一个不规则的凸多边形。
在 HSL 中执行相同操作将返回一个在色域内的结果。 但在其他方面并不令人满意:
--mycolor : lch ( 60 % 90 320 ); hsl ( fromvar ( --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() 函数时,允许的 分量关键字 如下:
-
l 是一个 <number>, 对应于 原色 在(如需转换则先转换到)OkLCh 下的 Oklab 明度。 1.0 等同于 100%。
-
c 是一个 <number>, 对应于 原色 在(如需转换则先转换到)OkLCh 下的色度。 0.4 等同于 100%。
-
h 是一个 <number>, 对应于 原色 在(如需转换则先转换到)OkLCh 下的色相,以度为单位, 并归一化到 [0, 360] 范围。90 等同于 90deg。
由于 OkLCh 既感知均匀又能保持色度,且其坐标轴与颜色的直观属性对应, 因此 OkLCh 是进行颜色操作的良好选择。
--mycolor : lch ( 60 % 90 320 ); oklch ( fromvar ( --mycolor) l ccalc ( 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 分量。 此函数的结果位于原色的颜色空间中。
Tests
--mycolor : oklch ( 60 % 0.25 315 /0.3 ); alpha ( fromvar ( --mycolor) /80 % );
--mycolor : oklch ( 60 % 0.25 315 /0.8 ); alpha ( fromvar ( --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. 相对颜色函数的颜色
在使用 <custom-params> 的 相对颜色 语法的 color() 函数中,允许的 分量关键字 的名称和数量由下列项决定:
-
由相应 @color-profile 的 components 描述符定义(若存在); 否则,不允许任何相对颜色操作。它们是对应于 原色 在(如需转换则先转换到)色彩配置文件色彩空间后的分量的 <number>。 数值 1.0 对应 100%。
在使用 <predefined-rgb-params> 的 相对颜色 语法的 color() 函数中,允许的 分量关键字 为:
在使用 <xyz-params> 的 相对颜色 语法的 color() 函数中,允许的 分量关键字 为:
在使用 <predefined-rgb-params> 或 <xyz-params> 的 相对颜色 语法的 color() 函数中,额外允许的一个 分量关键字 为:
参数具有如下形式:
-
一个表示色彩空间的 <ident> 或 <dashed-ident>。 若为 <ident>,则表示预定义色彩空间之一(见 CSS Color 4 § 10 预定义色彩空间,例如 display-p3); 若为 <dashed-ident>,则表示由 @color-profile 规则定义的自定义色彩空间。 个别预定义色彩空间可能进一步限制是否只能使用 <number>、或 <percentage>,或两者皆可。
如果该 <ident> 指向不存在的色彩空间(即名称不匹配任何预定义色彩空间), 或指向预定义但未被支持的色彩空间,则该参数表示一个 无效颜色。
如果该 <dashed-ident> 指向不存在的色彩空间(即名称不匹配任何 色彩配置文件 的名字,或虽匹配但相应配置文件尚未加载,或不代表有效配置文件), 则该参数表示一个 无效颜色。
-
一个或多个 <number> 或 <percentage>,用于提供该色彩空间所需的参数值。
对于自定义色彩空间,指定的分量值若小于 0 或 0%,或大于 1 或 100%,并不视为无效; 在计算值阶段这些值会被夹限到有效范围。 这是因为 ICC 配置文件通常不接受超范围的输入值。
对于自定义色彩空间,若提供的 <number> 或 <percentage> 比该色彩空间需要的参数更多, 则结尾处多余的 <number> 会被忽略。 该颜色仍被视为 有效颜色。
对于自定义色彩空间,若提供的 <number> 或 <percentage> 比可选的 components 描述中列出的分量更多, 结尾处的附加值仍然有效,但不能用于相对颜色语法。 该颜色仍被视为 有效颜色。
对于自定义色彩空间,若提供的 <number> 或 <percentage> 少于色彩空间所需的参数, 则缺省的参数值为 0。 (这对多组分打印机尤其方便,其中额外的油墨可能是点色或光油,大部分页面颜色不会使用它们。) 该颜色仍被视为 有效颜色。
对于预定义色彩空间,指定的分量值若小于 0 或 0%,或大于 1 或 100%,也不视为无效; 这些超出色域的颜色会在计算值阶段使用相对色度意图被映射到有效范围。
-
可选的以斜线分隔的 <alpha-value>。若省略,则默认为 100%。
--base : color ( display-p30.7 0.5 0.1 ); --dark : color ( fromvar ( --base) xyz-d65calc ( 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 色彩空间,或任何已被表征的其他彩色或单色输出设备。
color : color ( --swopc0.0134 0.8078 0.7451 0.3019 ); color : color ( --indigo0.0941 0.6274 0.3372 0.1647 0 0.0706 0.1216 ); color : color ( prophoto-rgb0.9137 0.5882 0.4784 ); color : color ( display-p30.3804 0.9921 0.1412 );
未使用预定义色彩空间的颜色(参见 CSS Color 4 § 10 预定义色彩空间) 可通过使用 <dashed-ident> 与众不同, 并且还需要在样式表的某处有一个匹配的 @color-profile at-rule, 以将名称与配置文件数据相关联。
@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 规则接受本规范中定义的描述符。
| Name: | src |
|---|---|
| For: | @color-profile |
| Value: | <url> |
| Initial: | n/a |
描述符 src 指定用于检索色彩配置文件信息的 URL。
如果定义了多个具有相同名称的 @color-profile 规则, 则按文档顺序最后出现的规则生效,之前的都会被忽略。
检索到的 ICC 配置文件在以下情况下被视为有效
-
它可以被解析为 ICC 配置文件
-
它是一个输入(Input)、显示(Display)、输出(Output)或色彩空间 ICC 配置文件。(抽象(Abstract)、DeviceLink 和 NamedColor ICC 配置文件不得使用)。
如果该配置文件无效,则引用该配置文件的所有 CSS 颜色均为 无效颜色。
要 获取外部色彩配置文件,给定一个 @color-profile 规则 rule, 按照 获取样式资源 的流程使用 rule 的 URL, 并将 ruleOrDeclaration 设为 rule, destination 设为 "color-profile", CORS 模式为 "cors", 并按以下步骤处理响应(给定 response |/res|)或 null、失败或字节流 byteStream: 若 byteStream 为字节流, 则应用从 |byteStream 解析出的色彩配置文件。
Note: ICC 配置文件的互联网媒体类型(“MIME 类型”) 为 application/vnd.iccprofile。
| Name: | rendering-intent |
|---|---|
| For: | @color-profile |
| Value: | relative-colorimetric | absolute-colorimetric | perceptual | saturation |
| Initial: | relative-colorimetric |
色彩配置文件 包含“渲染意图(rendering intents)”, 它们定义了如何将其颜色映射(gamut-map)到比其定义的色域更小的色域。 通常一个配置文件只包含单个意图, 但当存在多个时, rendering-intent 描述符用于选择其中一个。
四种可能的渲染意图见 [ICC]:
- relative-colorimetric
-
媒介相关的色度比对(media-relative
colorimetric)要求在相对于各自媒体白点的情况下,将落入目标媒体色域内的源颜色保持不变。落在目标媒体色域外的源颜色会使用多种不同方法映射到色域边界上的颜色。
媒体相关的色度比对渲染意图通常与黑点补偿(black point compensation)一起使用,在该方法中源媒体的黑点也被映射到目标媒体的黑点。该方法必须将源白点映射到目标白点。如果正在使用黑点补偿,源黑点也必须映射到目标黑点。应使用适配算法来调整白点变化。应保留源与目标色域内颜色的相对关系。目标色域外颜色的相对关系可能会被改变。
- absolute-colorimetric
-
ICC 绝对色度比对(ICC-absolute
colorimetric)要求在相对于采用的白点(一个理想的反射漫散体)情况下,将落入目标媒体色域内的源颜色保持不变。落在目标媒体色域外的源颜色会使用多种不同方法映射到色域边界上的颜色。该方法对于色域内颜色能产生最精确的颜色匹配,但如果目标媒体白点低于源媒体白点,会导致高光裁剪(highlight
clipping)。因此建议仅在需要精确颜色匹配且对高光裁剪不敏感的应用中使用。
在转换颜色时,该方法必须禁用白点匹配和黑点匹配。一般来说,除测试目的外不推荐使用此选项。
- perceptual
-
当源与目标之间存在显著差异(例如屏幕显示的图像在反射印刷上再现)时,该方法通常是图像的首选。它采用源图像的颜色并使用专有方法为目标媒介重新优化外观。此重新优化可能会改变源和目标色域内的颜色,虽然感知变换应保持原始作品的基本艺术意图。它不会尝试修正源图像中的错误。
Note: 对于 v2 ICC 配置文件,没有指定的感知参考媒介,这会导致互操作性问题。使用 v2 ICC 配置文件时,除非已核查要使用的特定源和目标配置文件能产生期望的结果,否则使用带黑点补偿的媒体相关色度比对渲染意图可能比感知渲染意图更安全。
该方法应在映射到目标设备色域时保持像素之间的相对颜色值。为避免色相偏移和不连续并尽可能保留场景的整体外观,该方法可能会改变原本已在目标设备色域内的像素值。
- saturation
- 该选项旨在保留原始的相对饱和度(色度),并保持纯色的纯度。然而,它像感知意图一样存在互操作性问题,并且因为使用 v4 配置文件的参考媒介方案无法解决纯色保持的问题,所以并不总能解决问题。除非已核查要使用的特定源和目标配置文件能产生期望结果,否则不建议使用此渲染意图。该选项应保留原始像素的相对饱和度(色度)值。超出色域的颜色应被转换为具有相同饱和度但刚好落入色域内的颜色。
| Name: | components |
|---|---|
| For: | @color-profile |
| Value: | <ident># |
| Initial: | n/a |
色彩配置文件可以定义包含不同数量分量的色彩空间。 例如,青(Cyan)、品红(Magenta)、黄(Yellow)和黑(Black)(CMYK)的配置文件 有四个分量, 名为 c, m, y 和 k。 而一个四分量的加法屏幕配置文件 可能使用名为 r, g, y 和 b 的四个分量。
此描述符的值为用逗号分隔的 <ident> 代币列表。 每个 <ident> 指定一个分量的名称, 顺序即为该分量在色彩配置文件中被使用的顺序, 代币总数即定义了分量的数量。
components: cyan, magenta, yellow, black而下述描述符采用更简洁的命名:
components: c,m,y,k
components: cyan, magenta, yellow, black, orange, green, violet
如果某个分量的名称与 ASCII 不区分大小写 的 none 匹配,则该描述符无效, 因为这将与用于表示缺失值的标记冲突。
如果为分量选择的名称与 CSS Values 4 § 10.7.1 Numeric Constants: e, pi 中定义的 CSS 数值常量冲突, 该分量仍然有效, 但在 calc() 中,该分量将被数值常量遮蔽, 可能导致意外结果。
@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 at-rule 并不限于 RGB 色彩空间。 虽然屏幕通常直接以 RGB 显示颜色, 打印机常用 CMYK 表示颜色。
使用青、品红、黄和黑(CMYK)的校准四色印刷, 或使用额外油墨(如橙、绿、紫)的高保真广色域印刷(CMYKOGV), 也可以在 CSS 中实现, 前提是你有一个与所使用的油墨、纸张、总墨量限制和设备相对应的 ICC 配置文件。
@color-profile --fogra39{ src : url ( 'https://example.org/Coated_Fogra39L_VIGC_300.icc' ); } .header{ background-color : color ( --fogra390 % 70 % 20 % 0 % ); }
此处 color() 函数首先指明我们为配置文件指定的名称, 然后给出青、品红、黄和黑的百分比。
在此配置文件中,这解析为颜色 lab(63.673303% 51.576902 5.811058) 即 rgb(93.124, 44.098% 57.491%)。
因为给定 CMYK 组合的实际颜色是已知的, 可以制作打印输出的屏幕软打样(soft-proof)。
另外,依赖于已知颜色的过程(抗锯齿、合成、在渐变中使用颜色等) 可以正常进行。
A color checker, used for ensuring color fidelity in the print and photographic industries. Averaged measured Lab values are available for each patch. The rectangles show the Lab values, converted to sRGB. The circles, which are barely visible, show the Lab values, passed through a FOGRA51 [FOGRA51] ICC profile to convert them to CMYK. The CMYK values are then passed through the same ICC profile in reverse, to yield new Lab values. These are then converted to sRGB for display.
The one patch with a more visible circle (third row, first patch) is because the color is slightly outside the gamut of the FOGRA51 CMYK space used.
The table below shows, for each patch, the DeltaE 2000 between the original Lab and the Lab value after round-tripping through CMYK. A DeltaE 2000 of 1 or more is just visible.
| 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 |
@color-profile --swop5c{ src : url ( 'https://example.org/SWOP2006_Coated5v2.icc' ); } .header{ background-color : color ( --swop5c0 % 70 % 20 % 0 % ); }
在该配置文件中,这一 CMYK 数值 (与前例相同的百分比) 解析为颜色 lab(64.965217% 52.119710 5.406966) 即 rgb(94.903% 45.248% 59.104%)。
可以指定后备颜色(fallback colors), 例如通过媒体查询, 在已知指定的 CMYK 颜色超出 sRGB 色域时使用。
@media ( color-gamut: srgb) { .header{ background-color : rgb ( 8.154 % 60.9704 % 37.184 % ); } } @media print, ( color-gamut: p3){ .header{ background-color : color ( --fogra3990 % 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)。例如,可以使用广色域的七色油墨集合。
- 橙色:CIELAB 65 58 88
- 绿色:CIELAB 60 -75 0
- CIELAB 22 47 -56
测量条件为 M1, 表示在考虑纸张中光学增白剂的情况下进行测量, 光谱仪没有 UV 截断滤镜。
@color-profile --fogra55beta{ src : url ( 'https://example.org/2020_13.003_FOGRA55beta_CL_Profile.icc' ); } .dark_skin{ background-color : color ( --fogra55beta0.183596 0.464444 0.461729 0.612490 0.156903 0.000000 0.000000 ); } .light_skin{ background-color : color ( --fogra55beta0.070804 0.334971 0.321802 0.215606 0.103107 0.000000 0.000000 ); } .blue_sky{ background-color : color ( --fogra55beta0.572088 0.229346 0.081708 0.282044 0.000000 0.000000 0.168260 ); } .foliage{ background-color : color ( --fogra55beta0.314566 0.145687 0.661941 0.582879 0.000000 0.234362 0.000000 ); } .blue_flower{ background-color : color ( --fogra55beta0.375515 0.259934 0.034849 0.107161 0.000000 0.000000 0.308200 ); } .bluish_green{ background-color : color ( --fogra55beta0.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 的转换那样简单; 精确转换依赖于输出设备的具体特性。
- 如果用户、作者或用户代理样式表中有一个 @color-profile 对 device-cmyk 的定义, 且 src 描述符指定的资源可获取, 并且资源为有效的 CMYK ICC 配置文件, 且用户代理能够处理 ICC 配置文件, 则 device-cmyk() 函数的计算值 必须是该 CMYK 颜色的 Lab 值。
- 否则, device-cmyk() 函数的计算值 必须是该 CMYK 颜色按下述朴素转换算法转为的 sRGB 值。
color : device-cmyk ( 0 81 % 81 % 30 % ); color : rgb ( 178 34 34 ); color : firebrick;
color : device-cmyk ( 0 81 % 81 % 30 % ); color : lab ( 45.060 % 45.477 35.459 ) color:rgb ( 70.690 % 26.851 % 19.724 % );
朴素转换本质上是近似的, 因为它不了解墨水的色度、网点增大、RGB 空间的色度等因素。
色卡(color checker),用于印刷和摄影行业以确保色彩保真。 每个色块均有平均测量得出的 Lab 值。 矩形显示这些 Lab 值转换为 sRGB 的结果。 圆圈则显示 Lab 值经过 ICC 配置文件转换为 CMYK 后, 再朴素地转换为 sRGB 的结果。
下表显示,每个色块在经过 CMYK 回转后的 Lab 与原始 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:
red= 1 - min( 1 , cyan* ( 1 - black) + black) green= 1 - min( 1 , magenta* ( 1 - black) + black) blue= 1 - min( 1 , yellow* ( 1 - black) + black) - Alpha 与输入色一样。
要朴素地将 RGBA 转换为 CMYK:
black= 1 - max( red, green, blue) cyan= ( 1 - red- black) / ( 1 - black), or0 if black is1 magenta= ( 1 - green- black) / ( 1 - black), or0 if black is1 yellow= ( 1 - blue- black) / ( 1 - black), or0 if black is1 - alpha 与输入色相同
7. 响应所用 color-scheme:light-dark() 函数
系统颜色能够根据当前的color-scheme(配色方案)值做出响应。 light-dark()函数同样让作者可以实现这一能力。
该函数有两种形式:一种接受一对颜色, 另一种接受一对图片。 尝试传入一张图片和一种颜色会导致解析时错误。
light-dark() = <light-dark-color> | <light-dark-image> <light-dark-color> = light-dark(<color>, <color>) <light-dark-image> = light-dark( [ <image> | none ] , [ <image> | none ] )
对于颜色形式,当所用配色方案为浅色或未知时, 此函数的结果为第一个颜色的计算值; 若所用配色方案为深色,则为第二个颜色的计算值。
对于图片形式,该函数在所用配色方案为浅色或未知时,返回第一张图片; 若所用配色方案为深色,则返回第二张图片。 none 关键字会生成一张完全透明、没有自然尺寸的图片。
它等价于单一渐变终止色为transparent的线性渐变:
linear-gradient ( transparent)
a : link{ color : light-dark ( blue, #81D9FE); background-color : light-dark ( white, black); }
传统的蓝色链接文本 在白色背景下清晰可读 (WCAG 对比度 8.59:1,AAA 通过), 但在黑色背景上不可读 (WCAG 对比度 2.44:1,AA 不通过)。 因此,深色模式下使用更亮的蓝色#81D9FE( WCAG 对比度 13.28:1,AAA 通过)。
可读链接文本
不可读链接文本
可读链接文本
ul.fancy{ list-style-image : light-dark ( url ( "icons/deep-maroon-ball.png" ), url ( "icons/pale-yellow-star.png" ) ); }
测试
8. 动态指定具有足够对比度的文本色:contrast-color() 函数
在动态创建颜色时,往往难以指定一个与之作为背景色时有足够对比度的文本色。 contrast-color() 函数可用作文本色,自动为指定背景色提供有保证色彩对比度的颜色。
注意: 可读性是一个复杂的话题,充足的色彩对比度只是其中一环。 一对有足够对比度的色并不保证文本容易辨认,还取决于字体、字号、周围颜色等诸多因素。
contrast-color() = contrast-color( <color> )
contrast-color() 会针对输入作为纯色背景时选出对文本最大色差的 白色 或 黑色。 若 白色 与 黑色产生相同的对比,则解析为 白色。
判断输出亮色还是暗色所用的具体色差算法在本级 UA 自行定义。
注意: 本规范的后续版本预计会引入 对比算法、用例以及返回颜色的更多控制。
建议用户代理不要仅用 WCAG 2.1 1.4.3 最低对比度算法决定亮色/暗色, 因为它存在若干已知问题。 但本函数返回的颜色仍应满足 WCAG 2.1 1.4.3 最低对比度 对于 AA 大号文本的要求,因为许多作者需要符合法律要求。
测试
- contrast-color-001.html (live test) (source)
- contrast-color-currentcolor-inherited.html (live test) (source)
- contrast-color-interpolation.html (live test) (source)
- color-computed-contrast-color-function.html (live test) (source)
- color-invalid-contrast-color-function.html (live test) (source)
- color-valid-contrast-color-function.html (live test) (source)
- contrast-color-function-calc-container.html (live test) (source)
9. 颜色插值
9.1. 插值色彩空间
<color-interpolation-method> ,如 CSS Color 4 § 12.1 插值色彩空间 中所定义,现扩展以允许使用 自定义色彩空间:
<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. Resolving <color> Values 进行解析。 否则(如果函数内使用了currentColor), 计算值则为color-mix()函数, 并且每个<color>参数都按照 CSS Color 4 § 14. Resolving <color> Values 进行解析, 以此传递继承到子元素。
Tests
10.2. 解析相对色彩语法值
如果所有<color>参数都解析为其各自色彩空间中的相应颜色, 则计算值为绝对<color>值, 在指定的RCS色彩空间中, 并按照CSS Color 4 § 14. Resolving <color> Values 进行解析。
Tests
否则(如果函数中使用了currentColor), 计算值为相对色彩语法函数, 其中起始<color>参数按 CSS Color 4 § 14. Resolving <color> Values 进行解析, 以此传递继承到子元素。
Tests
- relative-currentcolor-a98rgb-01.html (live test) (source)
- relative-currentcolor-lch-01.html (live test) (source)
- relative-currentcolor-rgb-01.html (live test) (source)
- relative-currentcolor-displayp3-01.html (live test) (source)
- relative-currentcolor-oklab-01.html (live test) (source)
- relative-currentcolor-rgb-02.html (live test) (source)
- relative-currentcolor-hsl-01.html (live test) (source)
- relative-currentcolor-oklch-01.html (live test) (source)
- relative-currentcolor-xyzd50-01.html (live test) (source)
- relative-currentcolor-hsl-02.html (live test) (source)
- relative-currentcolor-prophoto-01.html (live test) (source)
- relative-currentcolor-xyzd65-01.html (live test) (source)
- relative-currentcolor-hwb-01.html (live test) (source)
- relative-currentcolor-rec2020-01.html (live test) (source)
- relative-currentcolor-lab-01.html (live test) (source)
- relative-currentcolor-rec2020-02.html (live test) (source)
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. Serializing <color> Values 以增加对 color-mix()、 device-cmyk(), 以及 相对色彩函数的结果的序列化支持。
本节中,规范使用的字符串和对应字符如下:
| String | Character |
|---|---|
| " " | U+0020 空格 |
| "," | U+002C 逗号 |
| "-" | U+002D 连字符/减号 |
| "." | U+002E 句点 |
| "/" | U+002F 斜杠 |
字符串“.”应作为小数分隔符使用, 不论本地化设置, 且不应有千位分隔符。
与以往一样, 如果结果的alpha值恰好为1, 则在序列化时省略; 默认为1(完全不透明)。
11.1. color-mix()的序列化
color-mix() 函数声明值的序列化为字符串 "color-mix(", 后接如下内容,除非<color-space> 是 oklab (无论是显式指定还是默认): 添加字符串 "in ", 然后是全小写的 <color-space>, 如果指定了 <hue-interpolation-method> 且不是 shorter hue, 则添加 " " 和小写的 <hue-interpolation-method>, 再加上 ", ", 然后依次序列化每个颜色参数(见下文),参数之间用 ", " 分隔, 最后加上 ")"。
每个颜色参数的序列化为 已序列化的 <color>, 如果该参数需要序列化百分比(见下文), 则后面加 " " 和序列化的百分比。
每个颜色参数都是单独序列化的; 特别地, 相同颜色不会合并为同一个参数。
关于 color-mix() 函数声明值的 百分比序列化规则如下。 设 N 为颜色参数数量。
对于每个参数, 其 有效百分比 的定义如下:
-
如显式指定了 <percentage>, 且不是 calc() 表达式,则用此百分比;
-
如果 <percentage> 被省略, 且其他所有已指定的 <percentage> 均不是 calc() 表达式:
(100% − specified sum) / omitted count, 其中 specified sum 是所有已显式指定 <percentage> 的和, omitted count 是省略百分比参数的数量; -
否则,未知。
如果所有 有效百分比
都已知且都等于 100% / N,
则所有参数都不序列化百分比。
否则,每个参数的百分比序列化如下:
-
如显式指定了 <percentage>,则原样序列化。
-
如 <percentage> 省略, 且其他所有 <percentage> 均非 calc() 表达式,则序列化
(100% − specified sum) / omitted count,其中 specified sum 与 omitted count 同上。 -
否则(省略了 <percentage>, 但其它参数有 calc() <percentage>): 不序列化任何内容。
注意: calc() 的值视为未知,
因此永远不会等于 100% / N,
并会阻止计算省略的 <percentage>。
color-mix(in oklab, teal, peru 40%)是字符串 "color-mix(teal 60%, peru 40%)": 因为色彩空间为默认值(oklab)而被省略, 且所有百分比都被序列化 因为它们并非都等于 100%/2 = 50%。
下列声明值的序列化结果为
color-mix(in oklab, teal 50%, peru 50%)是字符串 "color-mix(teal, peru)": 两个百分比都等于 100%/2 = 50%,因此都被省略。
下列声明值的序列化结果为
color-mix(in oklab, teal 70%, peru 70%)是字符串 "color-mix(teal 70%, peru 70%)": 因为指定的百分比是 70%,而不是 50%, 所以不能省略, 即便计算时会归一化到各 50%。
下列声明值的序列化结果为
color-mix(in oklch longer hue, red, green, blue)是字符串 "color-mix(in oklch longer hue, red, green, blue)": 因为色彩空间(oklch) 不是默认值, 色相插值方法(longer)也不是默认值(shorter), 且所有百分比都等于 100%/3,所以全部省略。
下列声明值的序列化结果为
color-mix(red 50%, green, blue)是字符串 "color-mix(red 50%, green 25%, blue 25%)": 百分比并不都等于 100%/3, 所以都要序列化, 省略的参数由 (100% − 50%) / 2 = 25% 补足。
color-mix() 函数结果的序列化 取决于混合中是否使用了关键词 currentColor。 如果用到了,序列化结果与声明值一致。 这样子元素的 color 属性不同值时可以得到正确的混合效果。 否则, 序列化结果为 <color>, 见 CSS Color 4 § 15. Serializing <color> Values。 具体使用的格式 由 "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 的别名
Tests
用于round-trip的最小精度同 CSS Color 4 § 15. Serializing <color> Values规定一致。
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. 原始颜色的序列化
当颜色作为原始颜色, 用于另一个颜色函数的声明值组件中时, 该声明值的序列化方式为:
-
用于标识规范颜色函数的字符串, 对于rgb()和rgba()为"rgb", 对于hsl()和hsla()为"hsl",全为小写, 后跟"(", 后跟以空格分隔的非alpha分量列表(如声明时那样, 数字序列化为数字, 百分比序列化为百分比, 角度以正规化的度数序列化, calc()序列化为其化简形式), 不应用clamp, 如果有alpha分量,则后跟" / "和alpha分量(按组件相同规则序列化), 最后加")"。
注:无论使用现代还是旧语法,序列化格式一致。
-
用于标识颜色函数的小写字符串, 后跟"(", 后跟以空格分隔的非alpha分量列表(如声明时那样, 数字为数字, 百分比为百分比, 角度为度, calc()为化简形式,不clamp), 有alpha分量则后跟" / "和alpha分量(序列化规则同上述), 最后加")"。
-
对于color()
-
字符串"color(", 后跟规范色彩空间 (如"xyz"为"xyz-d65")小写, 后跟空格, 后跟以空格分隔的非alpha分量(数字为数字, 百分比为百分比, 角度为度, calc()为化简形式), 不clamp, 如有alpha分量则后跟" / "和alpha分量, 最后加")"。
11.3. 相对色彩函数的序列化
相对颜色声明值的序列化为:
-
用于标识规范颜色函数的字符串, rgb()和rgba()为"rgb", hsl()和hsla()为"hsl",均小写, 后跟"(from ", 后跟原始颜色的序列化 (用嵌套原始颜色序列化规则), 后跟一个空格, 后跟以空格分隔的非alpha通道参数列表(标识符为标识符, 数字和百分比为数字, 角度为度, calc()为化简形式), 如果alpha分量非1, 则后跟" / "和alpha分量(同通道参数序列化但clamp), 最后")"。
-
用于标识颜色函数的小写字符串, 后跟"(from ", 后跟原始颜色的序列化 (用嵌套原始颜色序列化规则), 后跟一个空格, 后跟以空格分隔的非alpha通道参数列表(标识符为标识符, 数字/百分比为数字, 角度为度数, calc()为化简形式), 如果alpha分量非1, 则后跟" / "和alpha分量(同通道参数序列化,但clamp), 最后加")"。
-
对于color()
-
字符串"color(from ", 后跟原始颜色的序列化 (用嵌套原始颜色序列化规则), 后跟一个空格, 后跟色彩空间(如"xyz"为"xyz-d65")小写, 后跟一个空格, 后跟以空格分隔的非alpha通道参数列表(标识符、数字、百分比、度、calc()化简), 如果alpha分量非1, 则后跟" / "和alpha分量(同通道参数、但clamp), 最后加")"。
rgb ( from redcalc ( r /2 ) gcalc ( 30 % ));
是字符串"rgb(from red calc(0.5 * r) g calc(30%))", 对应计算值的序列化为 "color(srgb 0.5 0 0.3)"。
hsl ( fromhsl ( none10 % 50 % ) h s l);
为字符串"hsl(from hsl(none 10% 50%) h s l)", 对应计算值的序列化为 "color(srgb 0.55 0.45 0.45)"。
hsl ( fromhsl ( 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)"。
< 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. Serializing <color> Values。
实际使用的序列化格式 取决于相对色彩的色彩空间:
| 混合色彩空间 | 形式 |
|---|---|
| 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) |
Tests
最小round-trip精度 与CSS Color 4 § 15.5 Serializing values of the color() function 规定一致。
的结果是字符串 "lch(49.80224 37.80819 243.6803)"lch ( from perucalc ( l *0.8 ) calc ( c *0.7 ) calc ( h +180 ))
11.4. 自定义色彩空间的序列化
color()各分量值保留的精度, 也就是序列化值中有效数字的位数, 本规范并未规定, 但对CMYK色彩空间,需至少保证8bit精度可round-trip; 通常应保证至少两位小数, 除非末尾的零被省略。
该颜色的序列化值为
@color-profile --swop5c{ src : url ( 'https://example.org/SWOP2006_Coated5v2.icc' ); } .header{ background-color : color ( --swop5c0 % 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()各分量值的精度, 也就是序列化有效数字的多少, 本规范未规定, 但必须满足8bit精度的round-trip; 通常应有至少两位小数, 除非末尾零被省略。 数值必须向上舍入,不可截断。
alpha值为1时不单独序列化。 非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 属性时,必须返回
一个
CSSOMString对象, 其内容为相关规则下色彩 配置文件定义的 name 的 序列化结果。 src, 类型为 CSSOMString,只读renderingIntent, 类型为 CSSOMString,只读components, 类型为 CSSOMString,只读-
获取其他属性时,
必须返回一个
CSSOMString对象, 其内容为相关规则下定义的对应描述符的序列化结果。 如果相关规则未指定该描述符, 属性必须返回空字符串。
13. 默认样式规则
以下样式表仅供参考,不具规范性。本样式表可被实现用作其 对 HTML 家族文档的默认样式部分。
/* traditional desktop user agent colors for hyperlinks */ :link{ color : LinkText; } :visited{ color : VisitedText; } :active{ color : ActiveText; } /* a reasonable, conservative default for 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) { // naively convert an array of CMYK values // to 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 配置文件的按需下载。 这些文件不包含可执行代码, 因此不会带来额外的安全风险。
16. 隐私注意事项
目前尚未有该规范的新隐私注意事项报告。
17. 无障碍性注意事项
本规范提供了一种保证文本和用户自定义颜色的背景(包括动态颜色) 具有足够对比度的方法。
18. 变更记录
18.1. 自2026年1月13日工作草案起
- 在本规范的“色彩插值”部分添加了一个反向链接, 指向大部分内容所定义的 CSS Color 4 中的同一章节 (Issue 13788)
- 新增了 light-dark() 函数的第二种形式, 可接受一对图片而不是一对颜色 (Issue 12513)
- 为 light-dark() 的图片形式新增 "none" 选项 (Issue 12513)
- 新增了 color-mix() 的三色示例, 因为现在它不再局限于仅支持两种颜色。
- 更新 color-mix() 序列化: 当色彩空间为默认(oklab)时省略, 当色相插值方式为非默认值时要序列化, 百分比规则推广到 N 个颜色 (当都等于 100%/N 时可全省略,否则全部序列化), 并明确相同颜色不会合并 (Issue 13320)
18.2. 自2025年3月18日工作草案起
- 相对色彩增加了回链到 CSS Color 4 对应定义(问题13286)
- 定义了多条 @color-profile 规则时,最后一条生效 问题12980)
- color-mix()默认采用 oklab,color-interpolation-method 可省略(问题10484)
- 移除了仍假设 color-mix() 只能两个颜色的遗留文本
- 更新了原色序列化规则(问题10328)
- 插值色彩空间中新增了 display-p3-linear
- 增加了 alpha() RCS 函数
- 改进了对 color-mix 仍仅限于两个颜色解释文本
- 澄清了外部URL样式资源的获取
- 澄清当 color-mix() 只传一个时返回指定色彩空间的值
- 使颜色混合算法传递归一化标志
- color-mix() 现在接受1个及以上参数,与其它*-mix()一致
- 迁移了“解析为sRGB”和“支持传统语法”的定义自 CSS Color 4
- 新增了 device-cmyk 的朴素转换 js 样例
- 新增了 color-mix() 用 device-cmyk 备用色的示例
- 明确(而非推断)device-cmyk() 不存在 RCS
- 定义当 color-mix() 百分比和为0时返回透明色
- 规范地导出“required conversion”用语
18.3. 自2024年2月29日工作草案起
- 明确组件关键字能返回 none 或数字
- 新增嵌套颜色函数序列化示例
- 定义了color-mix()+calc边界情况,工作组决议
- 移除“和为零则无效”表述,工作组决议
- 统一使用“color component”而非“color channel”
- 简化了 contrast-color(),工作组决议
- consistent premultiplied 用词
- 色彩配置组件大小写不敏感校验
- contrast-color() 纳入 color type 定义
- 新增辅助功能考量章节
- 补充 FOGRA39、51 与 55 的参考
- 移除 <hue-interpolation-method> 语法不会因矩形空间报错的说法
- 澄清相对色彩组件关键字归属色彩空间
- 分离相对色彩的概念与语法细节
- 确保 deltaE 表格文本对比度充足
- 澄清相对色彩组件不会clamp,alpha会
18.4. 自2022年6月28日工作草案起
- 用声明值(declared values)描述了 CSSOM 的序列化,不再用指定值(specified values)
- 新增了 contrast-color() 函数
- 为 color-mix() 显式链接到 CSS Color 4 的插值章节
- 移除了残留的关于 gamut 映射到 HSL 的描述
- 用文字定义了绝对色,而不是写进语法里
- 在每种情况下,显式重复了 percent 到 number 的换算参考区间
- 更好地定义了引用 origin color 为 currentColor 时的相对色序列化;sRGB、hsl() 和 hwb() 以 color(srgb ...) 的方式序列化,便于往返转换
- 更新摘要,提及 light-dark() 函数
- 从 CSS Color 4 向前移植了更完整的矩形色彩空间列表
- 修正了自定义参数的语法为用空格分隔而非逗号
- 修正了 device-cmyk() 的语法(补充了 none 和 CSS GCPM 的(旧)语法)
- color-mix() 在 color 类型的语法里缺失,现已补充
- 明确了指定 RCS 值的序列化方式
- 新增了 light-dark() 函数
- 修正了 color-mix 百分比归一化算法,补充了 50% 边界情况
- 更新了 HSL 示例,该示例此前在 sRGB 转 HSL 前还做了 gamut 映射
- 修正了部分示例的语法高亮
- 明确了 RCS 原色可以包含可选 alpha
- 修正了对 powerless 分量(powerless components)的错误用法
- percent 到 number 的换算使用了参考区间
- 按照 CSS 工作组决议,使 hsl() 和 hwb() 分量值为数字;所有 hue 角度分量值也改为度数。RCS 介绍部分已提过,但此前没全部落实
- 新增 CIE XYZ D65 色彩空间的 RCS 示例
- 移除了无必要且未变动的 CSS Color 4 章节副本(阅读更清晰)
- 将章节标题更正为“指定预定义及自定义色彩空间:color() 函数”
- 定义 HWB 现可接受 number,之前仅允许百分比
- 明确指出:在不常见的位置使用 RCS 分量时,不会有“神奇缩放”;如需缩放请用 calc()。并给出示例
- 明确了 CIE Lightness 和 Oklab lightness 的区别
- 明确了若 color-mix() 用到 currentColor,结果如何序列化,并补充了示例
- 修正了若干 color-mix 示例中的拼写错误
- 修正了使用 0 而非 none 作为 powerless 分量的示例
- 定义了 color-mix 指定值的序列化,明确用指定百分比,不归一化
- 移除未更动的 alpha-value 定义,只做 Color 4 的链接
- 现代和旧版 rgb, rgba, hsl, hsla 用了独立的语法规则
- 明确了原色(origin color)不设限制,可用现代或旧版语法
- 新增了一条 color 语法,明确了 RCS 可嵌套
- 明确了 RGB、HSL 可以百分比和数字混用,不再限于 RCS
- 明确 RCS 仅适用于现代色彩语法
- 定义了必须的色彩空间转换,允许跳过不需要的转换
- 新增了正确与错误的渐变渲染图片
- 明确未命名的自定义色彩空间分量仍有效
- 改进了部分示例,使之更清楚
- 定义了缺少分量(missing components)的 RCS
- 为 color-interpolation 方法新增了 dashed-ident,现在可在自定义色彩空间插值
- 明确 RCS 的 hue 分量解析为数字且单位为度
- 补充了当 origin color 是 currentColor 时的 RCS 解析值
- 分量关键字(Channel keywords)只能有一种类型
- 修正了 legacy 语法用错 RCS 的示例,现已用真正的 legacy 语法
- 例子用统一的序列化形式
- 注明 device-cmyk() 的序列化规则已定义
- 新增 CSSColorProfileRule 接口
- 统一 Oklab 和 OkLCh 的大小写
- 改进了色卡(color swatch)的无障碍访问
- 改进了图示的无障碍访问
- 修正了部分色卡被意外裁剪的问题
- 优化了部分图形的替代文本
- 补充一些缺失的色卡
- 为 MacBeth 图片和 deltaE 表新增了行列标签
- 为 hue-rotate 图表优化了标签
- 图表中的颜色描述更清晰,提升可访问性
- 确保所有图表和插图都有 ID、自链接
18.5. 自2022年4月28日工作草案起
- 修正 rgb() 定义中的拼写
- 编辑改善(大小写、拼写、表达清楚)
- 导出定义供其它规范使用
- color() 文法 alpha 补 none
- color-contrast() 移至6级
18.6. 自2021年12月15日工作草案起
- color() 过多/过少参数宽容仅限自定义色空间
- RCS 改为number/percent皆可
- 明确组件名与常量如PI可冲突
- 相对色彩不使用传统(逗号分隔)语法
- 修正 rgb() 文法 alpha 未含none
- 改变 color-mix() 用于 hsl/hwb 时序列化方式提升精度
- 新增超出色域 color-mix 示例
- 明确 HSL 和 HWB 不能表示超色域颜色用“无法表达该色”
- 修正拼写错误
18.7. 自2021年6月1日工作草案起
- 在矩形空间里使用 <hue-interpolation-method> 是错误
- 将旧 <hue-adjuster> 改为新的 <hue-interpolation-method>
- @color-profile 与 device-cmyk 上移到5级,WG决议
- 禁止组件名为 none
- 补充 OkLCh 相对色彩示例
- 定义插值色彩空间
- 色彩配置加载按 fetch 定义
- contrast 算法基于 D65 适配的 CIE XYZ
- 序列化补 oklab 和 oklch 用于 color-mix()
- 相对色彩语法补 oklab 与 oklch
- 补 lch vs oklch 混合示例
- 混合优先用 oklab/oklch
- xyz 改为 D65,相对于 CSS Color 4
- 新增 oklab 和 oklch 色彩空间
- 定义 color-contrast() 解析
- 明确序列化最小精度
- 说明 CIE LCH 用意
- 新增若干示例
- 移除 color-adjust(), 保留相对色彩语法
- 定义 color-mix/contrast/relative-color 的序列化
18.8. 自2020年6月10日FPWD起
- 为 color() 函数加入了相对色彩语法
- 明确 color-adjuster 不是可选
- color-mix 百分比为必填
- hue-adjuster 回归 color-mix
- 增加不同混合色彩空间示例
- 补 color-mix 百分比归一化示例
- 明确禁止 color-mix 的负百分比
- color-mix 百分比和小于100%会生成透明度小于100%
- color space 全部用 color space 这个说法
- 定义 <color-space> 词法单元
- 纠正 color-contrast 文法
- color-contrast() 可选对比目标
- 调整 adjuster 文法
- color-mix() 百分比和为0的边界情况处理
- 澄清 color-mix() 运算顺序
- 例子与最新文法一致
- 定义百分比归一化
- clarify color-mix 0%/100%意义
- move adjusters from color-mix/简化文法
- color-mix() 必需 color space
- 允许百分比在色彩参数前
- 显式算法给 color-mix()
- 移除 adjusters 并简化文法
- color-mix/in 关键字定义混合色彩空间
- color-contrast() 至少两项
- refine 相对色彩语法说明
- 链接 CSS 4 色彩序列化定义
- 增色空间独立章节
- color-adjust 示例更新
- 示意图完善
- 支持未解析百分比
- 参数归一化
- adjusters 允许百分比
- link 修复
- color-mix 文法调整,支持 adjusters、alpha 调整
- 部分示例修正
- 安全与隐私章节更新
- 新增 vs 关键字到 color-contrast
- 语法增加 xyz adjuster
- 色调调整关键字增加
- xyz 混合空间
- 定义色彩调整器和色彩空间
- mix 百分比默认 50%
- worked 示例与图示增补
- 修正拼写、语法等小问题
- color-contrast() 结果解析机制
18.9. 与 CSS Color 4 的变更
与 CSS Color 4 最大的不同是, CSS 颜色不再局限于 预定义的 RGB 空间(如 sRGB 或 display-p3)。
为支持这点,增加了众多新特性:
- color() 函数由 @color-profile at-rule 扩展,用于有色彩描述文件的设备相关颜色, 支持校准 CMYK。
- device-cmyk() 函数,用于在输出设备专用的 CMYK 色彩空间中指定未校准色。
此外新的 color-mix() 函数允许在指定色彩空间中混合两个颜色,产生新颜色。