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> 其计算值具有绝对的色度解释。 这意味着该值不包括:
-
currentColor(取决于 color 属性的值)
-
<system-color>(取决于颜色模式)
-
<light-dark()>(取决于颜色模式)
-
<contrast-color()> (取决于颜色模式)
-
<device-cmyk()>(无色度基础)
这些值也不能在 <color-mix()> 或相对颜色语法中使用。
解析为 sRGB 的颜色包括:
支持传统颜色语法的函数有:
<hsl()>、<hsla()>、<hwb()>、<lch()> 以及 <oklch()> 颜色函数 都是采用圆柱极坐标颜色表示方式,并使用 <色相> 角度; 其他颜色函数则采用矩形正交颜色表示方式。
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 的 50-50 混合, 在 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 的结果
-
对传递给函数的混合项列表进行混合百分比归一化, 并将“强制归一化”标志设置为 true, 得到 items 和 leftover。
-
如果 leftover 为 100%, 则返回透明黑, 并转换为指定的插值<color-space>。
-
令 alpha mult 为
1 - leftover, 其中 leftover 按 0 到 1 的数字解释。 -
如果 items 长度为 1, 则将 color 设为该唯一项的颜色, 并转换为指定插值<color-space>。
否则:
-
令 item stack 为将 items 反转后得到的堆栈。 (因此,第一个 item 在堆栈顶部。)
-
当 item stack 长度大于等于 2 时:
-
从 item stack 中弹出两次, 分别得到 a 和 b。 令 combined percentage 为 a 和 b 的百分比之和。
-
按CSS Color 4 § 12. 颜色插值的描述, 以进度百分比
(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。
注意:在圆柱极坐标颜色空间中, 混合顺序是有依赖的, 因为“shorter”或“longer”的方向可能随着已执行的混合而改变。 此算法依照指定顺序依次混合每个颜色, 用前一次的结果与下一个颜色混合。 对于矩形正交颜色空间, 混合顺序无影响, 可简化操作。
测试
- color-mix-basic-001.html (live test) (source)
- color-mix-missing-components.html (live test) (source)
- color-mix-non-srgb-001.html (live test) (source)
- color-computed-color-mix-function.html (live test) (source)
- color-invalid-color-mix-function.html (live test) (source)
- color-valid-color-mix-function.html (live test) (source)
- color-mix-out-of-gamut.html (live test) (source)
- 2d.fillStyle.colormix.html (live test) (source)
- 2d.fillStyle.colormix.currentcolor.html (live test) (source)
- 2d.strokeStyle.colormix.html (live test) (source)
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)
3.4. 混合色彩空间对 color-mix 的影响
选择的混合颜色空间会对最终结果产生很大影响。
color-mix ( in lch, white, black); color-mix ( in xyz, white, black); color-mix ( in srgb, white, black);
计算如下:
-
sRGB 白色 (#FFF) 为 lch(100% 0 0)
-
sRGB 黑色 (#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);
计算如下:
-
白色 为 rgb(100% 100% 100%), 即 lch(100% 0 none), 即 oklch(100% 0 none)
-
蓝色 为 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)
-
黄色为 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中的计算值。
为了可视化结果,假设device 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 乘以 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>(这是规范单位)。
测试
- 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)
- 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)。 结果颜色是 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 )); }
在这个示例中,结果颜色是 oklch(0.526 0.115 134.6)。
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%) 并且负蓝色分量未被裁剪。 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 ));
使用此方法,红色 将变为 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 ( 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) 但相似的色相分量被沿用 得到 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 中。
现代颜色语法下 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() 函数内, 允许的 分量关键字 如下:
-
h 是一个 <number>,对应 原始颜色的 HSL 色相(单位为度), 在 (如有需要)转换为 sRGB 后, 归一化到 [0, 360] 范围。90 等价于 90deg。
-
s 和 l 是 <number>,对应 原始颜色的 HSL 饱和度和亮度分量, 在 (如有需要)转换为 sRGB 后。 100 等价于 100%。
--accent : lightseagreen; --complement : hsl ( fromvar ( --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() 函数中, 允许的 分量关键字 有:
-
h 是一个 <number>,对应 原始颜色 的 HWB 色相(度数), 在 (如有需要)转换为 sRGB 后, 归一化到 [0, 360] 范围。90 等价于 90deg。
-
w 和 b 是 <number>,对应 原始颜色 的 HWB 白度与黑度分量, 在 (如有需要)转换为 sRGB 后。 100 等价于 100%。
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() 函数中, 允许的 分量关键字 有:
-
l 是 <number>,对应 原始颜色 的 CIE 亮度, 在 (如有需要)转换为 CIE Lab 后。 100 等价于 100%。
-
a 和 b 是 <number>, 对应 原始颜色 的 CIE Lab a 和 b 轴, 在 (如有需要)转换为 CIE Lab 后。 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 减少原值的 20%。
请注意,所有调整都是无损的,因为不会发生色域剪裁,因为 lab() 涵盖所有可见颜色。 这对基于 sRGB 的函数中的 alpha 调整(例如 'rgb()'、'hsl()' 或 'hwb()')是不成立的, 这些函数还会在计算 HSL 或 HWB 之前将颜色转换为 sRGB, 并且还会调整 alpha 透明度。
--mycolor : orchid; // orchid 是lab ( 62.753 52.460 -34.103 ) --mygray:lab ( fromvar ( --mycolor) l0 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() 函数中, 允许的 分量关键字 有:
-
l 是一个 <number>,对应 原始颜色 的 Oklab 亮度, 在 (如有需要)转换为 Oklab 后。 1.0 等价于 100%。
-
a 和 b 是 <number>, 对应 原始颜色 的 Oklab a 和 b 轴, 在 (如有需要)转换为 Oklab 后。 0.4 等价于 100%,-0.4 等价于 -100%。
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() 函数中, 允许的 分量关键字 有:
-
l 是 <number>,对应 原始颜色 的 CIE 亮度, 在 (如有需要)转换为 CIE LCH 后。 100 等价于 100%。
-
c 是 <number>,对应 原始颜色 的 LCH 色度, 在 (如有需要)转换为 CIE LCH 后。 150 等价于 100%。
-
h 是 <number>,对应 原始颜色 的 LCH 色相(度数), 在 (如有需要)转换为 CIE LCH 后, 并归一化到 [0, 360] 范围。90 等价于 90deg。
--accent : lightseagreen; --complement : lch ( fromvar ( --accent) l ccalc ( 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 ( fromvar ( --mycolor) l0 h); // mygray 是lch ( 62.753 0 326.973 ) ,即rgb ( 59.515 % 59.515 % 59.515 % )
但现在(由于色相被保留)再次 重新饱和:
--mymuted : lch ( fromvar ( --mygray) l30 h); // mymuted 是lch ( 62.753 30 326.973 ) ,即rgb ( 72.710 % 53.293 % 71.224 % )
然而,不同于 HSL,操纵结果不能保证处于色域内。
--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>,对应 原始颜色 的 Oklab 亮度, 在 需要时转换到 OkLCh 后。 1.0 等价于 100%。
-
c 是一个 <number>,对应 原始颜色 的 OkLCh 色度, 在 需要时转换到 OkLCh 后。 0.4 等价于 100%。
-
h 是一个 <number>,对应 原始颜色 的 OkLCh 色相(度), 在 需要时转换到 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 分量被替换或修改。 此函数返回值的颜色空间为原始颜色的颜色空间。
--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. 相对 Color-Function 颜色
在使用相对颜色语法、采用color()函数并用<custom-params>时,可用的分量关键字的数量和名称如下:
-
由对应components描述符(如果有)在@color-profile上定义; 否则,不存在有效的相对颜色操作。这些关键字是<number>,对应原始颜色分量, 在需要时转换到该色彩描述文件的色彩空间后。1.0 等价于 100%。
在使用相对颜色语法、采用color()函数并用<predefined-rgb-params>时,可用的分量关键字有:
在使用相对颜色语法、采用color()函数并用<xyz-params>时,可用的分量关键字有:
在采用<predefined-rgb-params>或<xyz-params>时, 又多了一个允许的分量关键字:
参数形式如下:
-
一个<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 描述符中声明的分量数量,多出的参数依然合法,但不能用于相对颜色语法,颜色仍为有效颜色。
对于自定义色彩空间,如果数量少于须要的参数,缺失的参数会补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规则, 以将名称与配置文件数据相关联。
@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 配置文件是有效的前提为:
-
能够被解析为 ICC Profile
-
它是 Input、Display、Output 或 color space ICC 配置文件。(不得使用 Abstract、DeviceLink 和 NamedColor ICC Profile)。
如果配置文件无效,则所有引用此配置文件的 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> 指定一个分量名, 顺序一致对应色彩文件中的顺序, 而记号数量总和就是分量总数。
components: cyan, magenta, yellow, black
而此描述符选用更简短命名:
components: c,m,y,k
components: cyan, magenta, yellow, black, orange, green, violet
如果某个分量名ASCII 不区分大小写匹配none, 此描述符无效, 因为该名会与缺失值记号冲突。
若某分量名与 CSS 数字常量冲突(见CSS Values 4 § 10.7.1 数值常量:e, pi), 该分量仍然有效, 但在 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 规则并不限于 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() 函数首先写出我们取的 profile 名称, 然后依次给出青、洋红、黄和黑的百分比。
在本 profile 下,该 CMYK 结果为 lab(63.673303% 51.576902 5.811058) 即 rgb(93.124, 44.098% 57.491%)。
由于给定 CMYK 组合产生的实际颜色是可知的, 可以在屏幕上模拟印刷输出的效果(软打样)。
此外,任何涉及该颜色的操作 (抗锯齿、复合、渐变色等) 都能如常进行。
色卡,用于印刷和摄影行业的色彩保真校验。 每个色块都有人均测量 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 |
@color-profile --swop5c{ src : url ( 'https://example.org/SWOP2006_Coated5v2.icc' ); } .header{ background-color : color ( --swop5c0 % 70 % 20 % 0 % ); }
本 profile 下,相同 CMYK 百分比得到的颜色为 lab(64.965217% 52.119710 5.406966) 即 rgb(94.903% 45.248% 59.104%)。
可以指定备用色, 例如配合媒体查询, 用于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 的转换那样容易; 具体转换要依赖输出设备的具体特性。
- 如用户、作者或 UA 样式表 对 device-cmyk 有 @color-profile 定义, 且 src 描述符指定的资源可获取, 且该资源是有效的 CMYK ICC profile, 且 UA 能处理 ICC profile, 那么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 空间色度等信息。
色卡,用于印刷和摄影行业的色彩保真校对。 每块都有实测的均值 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:
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), 或当 black 为1 时,cyan 为0 magenta= ( 1 - green- black) / ( 1 - black), 或当 black 为1 时,magenta 为0 yellow= ( 1 - blue- black) / ( 1 - black), 或当 black 为1 时,yellow 为0 - alpha 与输入颜色相同。
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() 解析为 white 或 black, 以当输入颜色用作纯色背景时,能为文本产生最大颜色对比度的那个为准。 如果 white 和 black 产生相同的对比度, 则解析为 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> 值 的方法解析, 以此保持继承到子元素。
测试
- relative-currentcolor-a98rgb-01.html (在线测试) (源代码)
- relative-currentcolor-lch-01.html (在线测试) (源代码)
- relative-currentcolor-rgb-01.html (在线测试) (源代码)
- relative-currentcolor-displayp3-01.html (在线测试) (源代码)
- relative-currentcolor-oklab-01.html (在线测试) (源代码)
- relative-currentcolor-rgb-02.html (在线测试) (源代码)
- relative-currentcolor-hsl-01.html (在线测试) (源代码)
- relative-currentcolor-oklch-01.html (在线测试) (源代码)
- relative-currentcolor-xyzd50-01.html (在线测试) (源代码)
- relative-currentcolor-hsl-02.html (在线测试) (源代码)
- relative-currentcolor-prophoto-01.html (在线测试) (源代码)
- relative-currentcolor-xyzd65-01.html (在线测试) (源代码)
- relative-currentcolor-hwb-01.html (在线测试) (源代码)
- relative-currentcolor-rec2020-01.html (在线测试) (源代码)
- relative-currentcolor-lab-01.html (在线测试) (源代码)
- relative-currentcolor-rec2020-02.html (在线测试) (源代码)
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>, 再跟 ", ", 再跟第一个指定颜色, 再跟一个空格, 再跟第一个百分比的序列化结果(见下述), 再跟 ", ", 再跟第二个指定颜色, 再跟第二个百分比的序列化结果(见下述), 最后加 ")"。
第一个百分比的序列化规则如下:
-
如果第一个百分比 p1 和第二个百分比 p2 都指定:
-
若 p1 = 50%,p2 = 50%,则不序列化任何内容。
-
否则,p1 按原样序列化。
-
-
如果只指定第一个百分比 p1:
-
若 p1 = 50%,不序列化任何内容。
-
否则,p1 按原样序列化。
-
-
如果只指定第二个百分比 p2:
-
若 p2 = 50%,不序列化任何内容。
-
若 p2 不是 calc(),则序列化 100% - p2。
-
否则,不序列化任何内容。
-
-
如果都未指定:
-
不序列化任何内容。
-
第二个百分比的序列化规则如下:
-
如果第一个百分比 p1 和第二个百分比 p2 都指定:
-
若都不是 calc() 且 p1 + p2 = 100%,不序列化任何内容。
-
否则,p2 按原样序列化。
-
-
如果只指定第一个百分比 p1:
-
不序列化任何内容。
-
-
如果只指定第二个百分比 p2:
-
若 p2 = 50%,不序列化任何内容。
-
若 p2 不是 calc(),不序列化任何内容。
-
否则,p2 按原样序列化。
-
-
如果都未指定:
-
不序列化任何内容。
-
注意: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. 序列化原始颜色
用作另一个颜色函数中原始颜色的已声明值的颜色,其组件值的序列化为:
-
标明规范色函数的字符串, 对 rgb() 和 rgba() 为 "rgb", 对 hsl() 和 hsla() 为 "hsl", 均为小写, 后跟 "(", 后跟以空格分隔的各非 alpha 分量的已声明值 (数字写为数字, 百分数写为百分数, 角度归一化为度, calc() 简化表示), 不进行钳制, 如有 alpha 分量, 后接 " / " 及 alpha 分量(按色值规则处理), 末尾加 ")"。
注:无论是现代语法还是旧版语法,序列化规则一致。
-
标识颜色函数的字符串(全部小写), 后跟 "(", 后跟一个以空格分隔的、按指定方式排列的非 alpha 组件列表 (数字序列化为数字, 百分比序列化为百分比, 角度序列化为规范化的度数角, calc() 序列化为其简化形式),不应用任何限制, 如果存在 alpha 组件,则后跟 " / " 和按指定方式排列的 alpha 组件 (使用与颜色组件相同的规则), 后跟 ")"。
-
对于 color()
-
字符串 "color(", 后跟规范的颜色空间 (对于 "xyz" 是 "xyz-d65"),全部小写, 后跟一个空格, 后跟一个以空格分隔的、按指定方式排列的非 alpha 组件列表 (数字序列化为数字, 百分比序列化为百分比, 角度序列化为规范化的度数角, calc() 序列化为其简化形式), 不应用任何限制, 如果存在 alpha 组件,则后跟 " / " 和按指定方式排列的 alpha 组件 (使用与颜色组件相同的规则), 后跟 ")"。
11.3. 序列化相对颜色函数
相对颜色的声明值序列化为:
-
小写规范颜色函数名的字符串, rgb() 和 rgba() 用 "rgb",hsl() 和 hsla() 用 "hsl", 后跟 "(from ", 后接原始颜色的序列化(采用嵌套序列化规则), 后跟一个空格, 后面是各非 alpha 通道参数,空格分隔 (标识符按标识符序列化,数字和百分比按数字、百分比序列化,角度用度制归一化,calc() 简化表示), 如 alpha 分量非1,则后跟 " / " 及 alpha 分量(与色值参数同规则,但要钳制), 最后加 ")"。
-
小写颜色函数名的字符串, 后跟 "(from ", 后接原始颜色的序列化(采用嵌套序列化规则), 空格分隔的各非 alpha 通道参数(标识符、数字、百分比等), 如 alpha 分量非1,则后跟 " / " 及 alpha 分量(与色值参数同规则,但要钳制), 最后加 ")"。
-
对于 color()
-
字符串 "color(from ", 后接原始颜色的序列化(嵌套序列化规则), 后跟空格, 后跟规范色彩空间("xyz" 用 "xyz-d65"),全小写, 后跟空格, 后面空格分隔的各非 alpha 通道(同上), 如 alpha 分量非1,则后跟 " / " 及钳制后的 alpha, 最后加 ")"。
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. 序列化 <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 perucalc ( 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 ( --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() 分量值所保留的精度, 以及序列化值的有效数字位数, 本规范未作要求, 但至少要能保证 八位精度值往返不丢失; 这通常意味着至少两位小数, 除非末尾有零被省略。 数值必须向正无穷方向舍入,不可截断。
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 日工作草案
- 为相对色增加回链至 CSS Color 4 的相关定义(Issue 13286)
- 规定若存在多条 @color-profile 规则,以最后一条为准(Issue 12980)
- color-mix() 默认 oklab,可省略 color-interpolation-method(Issue 10484)
- 删除遗留文本(原本假定 color-mix() 仅支持两色混合)
- 更新 origin color 的序列化(Issue 10328)
- 为插值增加 display-p3-linear 颜色空间
- 新增 alpha() RCS 函数
- 更新说明,取消 color-mix 只限于两色混合的说法
- 更清晰说明外部样式资源的抓取方式
- 明确 color-mix() 单色返回结果在当前指定色彩空间
- 使色彩混合算法传递归一化标志
- 允许 color-mix() 多于一个参数,与其它 *-mix() 形式一致
- 引入 CSS Color 4 关于 "resolve to sRGB" 和 "support legacy color syntax" 的定义
- 新增 device-cmyk 的 JS 简单转换示例代码
- 新增用 device-cmyk 作为 color-mix() 回退色的例子
- 明确 device-cmyk() 没有 RCS
- 规定 color-mix() 的百分比和为零时返回 transparent
- 补 export “required conversion” 术语
18.2. 自 2024 年 2 月 29 日工作草案
- 明确分量关键字可返回 none 或数值
- 增加嵌套色函数序列化示例
- WG 决议下定义 color-mix() 使用 calc 的边界情况
- 去除对 color-mix() 百分比和为零为非法的表述,采 WG 决议
- 统一使用“color component”而非“color channel”(原二者混用)
- 精简 contrast-color(),采 WG 决议
- 一致指向 “premultiplied” 术语
- 校验 color profile components 不区分大小写
- 将 contrast-color() 增加到 color 类型定义中
- 增加可访问性小部件
- 为插值解释增加 FOGRA39、51、55 引用
- 删除禁用 rect 空间 <hue-interpolation-method> 的内容(语法本不允许)
- 明确相对色的分量关键字关联的色彩空间
- 分离相对色概念与语法细节
- 保证 MacBeth deltaE 表中的文本对比度充足
- 明确相对色 component 不做钳制,alpha 除外
18.3. 自 2022 年 6 月 28 日工作草案
- 描述 CSSOM 序列化以声明值为准,不再用指定值
- 新增 contrast-color() 函数
- 显式链接色彩 4 中的插值章节(应用于 color-mix())
- 删除 HSL 色域映射相关表述
- 将绝对色用文字描述,不在语法中体现
- 在每种 RCS 对应场景都列出百分比换算区间
- 更完善地定义相对色 origin color 为 currentColor 时的序列化。currentColor、sRGB、hsl() 和 hwb() 都用 color(srgb ...) 以实现轮换
- 更新摘要,加入 light-dark() 函数
- 补充 CSS Color 4 的更多矩形色彩空间定义
- 修正 custom params 的语法(空格分隔,不是逗号)
- 补正 device-cmyk() 语法少了 none 及 CSS GCPM 的遗留语法
- color-mix() 补充到 color type 的语法
- 明确 RCS 已声明值的序列化规则
- 增加 color-mix 回退色实例及相关说明
- 增加 CIE XYZ D65 色空间 RCS 示例
- 删除部分与 Color 4 重复且未做改动的章节
- 更正章节标题为 "指定预定义和自定义色空:color() 函数"
- 规定 HWB 可接受 number,原仅允许百分比
- 明确 RCS 位置混用关键字无自动缩放,须用 calc() 手动处理,并补示例
- 明确 Oklab lightness/CIE Lightness 区分
- 明确序列化 color-mix() 用 currentColor 时的行为并补示例
- 修正 color-mix 示例拼写
- 修正示例中应为 none 而不是 0 的分量
- 规定 color-mix 指定值序列化以指定百分比,不归一化
- 删除 unchanged alpha-value 定义,直接链接到 Color 4
- 并用分别的 modern/legacy 语法定义 rgb、rgba、hsl、hsla
- 明确 origin color 类型不做限制,modern 和 legacy 均可
- 增加新 color 定义,明确 RCS 可嵌套
- 明确 RGB/HSL 可混用 percent 和 number,不再专属 RCS
- 明确 RCS 只适用于 modern 色彩语法
- 定义必须转换色彩空间,明确不需要转换时可跳过
- 补正确与错误渐变渲染示意图
- 明确 custom 空间无名分量同样有效
- 优化部分示例
- 明确定义 RCS 缺失分量
- 增加 dashed-ident 到 color-interpolation-method,可在自定义色彩空间插值
- 明确 RCS 中色相分量为度制数值
- 指明 currentColor 为 origin color 时已解析 RCS
- 分量关键字只能有一种类型
- 修正 RCS 用 legacy 语法的错误示例
- 各示例序列化格式规范
- 注记 device-cmyk() 有明确的序列化定义
- 增加 CSSColorProfileRule 接口
- Oklab 与 OkLCh 大小写统一
- 补色块可访问性处理
- 为色块和示意图补辅助文字
- 修正部分色块裁切
- 补充部分色块
- 为 MacBeth 图和 deltaE 表增加行列标签
- 色相轮图例更清晰
- 图表对比度、描述更好及可访问性提升
- 所有图例和结构均有唯一 id、自引用链接
18.4. 自 2022 年 4 月 28 日工作草案
- 修正 rgb() 定义中的拼写错误
- 编辑改进(大小写、拼写、表述更清晰)
- 导出定义,供其它规范引用
- alpha 语法补 none
- 将 color-contrast() 移至第 6 级
18.5. 自 2021 年 12 月 15 日工作草案
- color() 多余/不足参数容错仅限自定义色空间
- RCS 允许 number 或 percent 任意组合
- 详细说明分量名与 CSS 常量可能冲突(如 PI)
- 相对色语法只用现代(非逗号分隔)语法
- 修正 rgb() 语法遗漏 alpha 可选 none
- color-mix() 用于 hsl、hwb 时更高精度
- 补色域外 color-mix 示例
- HSL/HWB 无法表示超色域色时用“无法表达该色”表述
- 拼写修正
18.6. 自 2021 年 6 月 1 日工作草案
- 矩形空间下使用 <hue-interpolation-method> 为语法错误
- 旧 <hue-adjuster> 改为新 <hue-interpolation-method>
- @color-profile 和 device-cmyk 移到第五级(CSSWG 决议)
- 排除 none 作为分量名
- 增加 OkLCh 相对色语法例
- 定义插值色空间
- 按 fetch 定义加载色彩配置
- 明确对比度基于 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、color-contrast、相对色语法的结果序列化
18.7. 自 2020 年 6 月 10 日初稿
- 为 color() 函数增加了相对色语法
- 明确 color-adjuster 不是可选项
- 明确 color-mix 中百分比为必填
- hue-adjuster 移回 color-mix
- 增加不同混合色空间的示例
- 补充 color-mix() 百分比归一化示例
- 明确定义 color-mix() 禁止负百分比
- color-mix() 百分比和小于 100% 时 alpha 透明度小于 100%
- 统一用 color space 术语,定义 <color-space> 记号
- 修正 color-contrast 语法
- 为 color-contrast() 增加可选目标对比度
- 修正 adjuster 语法
- 指出百分比和为零需要特殊处理
- 明确 color-mix() 的运算顺序
- 示例已更新为当前语法
- 定义百分比归一化方法
- 明确 color-mix() 中 0% 和 100% 的含义
- adjusters 的定义从 color-mix() 移到 color-adjust()
- color-mix() 参数允许任意顺序
- color-mix() 必须指定混合色空间
- 允许 color-mix() 百分比写在颜色前面
- 明确 color-mix() 算法步骤
- color-mix() 移除 adjusters 并简化语法
- 增加 "in" 关键字指定混合色彩空间
- color-contrast() 列表至少两个元素
- 更详细地解释了相对色语法
- 链接至 CSS 4 的色值序列化定义
- 新增色彩空间独立章节
- 补充 color-adjust 的示例
- 增加讲解性插图
- 处理未解百分比情况
- color-mix 参数归一化
- 允许 adjusters 用百分比
- 修正链接
- color-mix 语法支持 adjuster,增加 alpha adjuster
- 修正部分示例
- 更新了安全/隐私章节
- 给 color-contrast 增加了 vs 关键字
- 在语法中补充 xyz adjuster
- 增加了色相 adjuster 关键字
- 允许用 XYZ 色彩空间进行混合
- 定义 color-adjuster 和 color space
- mix percent 默认可为 50%
- 增加了完整算法和图示例子
- 纠正拼写、语法、格式等小问题
- 补充 color-contrast() 解析章节
18.8. 相比 CSS Color 4 的主要变更
与 CSS Color 4 相比,一个重大变化是 CSS 颜色已不限于预定义的 RGB 色空间(如 sRGB、display-p3)。
为此增加了如下新特性:
- color() 函数由 @color-profile at 规则扩展,用于支持设备相关的有 profile 色,包括校准型 CMYK。
- device-cmyk() 函数,用于指定输出设备无校准的(设备相关的)CMYK 颜色。
此外,全新 color-mix() 函数允许在指定色空间将两色混合得到新色。