1. 引言
本节不是规范性的。
测试
本节不是规范性的,不需要测试。
本模块描述了 CSS 属性,这些属性允许作者指定元素文本内容的前景颜色和不透明度。 本模块还详细描述了 CSS <color> 值类型。
它不仅定义了已经存在于 CSS1、CSS2 和 CSS Color 3 中的与颜色相关的属性和值, 还定义了新的属性和值。
特别是,它允许在 sRGB 之外的其他 颜色空间 中指定颜色; 以前,即使显示设备支持,更饱和的颜色(超出 sRGB 色域的颜色)也不能在 CSS 中使用。
可用的 草稿实现报告 已发布。
1.1. 值的定义
本规范遵循 CSS 属性定义惯例,来自 [CSS2],使用 值定义语法,来自 [CSS-VALUES-3]。 本规范未定义的值类型在 CSS 值与单位 [CSS-VALUES-3] 中定义。 与其他 CSS 模块的组合可能会扩展这些值类型的定义。
除了在定义中列出的特定于属性的值外,本规范中定义的所有属性还接受 CSS-wide 关键字 作为其属性值。 为了可读性,它们没有被显式重复。
2. 颜色术语
测试
本节提供后续使用的定义,不需要测试。
颜色 是对人类视觉对光线或被光照亮的物体的视觉感知的定义(数值或文本)。 对人类颜色感知的客观研究称为 颜色测量学。
物体的颜色取决于它在每个可见波长上反射的光的多少, 以及照亮它的光的实际颜色(同样是每个波长上的光量)。 它通过分光光度计进行测量。
发光物体的颜色(包括计算机屏幕上的颜色) 取决于它在每个可见波长上发射的光的多少。 它通过分光辐射计进行测量。
如果两个物体具有不同的光谱,但仍然产生相同的物理感觉, 我们说它们具有相同的颜色。 我们可以通过将光谱转换为 CIE XYZ(三个数字)来计算两个颜色是否相同。
颜色空间 是对颜色相对于基础颜色测量学模型的组织, 使得在该颜色空间中任何颜色都有明确的、可客观测量的含义。 这也意味着相同的颜色可以在多个颜色空间中表示, 或从一个颜色空间转换为另一个颜色空间, 同时看起来保持相同。
使用分光光度计对叶子进行测量,发现颜色为 lch(51.2345% 21.2 130), 也就是 lab(51.2345% -13.6271 16.2401)。
同样的颜色可以在不同的颜色空间中表示:
color ( sRGB0.41587 0.503670 0.36664 ); color ( display-p30.43313 0.50108 0.37950 ); color ( a98-rgb0.44091 0.49971 0.37408 ); color ( prophoto-rgb0.36589 0.41717 0.31333 ); color ( rec20200.42210 0.47580 0.35605 );
加色色彩空间意味着坐标系在光强度上是线性的。 CIE XYZ 色彩空间是一种加色色彩空间。 XYZ 的 Y 分量是亮度,即单位面积的光强度, 或者说“它有多亮”。亮度以坎德拉每平方米 (cd/m²) 为单位进行测量, 也称为尼特。
在加色色彩空间中,可以进行计算 以准确预测颜色混合。大多数 RGB 空间 不是加色的,因为其分量是伽马编码的。取消这种伽马编码 会产生线性光值。
如果我们有两种不同颜色的聚光灯照射在舞台上, 一种测得的值是 color(xyz 0.15 0.24 0.17), 另一种是 color(xyz 0.11 0.06 0.06), 那么我们可以准确预测,如果两个有色光束重叠, 混合后的颜色将是 XYZ 分量值的总和,即 color(xyz 0.26 0.30 0.23)。
色度 是将亮度分量排除后的颜色测量值。 从上述相同的灯光示例中,一个灯光的u',v' 色度为 (0.2537, 0.5268), 而两个灯光的色度相同(它们的颜色相同,只是更亮)。
色度是加性的, 因此它可以准确预测混合物的色度(但不能预测其产生的亮度)。 色度是二维的,因此可以在色度图上轻松表示,以预测颜色混合的色度。 任何两个颜色都可以混合,结果颜色将位于图上连接它们的直线上。 三种颜色形成一个平面,结果颜色将位于它们在图上形成的三角形内。
因此,一旦线性化,RGB 色彩空间就是加色的, 它们的色域由红、绿、蓝三原色的色度, 加上白点(所有三种原色都达到最大强度时形成的颜色)的色度定义。
大多数色彩空间使用少数几种模拟日光的白点之一, 这些白点以相应黑体辐射器的相关色温 (CCT) [Understanding_CCT] 命名。 例如,D65 是一个日光白点, 对应于 6500 开尔文的相关色温 (实际上是 6504, 因为自从最初定义该颜色以来,普朗克常数的值已发生变化)。
为了避免累积的往返误差, 在计算的所有地方必须一致地使用相同的色度值, 这样才能实现最大兼容性。 因此,在本规范中定义了以下两个标准的白昼模拟白点:
名称 | x | y | CCT |
---|---|---|---|
D50 | 0.345700 | 0.358500 | 5003K |
D65 | 0.312700 | 0.329000 | 6504K |
当已知颜色空间或产生颜色的设备的物理特性 (例如其使用的基色的色度, 或对一组给定输入的响应所产生的颜色)时, 我们称它为已表征。
如果另外进行了调整,使设备满足校准目标,例如白点、中性色、调响应的可预测性和一致性, 那么它被称为已校准。
目前的物理设备还无法产生人眼可以看到的每种可能颜色。 给定设备能够产生的颜色范围称为色域 (不要与伽马混淆)。 色域有限的设备无法产生非常饱和的颜色, 如彩虹中的颜色。
不同颜色空间的色域可以通过查看可以表示的颜色体积(以立方 Lab 单位为单位)来比较。 下表检查了 CSS 中可用的预定义颜色空间。
颜色空间 | 体积(百万 Lab 单位) |
---|---|
sRGB | 0.820 |
display-p3 | 1.233 |
a98-rgb | 1.310 |
prophoto-rgb | 2.896 |
rec2020 | 2.042 |
CSS 中的颜色要么是无效颜色, 如下所述的每种语法形式, 要么是有效颜色。
任何不是无效颜色的颜色都是有效颜色。
某些颜色可以是有效颜色, 但仍然超出输出设备(屏幕、投影仪或打印机)可以产生的颜色范围。
这种情况称为超出色域。
每个有效颜色要么对于特定输出设备(屏幕或打印机)在色域内, 要么超出色域。
color ( prophoto-rgb0.88 0.45 0.10 )
因为,在 display-p3 中表示时, 一个或多个坐标要么大于 1.0,要么小于 0.0:
color ( display-p31.0844 0.43 0.1 )
此颜色是有效的, 例如,它可以用作渐变的停止点, 但需要进行CSS 色域映射, 以便显示,从而产生看起来相似但色度较低(饱和度较低)的颜色。
3. 在 CSS 中应用颜色
3.1. 可访问性与通过颜色传达信息
测试
本节提供编写指导,不需要测试。
虽然颜色可以为文档增加重要信息并提高其可读性, 但颜色本身不应成为传达重要信息的唯一手段。 作者在文档中使用颜色时应考虑 W3C Web 内容可访问性指南 [WCAG21]。
3.2. 前景颜色:color 属性
名称: | color |
---|---|
值: | <color> |
初始值: | CanvasText |
适用于: | 所有元素和文本 |
继承: | 是 |
百分比: | N/A |
计算值: | 计算的颜色,参见解析颜色值 |
规范顺序: | 按语法 |
动画类型: | 按计算值类型 |
测试
此属性指定元素的主要前景颜色。 它用作文本内容的填充颜色, 并且还指定了 使用的值,currentcolor 将解析为该值, 这允许间接引用该前景颜色,并影响其他各种颜色属性的初始值, 如 border-color 和 text-emphasis-color。
- <color>
- 将主要前景颜色设置为指定的 <color>。
em{ color : lime; } /* 颜色关键字 */ em{ color : rgb ( 0 255 0 ); } /* RGB 范围 0-255 */ em{ color : rgb ( 0 % 100 % 0 % ); } /* RGB 范围 0%-100% */ em{ color : color ( sRGB0 1 0 ); } /* sRGB 范围 0.0-1.0 */
当应用于文本时,此属性(包括其 alpha 分量)对“彩色字形”没有影响(例如某些字体中的表情符号),这些字形由内置调色板着色。
然而,一些彩色字体能够引用上下文“前景色”,
例如 OpenType 的 COLR
表中的调色板条目 0xFFFF,
或者 SVG-in-OpenType 中的 context-fill 值。
在这种情况下,前景色由此属性设置,与设置 currentcolor 值相同。
3.3. 透明度:opacity 属性
透明度可以被看作是后处理操作。 从概念上讲,在元素(包括其子元素)被渲染为 RGBA 离屏图像后, 透明度设置指定如何将离屏渲染与当前的合成渲染进行混合。 详情见简单的 alpha 合成。
名称: | opacity |
---|---|
值: | <opacity-value> |
初始值: | 1 |
适用于: | 所有元素 |
继承: | 否 |
百分比: | 映射到范围 [0,1] |
计算值: | 指定的数值,限定在 [0,1] 范围内 |
规范顺序: | 按语法 |
动画类型: | 按计算值类型 |
测试
- clip-opacity-out-of-flow.html (实时测试) (来源)
- t32-opacity-basic-0.0-a.xht (实时测试) (来源)
- t32-opacity-basic-0.6-a.xht (实时测试) (来源)
- t32-opacity-basic-1.0-a.xht (实时测试) (来源)
- t32-opacity-clamping-0.0-b.xht (实时测试) (来源)
- t32-opacity-clamping-1.0-b.xht (实时测试) (来源)
- t32-opacity-offscreen-b.xht (实时测试) (来源)
- t32-opacity-offscreen-multiple-boxes-1-c.xht (实时测试) (来源)
- t32-opacity-offscreen-multiple-boxes-2-c.xht (实时测试) (来源)
- t32-opacity-offscreen-with-alpha-c.xht (实时测试) (来源)
- t32-opacity-zorder-c.xht (实时测试) (来源)
- opacity-computed.html (实时测试) (来源)
- opacity-valid.html (实时测试) (来源)
- opacity-invalid.html (实时测试) (来源)
- composited-filters-under-opacity.html (实时测试) (来源)
- filters-under-will-change-opacity.html (实时测试) (来源)
- color-composition.html (实时测试) (来源)
- opacity-interpolation.html (实时测试) (来源)
- canvas-change-opacity.html (实时测试) (来源)
- opacity-animation-ending-correctly-001.html (实时测试) (来源)
- opacity-animation-ending-correctly-002.html (实时测试) (来源)
- <不透明度值>
-
应用于元素的透明度。
最终的透明度应用于整个元素,而不是某个特定颜色。
透明度值超出范围 [0,1] 并非无效,且在指定值中会被保留, 但在计算值中会被限定在 [0, 1] 范围内。
CSS 中的不透明度使用 <opacity-value> 语法表示, 例如在 opacity 属性中。
<opacity-value> = <number> | <percentage>
表示为 <number> 时, 其值的有效范围是 0(表示完全透明) 到 1(表示完全不透明)。 它也可以写成 <percentage>, 其计算结果为等效的 <number>(0% 对应 0,100% 对应 1)。
opacity 属性将指定的不透明度应用于元素 整体, 包括其内容,而不是单独应用于每个子元素。 这意味着,例如,即使 opacity 小于 1, 遮挡部分背景的不透明子元素仍然会继续遮挡,但元素和子元素作为一个整体将显示底层页面。
这也意味着, 元素中所有字符的字形都被 作为一个整体 处理; 任何重叠部分都不会增加不透明度。
如果希望每个字形具有不同的不透明度, 可以通过使用包含 alpha 通道的颜色值来实现, 而不是设置 opacity 属性。
如果一个盒子具有小于 1 的 opacity, 它会为其子元素形成一个堆叠上下文。 (这可以防止其内容在 z 轴上与外部内容交错。)
此外,如果 z-index 属性应用于盒子, 则该元素的 auto 值被视为 0; 否则它会在其父堆叠上下文中与具有堆叠级别 0 的定位元素在同一层上绘制 (就好像它是具有 z-index:0 的定位元素一样)。
更多关于堆叠上下文的信息,请参阅 第 9.9 节 和 附录 E,参见 [CSS2]。
这些关于堆叠顺序的规则不适用于 SVG 元素, 因为 SVG 有其自己的 渲染模型([SVG11],第 3 章)。
3.4. 标记图像的颜色空间
标记图像是指显式分配了颜色配置文件的图像, 由图像格式定义。 这通常通过包含国际色彩联盟(ICC)配置文件来完成 [ICC]。
例如,JPEG [JPEG]、PNG [PNG] 和 TIFF [TIFF] 都指定了一种嵌入 ICC 配置文件的方法。
图像格式也可以使用其他等效的方法,通常是为了简洁。
例如,PNG 指定了一种方法(sRGB 块), 用于显式地将图像标记为 sRGB 颜色空间, 而无需包含 sRGB ICC 配置文件。
类似地,PNG 指定了一种紧凑的方法 (cICP 块), 用于显式地将图像标记为各种 SDR 或 HDR 颜色空间之一, 例如 Display P3 或 BT.2100 HLG, 而无需包含 ICC 配置文件。
标记的 RGB 图像, 以及使用 RGB 转换(如 YCbCr)的标记图像, 如果颜色配置文件或其他识别信息有效, 必须被视为处于指定的颜色空间中。
测试
例如,当运行在具有 Display P3 显示器的系统上的浏览器显示一个标记为 ITU Rec BT.2020 [Rec.2020] 色彩空间的 JPEG 图像时,必须将颜色从 ITU Rec BT.2020 转换为 Display P3,以便正确显示。不能将 ITU Rec BT.2020 值视为 Display P3 值,否则会产生错误的颜色。
如果颜色配置文件或其他标识信息无效,则图像将按照未标记图像的描述进行处理。
3.5. 未标记颜色的色彩空间
为了兼容性,HTML 中指定的颜色 以及未标记图像必须被视为 处于 sRGB 色彩空间([SRGB]) 除非另有规定。
未标记图像是指未根据图像格式定义明确指定颜色配置文件的图像。
此规则不适用于未标记视频,因为未标记视频应假定采用 ITU 定义的色彩空间。
-
低于 720p 时,使用 Recommendation ITU-R BT.601 [ITU-R-BT.601]
-
720p 时,使用 SMPTE ST 296(与 709 具有相同的色彩学) [SMPTE296]
-
1080p 时,使用 Recommendation ITU-R BT.709 [ITU-R-BT.709]
-
4k (UHDTV) 及更高分辨率时,使用 ITU-R BT.2020 [Rec.2020] 用于 SDR 视频
4. 表示颜色: <color> 类型
测试
本节描述了一种类型,主要在使用该类型的地方进行测试。
CSS 中的颜色表示为颜色分量列表, 有时也称为“通道”, 代表色彩空间中的轴。 每个分量都有一个最小值和最大值, 并且可以取这两个值之间的任何值。 此外,每种颜色都附带一个 Alpha 分量, 指示其透明程度, 从而指示可以通过颜色看到多少背景。
CSS 有多种指定颜色值的语法:
-
sRGB 十六进制颜色表示法,它以十六进制表示法表示 RGB 和 Alpha 分量
-
各种颜色函数,可以使用各种色彩空间和坐标系表示颜色
-
常量命名颜色关键字
-
变量<system-color>关键字和currentColor关键字。
颜色函数使用 CSS 函数表示法通过指定其分量坐标来表示各种色彩空间中的颜色。 其中一些使用圆柱极坐标颜色模型, 通过<hue>角度、代表亮度 (黑到白)的中心轴, 以及代表饱和度或色度 (颜色与中性灰色的距离)的半径来指定颜色。 其他的则使用矩形正交颜色模型, 使用三个正交分量轴指定颜色。
第 4 级中可用的颜色函数有:
-
rgb() 及其别名 rgba(), 它们(类似于十六进制颜色表示法)通过其红/绿/蓝/Alpha 分量直接指定 sRGB 颜色。
-
lab(), 它使用 CIE LAB 矩形坐标模型通过 CIE 亮度和其 a 轴和 b 轴色相坐标(红/绿度 和 黄/蓝度)指定 CIELAB 颜色。
-
lch(), 它使用 CIE LCH 圆柱坐标模型通过 CIE 亮度、色度和色相指定 CIELAB 颜色。
-
oklab(), 它使用 Oklab 矩形坐标模型通过 Oklab 亮度和其 a 轴和 b 轴色相坐标(红/绿度 和 黄/蓝度)指定 Oklab 颜色。
-
color(), 它允许在各种色彩空间中指定颜色, 包括 sRGB、线性光 sRGB、Display P3、A98 RGB、ProPhoto RGB、ITU-R BT.2020-2 和 CIE XYZ。
为了方便在其他规范中参考,不透明黑色定义为颜色 rgb(0 0 0 / 100%);透明黑色是相同的颜色, 但完全透明——即 rgb(0 0 0 / 0%)。
测试
4.1. <color> 语法
测试
本节提供稍后使用的定义,不需要测试。
在 CSS 中,颜色由 <color> 类型表示:
<color> = <color-base> | currentColor | <system-color> <color-base> = <hex-color> | <color-function> | <named-color> | transparent <color-function> = <rgb () > | <rgba () > | <hsl () > | <hsla () > | <hwb () > | <lab () > | <lch () > | <oklab () > | <oklch () > | <color () >
绝对颜色是一个 <color>,其计算值具有绝对的、色度学解释。这意味着该值不是:
-
currentColor(它取决于 color 属性的值)
-
一个 <system-color>(它取决于颜色模式)
解析为 sRGB 的颜色有:
支持旧版颜色语法的函数有:
<hsl()>、<hsla()>、<hwb()>、<lch()> 和 <oklch()> 颜色函数是使用 <hue> 角度的圆柱极坐标颜色表示法; 其他颜色函数使用矩形正交颜色表示法。
4.1.1. 现代(空格分隔)颜色函数语法
本规范中首次定义的所有绝对颜色函数形式 都使用现代颜色语法, 这意味着:
-
颜色分量由空格分隔
-
可选的 alpha 项由斜杠 (“/”) 分隔
-
序列化时的最低所需精度已定义, 并且可能大于每个分量 8 位
-
使用 <percentage> 和 <number> 的分量可以自由混合
4.1.2. 传统(逗号分隔)颜色函数语法
为了 Web 兼容性, rgb()、rgba()、hsl() 和 hsla() 的语法形式 (在早期规范中定义的那些) 也支持一种旧版颜色语法,它具有以下区别:
-
颜色分量用逗号分隔 (可选地在前面和/或后面加上空格)
-
非不透明形式使用单独的表示法 (例如 hsla() 而不是 hsl()) 并且 alpha 项用逗号分隔 (可选地在前面和/或后面加上空格)
-
最低所需精度较低,每个分量 8 位
-
不允许使用 none 值
-
颜色分量必须全部使用 <percentage> 或全部使用 <number> 来指定,它们不能混合使用。
对于本级别或随后的级别中引入的 颜色函数,在没有 Web 兼容性问题的情况下,传统颜色语法是无效的。
4.2. 表示颜色中的透明度:<alpha-value> 语法
测试
本节提供后续使用的定义,不需要测试。
<alpha-value> = <number> | <percentage>
除非另有规定,颜色的 <alpha-value> 组件在省略时默认为 100%。超出范围 [0,1] 的值不是无效的,但在解析值时会被限制在该范围内。
4.3. 表示圆柱坐标色相:<hue> 语法
测试
本节提供后续使用的定义,不需要测试。
色相表示为颜色圆的一个角度(将彩虹扭曲成一个圆,并在紫色和红色之间加入紫红色)。
<hue> = <number> | <angle>
由于这个值通常以度数给出,参数也可以用数字表示,这个数字被解释为度数,是 标准单位。
这个数字被标准化为范围 [0,360)。
在 hsl(360 0 0) 中,<hue> 分量被标准化为 0 度。
在 hsl(calc(-infinity) 0 0) 或 hsl(calc(infinity) 0 0) 中, <hue> 分量再次被标准化为 0 度。
注意: 特定色相对应的角度和间距取决于色彩空间。例如,在使用 sRGB 色彩空间的 HSL 和 HWB 中,sRGB 的绿色是 120 度。在 LCH 中,sRGB 绿色是 134.39 度,display-p3 绿色是 136.01 度,a98-rgb 绿色是 145.97 度,prophoto-rgb 绿色是 141.04 度(因为这些都是不同的绿色阴影)。
<hue> 分量是最常变为无效的颜色分量; 任何足够接近中心非彩色轴的颜色 都将具有无效的色相分量。
4.4. “缺失”的颜色组件和 none 关键字
在某些情况下,颜色可能有一个或多个 缺失的颜色组件。
在本规范中,由于某些颜色的 基于色相的插值,这种情况会自动发生(例如 白色);其他规范可以定义组件自动缺失的其他情况。
也可以显式指定,通过在颜色函数中为组件提供关键字 none。所有颜色函数(使用 传统颜色语法 的除外)允许其组件中的任意一个被指定为 none。
这应该谨慎使用,只有在需要特定效果时才应这样做。
测试
- color-computed-color-function.html (实时测试) (来源)
- color-computed-hsl.html (实时测试) (来源)
- color-computed-hwb.html (实时测试) (来源)
- color-computed-lab.html (实时测试) (来源)
- color-computed-relative-color.html (实时测试) (来源)
- color-computed-rgb.html (实时测试) (来源)
- color-invalid-hsl.html (实时测试) (来源)
- color-invalid-rgb.html (实时测试) (来源)
- color-valid-color-function.html (实时测试) (来源)
- color-valid-color-mix-function.html (实时测试) (来源)
- color-valid-hsl.html (实时测试) (来源)
- color-valid-hwb.html (实时测试) (来源)
- color-valid-lab.html (实时测试) (来源)
- color-valid-relative-color.html (实时测试) (来源)
- color-valid-rgb.html (实时测试) (来源)
有关在颜色插值等组合两种颜色的情况下处理缺失分量的信息, 请参阅 § 12.2 使用缺失分量进行插值。
对于其他所有用途,缺失组件表现为零值,采用该组件的适当单位:0,0%,或0deg。这包括直接渲染颜色、将其转换为其他颜色空间、对颜色组件值执行计算等。
如果带有缺失组件的颜色被序列化或直接呈现给作者,对于传统颜色语法,其表示该组件为零值;否则,则表示该组件为none关键字。
结果将是一个真正看起来像绿色和白色混合的颜色,而不是看起来略带红色(如果将白色的色相默认为0deg)。
例如,要将一种颜色动画化为“灰度”,无论该颜色是什么,可以将其与oklch(none 0 none)进行插值。这将从起始颜色中获取色相和亮度,但将其色度动画化为0,使其在整个动画中保持均匀亮度的灰色。
手动执行此操作将需要显式匹配起始颜色的色相和亮度。
4.4.1. “无效”颜色组件
个别颜色语法可以指定,在某些情况下,它们的语法中的某个组件会成为无效颜色组件。这表明该组件的值不会影响渲染的颜色;无论你赋予它什么值,屏幕上显示的颜色都是相同的。
例如,在hsl()中,当饱和度组件为0%时,色相组件是无效的;0%的饱和度表示灰度颜色,它根本没有色相,因此0deg和180deg或任何其他角度,都会得到完全相同的结果。
如果手动指定了无效分量, 则其行为正常; 其无效的事实没有任何影响。
但是,如果颜色是通过色彩空间转换自动生成的, 则结果中的任何无效分量都必须设置为缺失, 而不是转换过程中产生的任何值。
当执行到圆柱极坐标色彩空间的色彩空间转换时, 如果色度(或其他色彩度量,例如 hsl 中的饱和度) 小于为该色彩空间指定的 epsilon (ε),则用户代理必须将色相分量视为无效。 例如,由于数值误差, 转换为 oklch() 的灰色可能具有极小的色度,而不是精确的 0%; 因此,色相分量是无效的。
4.5. 解析 <color> 值
测试
本节提供了一个在其他地方引用的定义,不需要测试。
注意:此算法并非旨在解析 CSS 样式表或 CSSOM 接口中指定的 CSS <color> 值,而是在 HTML 属性或 Canvas 接口等其他地方使用。
5. sRGB 颜色
CSS 中位于 sRGB 色彩空间内的颜色通过三元值来表示——红、绿和蓝——标识 sRGB 色彩空间中的一个点 [SRGB]。 这是一种国际公认的设备无关的色彩空间,因此适用于指定在计算机屏幕上显示的颜色,也适用于在其他类型的设备(如打印机)上指定颜色。
CSS 也允许使用非 sRGB 的 色彩空间,如 第 10 节 预定义的色彩空间 中所述。
CSS 提供了几种直接指定 sRGB 颜色的方法:十六进制颜色、rgb()/rgba() 颜色函数、hsl()/hsla() 颜色函数、hwb() 颜色函数、命名颜色, 以及 transparent 关键字。
5.1. RGB 函数:rgb() 和 rgba()
rgb() 和 rgba() 函数通过直接指定 r、g 和 b(红、绿、蓝)分量来定义 sRGB 颜色。 它们的语法是:
rgb () =[ <legacy-rgb-syntax> | <modern-rgb-syntax>] rgba () =[ <legacy-rgba-syntax> | <modern-rgba-syntax>] <legacy-rgb-syntax> =rgb ( <percentage>#{ 3 } , <alpha-value>?) |rgb ( <number>#{ 3 } , <alpha-value>?) <legacy-rgba-syntax> =rgba ( <percentage>#{ 3 } , <alpha-value>?) |rgba ( <number>#{ 3 } , <alpha-value>?) <modern-rgb-syntax> =rgb ( [ <number> | <percentage> | none] { 3 } [ /[ <alpha-value> | none] ] ?) <modern-rgba-syntax> =rgba ( [ <number> | <percentage> | none] { 3 } [ /[ <alpha-value> | none] ] ?)
百分比 | 适用于 r、g 和 b |
---|---|
百分比参考范围 | 对于 r、g 和 b:0% = 0.0,100% = 255.0 对于 alpha:0% = 0.0,100% = 1.0 |
测试
- rgb-001.html (实时测试) (来源)
- rgb-002.html (实时测试) (来源)
- rgb-003.html (实时测试) (来源)
- rgb-004.html (实时测试) (来源)
- rgb-005.html (实时测试) (来源)
- rgb-006.html (实时测试) (来源)
- rgb-007.html (实时测试) (来源)
- rgb-008.html (实时测试) (来源)
- out-of-gamut-legacy-rgb.html (实时测试) (来源)
- color-valid.html (实时测试) (来源)
- color-computed-rgb.html (实时测试) (来源)
- color-invalid-rgb.html (实时测试) (来源)
- color-valid-rgb.html (实时测试) (来源)
前三个参数分别指定颜色的 r、g 和 b(红、绿、蓝)分量。 0% 表示 sRGB 色域中该颜色分量的最小值, 100% 表示最大值。
颜色分量的百分比参考范围源于这样一个历史事实:许多图形引擎在内部将颜色分量存储为单个字节, 该字节可以容纳 0 到 255 之间的整数。 实现应尽可能遵循创作或计算的分量精度。 如果无法做到,则应将分量向 +∞ 舍入。
最后一个参数 <alpha-value> 指定颜色的 Alpha 值。 如果省略,则默认为 100%。
测试
超出这些范围的值并非无效, 而是在解析值时被限制在此处定义的范围内。
由于历史原因,rgb() 和 rgba() 也支持旧版颜色语法。
测试
5.2. RGB 十六进制表示法:#RRGGBB
CSS 十六进制颜色表示法允许通过将分量指定为十六进制数来指定 sRGB 颜色, 这与颜色通常在计算机代码中直接编写的方式类似。 它也比用 rgb() 表示法写出相同的颜色要短。
<hex-color> 的语法是一个 <hash-token> 标记,其值由 3、4、6 或 8 个十六进制数字组成。 换句话说,十六进制颜色写为一个哈希字符“#”, 后跟一些数字 0-9 或字母 a-f (字母的大小写无关紧要 - #00ff00 与 #00FF00 相同)。
给定的十六进制数字的数量决定了如何将十六进制表示法解码为 RGB 颜色:
- 6 位数字
- 第一对数字,解释为十六进制数, 指定颜色的红色分量, 其中 00 表示最小值, ff(十进制的 255)表示最大值。 下一对数字,以相同的方式解释, 指定绿色分量, 最后一对指定蓝色分量。 颜色的 Alpha 分量是完全不透明的。
- 8 位数字
- 前 6 位数字的解释与 6 位数字表示法相同。 最后一对数字,解释为十六进制数, 指定颜色的 Alpha 分量, 其中 00 表示完全透明的颜色, ff 表示完全不透明的颜色。
- 3 位数字
- 这是 6 位数字表示法的一种较短的变体。 第一个数字,解释为十六进制数, 指定颜色的红色分量, 其中 0 表示最小值, f 表示最大值。 接下来的两个数字分别以相同的方式表示绿色和蓝色分量。 颜色的 Alpha 分量是完全不透明的。
- 4 位数字
- 这是 8 位数字表示法的一种较短的变体, 其“扩展”方式与 3 位数字表示法相同。 第一个数字,解释为十六进制数, 指定颜色的红色分量, 其中 0 表示最小值, f 表示最大值。 接下来的三个数字分别表示绿色、蓝色和 Alpha 分量。
测试
- hex-001.html (实时测试) (来源)
- hex-002.html (实时测试) (来源)
- hex-003.html (实时测试) (来源)
- hex-004.html (实时测试) (来源)
- border-bottom-color.xht (实时测试) (来源)
- border-left-color.xht (实时测试) (来源)
- border-right-color.xht (实时测试) (来源)
- border-top-color.xht (实时测试) (来源)
- color-valid.html (实时测试) (来源)
- color-computed-hex-color.html (实时测试) (来源)
- color-invalid-hex-color.html (实时测试) (来源)
6. 颜色关键词
除了 <color> 的各种数字语法外, CSS 还定义了几组颜色关键字,可以替代使用——每组都有其自身的优点或用例。
6.1. 命名颜色
CSS 定义了一组 命名颜色,这样常见的颜色可以更容易地书写和阅读。 一个 <named-color> 以 <ident> 的形式编写,任何需要 <color> 的地方都接受这种形式。 对于 CSS 定义的 <ident>,所有这些关键词都是 ASCII 大小写不敏感的。
这些名字解析为 sRGB 颜色。
CSS 的 16 个命名颜色最初来自 VGA 调色板,后来被 HTML 采用:aqua、black、blue、fuchsia、gray、green、lime、maroon、navy、olive、purple、red、silver、teal、white 和 yellow。 其余大部分颜色来自 X11 颜色系统的一个版本,该系统用于 Unix 衍生系统的控制台颜色指定,后来被 SVG 采用。
注意:这些颜色名称在这里被标准化,不是因为它们好,而是因为它们的使用和实现已经存在了几十年,标准需要反映现实。 实际上,很难想象每个名字对应的颜色是什么(因此有下面的列表);这些名字在 sRGB 色彩空间中的分布并不均匀,甚至它们内部也不一致( darkgray 比 gray 更亮,而 lightpink 却比 pink 更暗), 并且一些名字(例如 indianred,最初是以来自印度的红色颜料命名的)被发现具有冒犯性。因此,不建议使用它们。
(两个特殊的颜色值 transparent 和 currentcolor 在各自的章节中有特殊定义。)
下表定义了所有不透明的命名颜色,通过给出其他颜色语法的等价数值表示。
命名 | 数值 | 颜色名称 | 十六进制 RGB | 十进制 |
---|---|---|---|---|
aliceblue | #f0f8ff | 240 248 255 | ||
antiquewhite | #faebd7 | 250 235 215 | ||
aqua | #00ffff | 0 255 255 | ||
aquamarine | #7fffd4 | 127 255 212 | ||
azure | #f0ffff | 240 255 255 | ||
beige | #f5f5dc | 245 245 220 | ||
bisque | #ffe4c4 | 255 228 196 | ||
black | #000000 | 0 0 0 | ||
blanchedalmond | #ffebcd | 255 235 205 | ||
blue | #0000ff | 0 0 255 | ||
blueviolet | #8a2be2 | 138 43 226 | ||
brown | #a52a2a | 165 42 42 | ||
burlywood | #deb887 | 222 184 135 | ||
cadetblue | #5f9ea0 | 95 158 160 | ||
chartreuse | #7fff00 | 127 255 0 | ||
chocolate | #d2691e | 210 105 30 | ||
coral | #ff7f50 | 255 127 80 | ||
cornflowerblue | #6495ed | 100 149 237 | ||
cornsilk | #fff8dc | 255 248 220 | ||
crimson | #dc143c | 220 20 60 | ||
cyan | #00ffff | 0 255 255 | ||
darkblue | #00008b | 0 0 139 | ||
darkcyan | #008b8b | 0 139 139 | ||
darkgoldenrod | #b8860b | 184 134 11 | ||
darkgray | #a9a9a9 | 169 169 169 | ||
darkgreen | #006400 | 0 100 0 | ||
darkgrey | #a9a9a9 | 169 169 169 | ||
darkkhaki | #bdb76b | 189 183 107 | ||
darkmagenta | #8b008b | 139 0 139 | ||
darkolivegreen | #556b2f | 85 107 47 | ||
darkorange | #ff8c00 | 255 140 0 | ||
darkorchid | #9932cc | 153 50 204 | ||
darkred | #8b0000 | 139 0 0 | ||
darksalmon | #e9967a | 233 150 122 | ||
darkseagreen | #8fbc8f | 143 188 143 | ||
darkslateblue | #483d8b | 72 61 139 | ||
darkslategray | #2f4f4f | 47 79 79 | ||
darkslategrey | #2f4f4f | 47 79 79 | ||
darkturquoise | #00ced1 | 0 206 209 | ||
darkviolet | #9400d3 | 148 0 211 | ||
deeppink | #ff1493 | 255 20 147 | ||
deepskyblue | #00bfff | 0 191 255 | ||
dimgray | #696969 | 105 105 105 | ||
dimgrey | #696969 | 105 105 105 | ||
dodgerblue | #1e90ff | 30 144 255 | ||
firebrick | #b22222 | 178 34 34 | ||
floralwhite | #fffaf0 | 255 250 240 | ||
forestgreen | #228b22 | 34 139 34 | ||
fuchsia | #ff00ff | 255 0 255 | ||
gainsboro | #dcdcdc | 220 220 220 | ||
ghostwhite | #f8f8ff | 248 248 255 | ||
gold | #ffd700 | 255 215 0 | ||
goldenrod | #daa520 | 218 165 32 | ||
gray | #808080 | 128 128 128 | ||
green | #008000 | 0 128 0 | ||
greenyellow | #adff2f | 173 255 47 | ||
grey | #808080 | 128 128 128 | ||
honeydew | #f0fff0 | 240 255 240 | ||
hotpink | #ff69b4 | 255 105 180 | ||
indianred | #cd5c5c | 205 92 92 | ||
indigo | #4b0082 | 75 0 130 | ||
ivory | #fffff0 | 255 255 240 | ||
khaki | #f0e68c | 240 230 140 | ||
lavender | #e6e6fa | 230 230 250 | ||
lavenderblush | #fff0f5 | 255 240 245 | ||
lawngreen | #7cfc00 | 124 252 0 | ||
lemonchiffon | #fffacd | 255 250 205 | ||
lightblue | #add8e6 | 173 216 230 | ||
lightcoral | #f08080 | 240 128 128 | ||
lightcyan | #e0ffff | 224 255 255 | ||
lightgoldenrodyellow | #fafad2 | 250 250 210 | ||
lightgray | #d3d3d3 | 211 211 211 | ||
lightgreen | #90ee90 | 144 238 144 | ||
lightgrey | #d3d3d3 | 211 211 211 | ||
lightpink | #ffb6c1 | 255 182 193 | ||
lightsalmon | #ffa07a | 255 160 122 | ||
lightseagreen | #20b2aa | 32 178 170 | ||
lightskyblue | #87cefa | 135 206 250 | ||
lightslategray | #778899 | 119 136 153 | ||
lightslategrey | #778899 | 119 136 153 | ||
lightsteelblue | #b0c4de | 176 196 222 | ||
lightyellow | #ffffe0 | 255 255 224 | ||
lime | #00ff00 | 0 255 0 | ||
limegreen | #32cd32 | 50 205 50 | ||
linen | #faf0e6 | 250 240 230 | ||
magenta | #ff00ff | 255 0 255 | ||
maroon | #800000 | 128 0 0 | ||
mediumaquamarine | #66cdaa | 102 205 170 | ||
mediumblue | #0000cd | 0 0 205 | ||
mediumorchid | #ba55d3 | 186 85 211 | ||
mediumpurple | #9370db | 147 112 219 | ||
mediumseagreen | #3cb371 | 60 179 113 | ||
mediumslateblue | #7b68ee | 123 104 238 | ||
mediumspringgreen | #00fa9a | 0 250 154 | ||
mediumturquoise | #48d1cc | 72 209 204 | ||
mediumvioletred | #c71585 | 199 21 133 | ||
midnightblue | #191970 | 25 25 112 | ||
mintcream | #f5fffa | 245 255 250 | ||
mistyrose | #ffe4e1 | 255 228 225 | ||
moccasin | #ffe4b5 | 255 228 181 | ||
navajowhite | #ffdead | 255 222 173 | ||
navy | #000080 | 0 0 128 | ||
oldlace | #fdf5e6 | 253 245 230 | ||
olive | #808000 | 128 128 0 | ||
olivedrab | #6b8e23 | 107 142 35 | ||
orange | #ffa500 | 255 165 0 | ||
orangered | #ff4500 | 255 69 0 | ||
orchid | #da70d6 | 218 112 214 | ||
palegoldenrod | #eee8aa | 238 232 170 | ||
palegreen | #98fb98 | 152 251 152 | ||
paleturquoise | #afeeee | 175 238 238 | ||
palevioletred | #db7093 | 219 112 147 | ||
papayawhip | #ffefd5 | 255 239 213 | ||
peachpuff | #ffdab9 | 255 218 185 | ||
peru | #cd853f | 205 133 63 | ||
pink | #ffc0cb | 255 192 203 | ||
plum | #dda0dd | 221 160 221 | ||
powderblue | #b0e0e6 | 176 224 230 | ||
purple | #800080 | 128 0 128 | ||
rebeccapurple | #663399 | 102 51 153 | ||
red | #ff0000 | 255 0 0 | ||
rosybrown | #bc8f8f | 188 143 143 | ||
royalblue | #4169e1 | 65 105 225 | ||
saddlebrown | #8b4513 | 139 69 19 | ||
salmon | #fa8072 | 250 128 114 | ||
sandybrown | #f4a460 | 244 164 96 | ||
seagreen | #2e8b57 | 46 139 87 | ||
seashell | #fff5ee | 255 245 238 | ||
sienna | #a0522d | 160 82 45 | ||
silver | #c0c0c0 | 192 192 192 | ||
skyblue | #87ceeb | 135 206 235 | ||
slateblue | #6a5acd | 106 90 205 | ||
slategray | #708090 | 112 128 144 | ||
slategrey | #708090 | 112 128 144 | ||
snow | #fffafa | 255 250 250 | ||
springgreen | #00ff7f | 0 255 127 | ||
steelblue | #4682b4 | 70 130 180 | ||
tan | #d2b48c | 210 180 140 | ||
teal | #008080 | 0 128 128 | ||
thistle | #d8bfd8 | 216 191 216 | ||
tomato | #ff6347 | 255 99 71 | ||
turquoise | #40e0d0 | 64 224 208 | ||
violet | #ee82ee | 238 130 238 | ||
wheat | #f5deb3 | 245 222 179 | ||
white | #ffffff | 255 255 255 | ||
whitesmoke | #f5f5f5 | 245 245 245 | ||
yellow | #ffff00 | 255 255 0 | ||
yellowgreen | #9acd32 | 154 205 50 |
注意:此颜色列表及其定义是 SVG 1.1 定义的命名颜色 列表的超集。
为了历史原因,这也被称为 X11 颜色集。注意: X11 颜色系统的历史非常有趣,并由 Alex Sexton 在其演讲 “Peachpuffs and Lemonchiffons” 中做了极好的总结。
测试
6.2. 系统颜色
通常,<系统颜色>关键字反映了用户、浏览器或操作系统做出的默认颜色选择。因此,它们通常在浏览器的默认样式表中使用。
为了保持可读性,<系统颜色>关键字也会响应亮模式或暗模式的变化。
可读链接文本
不可读链接文本
可读链接文本
然而,在强制颜色模式下,页面上的大多数颜色会被强制转换为用户选择的受限调色板。<系统颜色>关键字会暴露这些用户选择的颜色,以便页面的其他部分能够与受限的调色板融合。
当强制颜色 媒体特性 激活时,作者应该使用<系统颜色>关键字作为属性中的颜色值,这些属性除外,请参考CSS 颜色调整 1 § 3.1 被强制颜色模式影响的属性,以确保页面的可读性和一致性,避免用户强制颜色和页面选择颜色的混乱拼凑。
测试
当<系统颜色>关键字的值来自浏览器(而不是作为操作系统的默认值或用户选择)时,浏览器应确保匹配的前景/背景对具有最小的WCAG AA对比度。然而,用户偏好(无论是更高还是更低的对比度),无论是作为浏览器偏好设置、用户样式表设置,还是通过更改操作系统的默认设置,必须优先于此要求。
作者也可以随时使用这些关键字,但应该小心使用匹配的背景-前景对来确保适当的对比度,因为跨不匹配对的特定对比关系(例如,Canvas和ButtonText)不保证。
<系统颜色>关键字定义如下:
- AccentColor
- 突出显示的用户界面控件的背景。
- AccentColorText
- 突出显示的用户界面控件的文本。
- ActiveText
- 活动链接中的文本。对于浅色背景,通常为红色。
- ButtonBorder
- 按钮的边框颜色。
- ButtonFace
- 按钮的表面背景颜色。
- ButtonText
- 按钮上的文本。
- Canvas
- 应用程序内容或文档的背景。
- CanvasText
- 应用程序内容或文档中的文本。
- Field
- 输入字段的背景。
- FieldText
- 输入字段中的文本。
- GrayText
- 禁用文本。(通常,但不一定是灰色。)
- Highlight
- 选中文本的背景,例如来自::selection。
- HighlightText
- 选中文本的文本。
- LinkText
- 非活动、未访问链接中的文本。对于浅色背景,通常为蓝色。
- Mark
- 被特别标记的文本的背景(例如通过HTML
mark
元素)。 - MarkText
- 被特别标记的文本(例如通过HTML
mark
元素)。 - SelectedItem
- 选中项的背景,例如选中的复选框。
- SelectedItemText
- 选中项的文本。
- VisitedText
- 已访问链接中的文本。对于浅色背景,通常为紫色。
测试
注意:与所有其他关键字一样,这些名称是ASCII 大小写不敏感的。它们在这里以混合大小写显示以便于阅读。
对于没有特定系统 UI 概念的系统,指定的值应映射到最接近的相关系统颜色值。以下系统颜色配对预计将形成可读的背景-前景颜色:
-
Canvas背景与ButtonBorder边框以及相邻颜色Canvas
-
ButtonFace背景与ButtonText前景配对。
-
ButtonFace或Field背景与ButtonBorder边框以及相邻颜色Canvas
-
Highlight背景与HighlightText前景配对。
-
SelectedItem背景与SelectedItemText前景配对。
-
AccentColor背景与AccentColorText前景配对。
此外,GrayText预计可以阅读,尽管对比度可能较低,在任何背景上都可以阅读。
Canvas 与 CanvasText:CanvasText
Canvas 与 LinkText:LinkText
Canvas 与 VisitedText:VisitedText
Canvas 与 ActiveText:ActiveText
Canvas 与 GrayText:GrayText
Canvas 与 ButtonBorder 以及相邻的 Canvas:CanvasText相邻
ButtonFace 与 ButtonText:ButtonText
ButtonFace 与 ButtonText 和 ButtonBorder:ButtonText
ButtonFace 与 GrayText:GrayText
Field 与 FieldText:FieldText
Field 与 GrayText:GrayText
Mark 与 MarkText:MarkText
Mark 与 GrayText:GrayText
Highlight 与 HighlightText:HighlightText
Highlight 与 GrayText:GrayText
SelectedItem 与 SelectedItemText:SelectedItemText
AccentColor 与 AccentColorText:AccentColorText
AccentColor 与 GrayText:GrayText
早期版本的CSS定义了其他<系统颜色>,这些已经被弃用。它们在附录A:弃用的CSS系统颜色中进行了记录。
注意:<系统颜色>存在一些隐私和安全风险,详见§ 21 隐私考虑和§ 20 安全考虑。
用户代理可以选择返回固定值以减轻隐私和安全风险(例如指纹识别),这些值不反映用户的自定义或主题选择。
6.3. transparent关键字
关键字transparent指定了透明黑。它是一种<named-color>。
测试
6.4. currentcolor关键字
关键字currentcolor表示同一元素上的color属性的值。与<named-color>不同,它不局限于 sRGB;该值可以是任何<color>。其使用值由解析颜色值来确定。
测试
- border-color-currentcolor.html (实时测试) (来源)
- color-mix-currentcolor-nested-for-color-property.html (实时测试) (来源)
- currentcolor-001.html (实时测试) (来源)
- currentcolor-002.html (实时测试) (来源)
- currentcolor-003.html (实时测试) (来源)
- currentcolor-004.html (实时测试) (来源)
- currentcolor-visited-fallback.html (实时测试) (来源)
- color-valid.html (实时测试) (来源)
.foo{ color : red; background-color : currentcolor; }
这相当于写成:
.foo{ color : red; background-color : red; }
< p >< em > Some< strong > really</ strong > emphasized text.</ em > < style > p { color : black ; } em { text-emphasis : dot ; } strong { color : red ; } </ style >
在上面的示例中,强调标记在文本 "Some" 和 "emphasized text" 上为黑色,但在文本 "really" 上为红色。
注意: 在 CSS 中,多词关键字通常用连字符分隔其组成单词。currentcolor没有这样做,因为(深呼吸)它最初在 SVG 中作为属性值 "current-color" 被引入,遵循通常的 CSS 拼写。随后,它(连同所有其他属性及其值)成为表现属性和属性值,以及属性,以使得使用 XSLT 的生成更容易。然后所有表现属性从连字符形式变为 camelCase,因为 DOM 对连字符表示“减号”有问题。但这样一来,它们就不再遵循 CSS 约定了,因此所有已经属于 CSS 的属性和属性值都改回了连字符形式!currentcolor当时并不属于 CSS,因此保留了 camelCase。后来 CSS 接受了它,此时由于 CSS 关键字是ASCII 大小写不敏感的,所以拼写方式不再重要。
7. HSL 颜色:hsl() 和 hsla() 函数
RGB 系统用于指定颜色, 对于机器和图形库来说很方便, 但通常被认为对人类来说很难直观地理解。 例如,很难知道如何改变 RGB 颜色以产生同一色调的较亮变体。
还有几种其他的颜色方案可行。 其中一种是 HSL [HSL] 颜色方案, 使用起来更直观, 但仍可以轻松映射回 RGB 颜色。
HSL 颜色是通过色相、饱和度和亮度三元组来指定的。 hsl() 和 hsla() 函数的语法是:
hsl () =[ <legacy-hsl-syntax> | <modern-hsl-syntax>] hsla () =[ <legacy-hsla-syntax> | <modern-hsla-syntax>] <modern-hsl-syntax> =hsl ( [ <hue> | none] [ <percentage> | <number> | none] [ <percentage> | <number> | none] [ /[ <alpha-value> | none] ] ?) <modern-hsla-syntax> =hsla ( [ <hue> | none] [ <percentage> | <number> | none] [ <percentage> | <number> | none] [ /[ <alpha-value> | none] ] ?) <legacy-hsl-syntax> =hsl ( <hue>, <percentage>, <percentage>, <alpha-value>?) <legacy-hsla-syntax> =hsla ( <hue>, <percentage>, <percentage>, <alpha-value>?)
百分比 | 适用于 S 和 L |
---|---|
百分比参考范围 | 对于 S 和 L:0% = 0.0,100% = 100.0 |
无效色相 ε | S <= 0.001 |
测试
- hsl-001.html (实时测试) (来源)
- hsl-002.html (实时测试) (来源)
- hsl-003.html (实时测试) (来源)
- hsl-004.html (实时测试) (来源)
- hsl-005.html (实时测试) (来源)
- hsl-006.html (实时测试) (来源)
- hsl-007.html (实时测试) (来源)
- hsl-008.html (实时测试) (来源)
- hsl-clamp-negative-saturation.html (实时测试) (来源)
- background-color-hsl-001.html (实时测试) (来源)
- background-color-hsl-002.html (实时测试) (来源)
- background-color-hsl-003.html (实时测试) (来源)
- background-color-hsl-004.html (实时测试) (来源)
- color-computed-hsl.html (实时测试) (来源)
- color-invalid-hsl.html (实时测试) (来源)
- color-valid-hsl.html (实时测试) (来源)
第一个参数指定色相角度。
在 HSL(和 HWB)中,角度 0deg 代表 sRGB 原始红色(同样适用于 360deg、720deg 等),其余的色相围绕圆周分布,所以 120deg 代表 sRGB 原始绿色,240deg 代表 sRGB 原始蓝色,依此类推。
接下来的两个参数分别是饱和度和亮度。对于饱和度,100% 或 100 表示完全饱和、明亮的颜色,而 0% 或 0 表示完全不饱和的灰色。对于亮度,50% 或 50 表示“正常”颜色,而 100% 或 100 是白色,0% 或 0 是黑色。
由于历史原因,如果饱和度小于 0%,它将在解析值阶段被钳制到 0%,然后再转换为 sRGB 颜色。
最后一个参数指定颜色的 Alpha 分量。 它的解释与 rgb() 函数的第四个参数完全相同。 如果省略,则默认为 100%。
HSL 颜色解析为 sRGB。
如果 HSL 颜色的饱和度为 0% 或 0,则色相分量是无效的。
与 RGB 相比,HSL 的一个优点是它更直观:人们可以猜测他们想要的颜色,然后进行调整。
hsl ( 120 deg 100 % 50 % ) 亮绿色hsl ( 120 deg 100 % 25 % ) 深绿色hsl ( 120 deg 100 % 75 % ) 浅绿色hsl ( 120 deg 75 % 85 % ) 粉绿色
HSL 相对于 OKLCh 的一个缺点是,色相操作会改变视觉亮度,并且色相并非均匀分布。
因此,在 HSL 中创建一组匹配的颜色(通过保持色相不变并改变饱和度和亮度)比操作 sRGB 组件值更容易;但是,由于亮度只是伽马校正的红、绿和蓝组件的平均值,因此它不对应于色相的视觉亮度。
在 OKLCh 中,sRGB 蓝色为 oklch(0.452 0.313 264.1),而 sRGB 黄色为 oklch(0.968 0.211 109.8)。OKLCh 的亮度值 0.452 和 0.968 明确地反映了两种颜色的视觉亮度。
在 HSL 中,色相角度并非感知上均匀的;颜色在某些区域聚集,而在其他区域则较为稀疏。
在 OKLCh 中,相同的颜色对 oklch(0.533 0.26 262.6) 和 oklch(0.462 0.306 268.9) 的色相差异为 268.9 - 262.6 = 6.3度,而另一对 oklch(0.882 0.181 94.24) 和 oklch(0.91 0.245 129.9) 的色相差异为 129.9 - 94.24 = 35.66度,正确地反映了色相的视觉分离程度。
由于历史原因,hsl() 和 hsla() 也支持旧版颜色语法。
测试
7.1. 将 HSL 颜色转换为 sRGB
将 HSL 颜色转换为 sRGB 在数学上很简单。 以下是 JavaScript 中转换算法的示例实现。 它返回一个包含三个数字的数组, 分别表示颜色的红色、绿色和蓝色分量, 对于 sRGB 色域中的颜色,这些分量将在 [0, 1] 范围内。
此代码假设已经应用了解析时对负饱和度的限制。
/** * @param {number} hue - Hue as degrees 0..360 * @param {number} sat - Saturation in reference range [0,100] * @param {number} light - Lightness in reference range [0,100] * @return {number[]} Array of sRGB components; in-gamut colors in range [0..1] */ function hslToRgb( hue, sat, light) { sat/= 100 ; light/= 100 ; function f( n) { let k= ( n+ hue/ 30 ) % 12 ; let a= sat* Math. min( light, 1 - light); return light- a* Math. max( - 1 , Math. min( k- 3 , 9 - k, 1 )); } return [ f( 0 ), f( 8 ), f( 4 )]; }
7.2. 将 sRGB 颜色转换为 HSL
反向的转换过程类似。
特别注意处理由远离 sRGB 色域的颜色产生的中间负饱和度值。
/** * @param {number} red - Red component 0..1 * @param {number} green - Green component 0..1 * @param {number} blue - Blue component 0..1 * @return {number[]} Array of HSL values: Hue as degrees 0..360, Saturation and Lightness in reference range [0,100] */ function rgbToHsl( red, green, blue) { let max= Math. max( red, green, blue); let min= Math. min( red, green, blue); let [ hue, sat, light] = [ NaN , 0 , ( min+ max) / 2 ]; let d= max- min; let epsilon= 1 / 100000 ; // max Sat is 1, in this code if ( d!== 0 ) { sat= ( light=== 0 || light=== 1 ) ? 0 : ( max- light) / Math. min( light, 1 - light); switch ( max) { case red: hue= ( green- blue) / d+ ( green< blue? 6 : 0 ); break ; case green: hue= ( blue- red) / d+ 2 ; break ; case blue: hue= ( red- green) / d+ 4 ; } hue= hue* 60 ; } // Very out of gamut colors can produce negative saturation // If so, just rotate the hue by 180 and use a positive saturation // see https://github.com/w3c/csswg-drafts/issues/9222 if ( sat< 0 ) { hue+= 180 ; sat= Math. abs( sat); } if ( hue>= 360 ) { hue-= 360 ; } if ( sat<= epsilon) { hue= NaN ; } return [ hue, sat* 100 , light* 100 ]; }
7.3. HSL 颜色示例
本节不是规范性的。
测试
本节不是规范性的,因此不需要测试。
下表展示了可能的 HSL 颜色的广泛范围。 每个表格代表一个色相, 以 30° 为间隔选择, 以说明常见的 "核心" 色调: 红色, 黄色, 绿色, 青色, 蓝色, 洋红色, 以及这些之间的六种中间颜色。
在每个表格中,X 轴表示饱和度, Y 轴表示亮度。
0° 红色 | ||||||
---|---|---|---|---|---|---|
100% | 80% | 60% | 40% | 20% | 0% | |
100% | ||||||
90% | ||||||
80% | ||||||
70% | ||||||
60% | ||||||
50% | ||||||
40% | ||||||
30% | ||||||
20% | ||||||
10% | ||||||
0% |
30° 红-黄(=橙色) | ||||||
---|---|---|---|---|---|---|
100% | 80% | 60% | 40% | 20% | 0% | |
100% | ||||||
90% | ||||||
80% | ||||||
70% | ||||||
60% | ||||||
50% | ||||||
40% | ||||||
30% | ||||||
20% | ||||||
10% | ||||||
0% |
60° 黄色 | ||||||
---|---|---|---|---|---|---|
100% | 80% | 60% | 40% | 20% | 0% | |
100% | ||||||
90% | ||||||
80% | ||||||
70% | ||||||
60% | ||||||
50% | ||||||
40% | ||||||
30% | ||||||
20% | ||||||
10% | ||||||
0% |
90° 黄绿色 | ||||||
---|---|---|---|---|---|---|
100% | 80% | 60% | 40% | 20% | 0% | |
100% | ||||||
90% | ||||||
80% | ||||||
70% | ||||||
60% | ||||||
50% | ||||||
40% | ||||||
30% | ||||||
20% | ||||||
10% | ||||||
0% |
120° 绿色 | ||||||
---|---|---|---|---|---|---|
100% | 80% | 60% | 40% | 20% | 0% | |
100% | ||||||
90% | ||||||
80% | ||||||
70% | ||||||
60% | ||||||
50% | ||||||
40% | ||||||
30% | ||||||
20% | ||||||
10% | ||||||
0% |
150° 绿青色 | ||||||
---|---|---|---|---|---|---|
100% | 80% | 60% | 40% | 20% | 0% | |
100% | ||||||
90% | ||||||
80% | ||||||
70% | ||||||
60% | ||||||
50% | ||||||
40% | ||||||
30% | ||||||
20% | ||||||
10% | ||||||
0% |
180° 青色 | ||||||
---|---|---|---|---|---|---|
100% | 80% | 60% | 40% | 20% | 0% | |
100% | ||||||
90% | ||||||
80% | ||||||
70% | ||||||
60% | ||||||
50% | ||||||
40% | ||||||
30% | ||||||
20% | ||||||
10% | ||||||
0% |
210° 青-蓝色 | ||||||
---|---|---|---|---|---|---|
100% | 80% | 60% | 40% | 20% | 0% | |
100% | ||||||
90% | ||||||
80% | ||||||
70% | ||||||
60% | ||||||
50% | ||||||
40% | ||||||
30% | ||||||
20% | ||||||
10% | ||||||
0% |
240° 蓝色 | ||||||
---|---|---|---|---|---|---|
100% | 80% | 60% | 40% | 20% | 0% | |
100% | ||||||
90% | ||||||
80% | ||||||
70% | ||||||
60% | ||||||
50% | ||||||
40% | ||||||
30% | ||||||
20% | ||||||
10% | ||||||
0% |
270° 蓝-洋红 | ||||||
---|---|---|---|---|---|---|
100% | 80% | 60% | 40% | 20% | 0% | |
100% | ||||||
90% | ||||||
80% | ||||||
70% | ||||||
60% | ||||||
50% | ||||||
40% | ||||||
30% | ||||||
20% | ||||||
10% | ||||||
0% |
300° 洋红 | ||||||
---|---|---|---|---|---|---|
100% | 80% | 60% | 40% | 20% | 0% | |
100% | ||||||
90% | ||||||
80% | ||||||
70% | ||||||
60% | ||||||
50% | ||||||
40% | ||||||
30% | ||||||
20% | ||||||
10% | ||||||
0% |
330° 洋红-红 | ||||||
---|---|---|---|---|---|---|
100% | 80% | 60% | 40% | 20% | 0% | |
100% | ||||||
90% | ||||||
80% | ||||||
70% | ||||||
60% | ||||||
50% | ||||||
40% | ||||||
30% | ||||||
20% | ||||||
10% | ||||||
0% |
8. HWB 颜色:hwb() 函数
HWB(色相-白度-黑度的缩写)[HWB] 是另一种指定 sRGB 颜色的方法,类似于HSL,但通常对人类来说更容易使用。它通过一个起始色相,然后混入一定程度的白色和黑色来描述颜色。
许多颜色选择器基于 HWB 色彩系统,因为它直观易用。
HWB 颜色解析为 sRGB。

< input type = "color" >
时显示。外部的轮盘用于选择色相,然后通过单击内部三角形选择相对的白色和黑色量。hwb() 函数的语法如下:
hwb () =hwb ( [ <hue> | none] [ <percentage> | <number> | none] [ <percentage> | <number> | none] [ /[ <alpha-value> | none] ] ?)
百分比 | 允许用于 W 和 B |
---|---|
百分比参考范围 | 对于 W 和 B:0% = 0.0,100% = 100.0 |
无效色相 ε | W + B >= 99.999 |
第一个参数指定色相, 其定义与 hsl() 完全相同; 这意味着它具有相同的缺点,例如色相均匀性。
第二个参数指定要混合的白色量, 百分比范围从 0%(无白色)到 100%(全白色)。 类似地,第三个参数指定要混合的黑色量, 百分比范围也从 0%(无黑色)到 100%(全黑色)。
超出这些范围的值并不无效;色相角度超出 [0,360) 范围将被归一化至该范围,而白色和黑色的值相加为 100% 或更高时,将生成如下所述的无彩色。
最终的颜色可以在概念上理解为选择的色相、白色颜料和黑色颜料的混合物,相对的数量由百分比决定。
如果白色加黑色的和大于或等于 100%,则定义为无彩色,即灰色阴影;转换为 sRGB 时,R、G 和 B 的值相等,其值为 white / (white + black)。
无彩色的 HWB 颜色不再包含任何所选择的色相。在这种情况下,色相组件为无效。
第四个参数指定颜色的 Alpha 分量。 它的解释与 rgb() 函数的第四个参数完全相同。 如果省略,则默认为 100%。
由于 hwb 是本规范此级别中的新增内容,因此不存在 Web 兼容性问题,所以 hwb() 不支持使用逗号分隔其所有参数的旧版颜色语法。 在 hwb() 内部使用逗号是错误的。
测试
8.1. 将 HWB 颜色转换为 sRGB
将 HWB 颜色转换为 sRGB 非常简单,类似于将 HSL 转换为 RGB 的方式。以下是算法的 Javascript 实现,首先将白色和黑色组件标准化,使它们的总和不超过 100%。
/** * @param {number} hue - Hue as degrees 0..360 * @param {number} white - Whiteness in reference range [0,100] * @param {number} black - Blackness in reference range [0,100] * @return {number[]} Array of RGB components 0..1 */ function hwbToRgb( hue, white, black) { white/= 100 ; black/= 100 ; if ( white+ black>= 1 ) { let gray= white/ ( white+ black); return [ gray, gray, gray]; } let rgb= hslToRgb( hue, 100 , 50 ); for ( let i= 0 ; i< 3 ; i++ ) { rgb[ i] *= ( 1 - white- black); rgb[ i] += white; } return rgb; }
8.2. 将 sRGB 颜色转换为 HWB
反向转换的过程类似。
/** * @param {number} red - Red component 0..1 * @param {number} green - Green component 0..1 * @param {number} blue - Blue component 0..1 * @return {number} Hue as degrees 0..360 */ function rgbToHue( red, green, blue) { // Similar to rgbToHsl, except that saturation and lightness are not calculated, and // potential negative saturation is ignored. let max= Math. max( red, green, blue); let min= Math. min( red, green, blue); let hue= NaN ; let d= max- min; if ( d!== 0 ) { switch ( max) { case red: hue= ( green- blue) / d+ ( green< blue? 6 : 0 ); break ; case green: hue= ( blue- red) / d+ 2 ; break ; case blue: hue= ( red- green) / d+ 4 ; } hue*= 60 ; } if ( hue>= 360 ) { hue-= 360 ; } return hue; } /** * @param {number} red - Red component 0..1 * @param {number} green - Green component 0..1 * @param {number} blue - Blue component 0..1 * @return {number[]} Array of HWB values: Hue as degrees 0..360, Whiteness and Blackness in reference range [0,100] */ function rgbToHwb( red, green, blue) { let epsilon= 1 / 100000 ; // account for multiply by 100 var hue= rgbToHue( red, green, blue); var white= Math. min( red, green, blue); var black= 1 - Math. max( red, green, blue); if ( white+ black>= 1 - epsilon) { hue= NaN ; } return ([ hue, white* 100 , black* 100 ]); }
8.3. HWB 颜色示例
本节不是规范性内容。
测试
本节不是规范性内容,不需要测试。
0° 红色 | ||||||
---|---|---|---|---|---|---|
W\B | 0% | 20% | 40% | 60% | 80% | 100% |
0% | ||||||
20% | ||||||
40% | ||||||
60% | ||||||
80% | ||||||
100% |
30° 红-黄色(橙色) | ||||||
---|---|---|---|---|---|---|
W\B | 0% | 20% | 40% | 60% | 80% | 100% |
0% | ||||||
20% | ||||||
40% | ||||||
60% | ||||||
80% | ||||||
100% |
60° 黄色 | ||||||
---|---|---|---|---|---|---|
W\B | 0% | 20% | 40% | 60% | 80% | 100% |
0% | ||||||
20% | ||||||
40% | ||||||
60% | ||||||
80% | ||||||
100% |
90° 黄-绿色 | ||||||
---|---|---|---|---|---|---|
W\B | 0% | 20% | 40% | 60% | 80% | 100% |
0% | ||||||
20% | ||||||
40% | ||||||
60% | ||||||
80% | ||||||
100% |
120° 绿色 | ||||||
---|---|---|---|---|---|---|
W\B | 0% | 20% | 40% | 60% | 80% | 100% |
0% | ||||||
20% | ||||||
40% | ||||||
60% | ||||||
80% | ||||||
100% |
150° 绿-青色 | ||||||
---|---|---|---|---|---|---|
W\B | 0% | 20% | 40% | 60% | 80% | 100% |
0% | ||||||
20% | ||||||
40% | ||||||
60% | ||||||
80% | ||||||
100% |
180° 青色 | ||||||
---|---|---|---|---|---|---|
W\B | 0% | 20% | 40% | 60% | 80% | 100% |
0% | ||||||
20% | ||||||
40% | ||||||
60% | ||||||
80% | ||||||
100% |
210° 青-蓝色 | ||||||
---|---|---|---|---|---|---|
W\B | 0% | 20% | 40% | 60% | 80% | 100% |
0% | ||||||
20% | ||||||
40% | ||||||
60% | ||||||
80% | ||||||
100% |
240° 蓝色 | ||||||
---|---|---|---|---|---|---|
W\B | 0% | 20% | 40% | 60% | 80% | 100% |
0% | ||||||
20% | ||||||
40% | ||||||
60% | ||||||
80% | ||||||
100% |
270° 蓝-品红色 | ||||||
---|---|---|---|---|---|---|
W\B | 0% | 20% | 40% | 60% | 80% | 100% |
0% | ||||||
20% | ||||||
40% | ||||||
60% | ||||||
80% | ||||||
100% |
300° 品红色 | ||||||
---|---|---|---|---|---|---|
W\B | 0% | 20% | 40% | 60% | 80% | 100% |
0% | ||||||
20% | ||||||
40% | ||||||
60% | ||||||
80% | ||||||
100% |
330° 品红-红色 | ||||||
---|---|---|---|---|---|---|
W\B | 0% | 20% | 40% | 60% | 80% | 100% |
0% | ||||||
20% | ||||||
40% | ||||||
60% | ||||||
80% | ||||||
100% |
9. 设备无关颜色:CIE Lab 和 LCH,Oklab 和 OKLCh
9.1. CIE Lab 和 LCH
本节不具规范性。
测试
本节不具规范性,不需要测试。
颜色的物理测量通常表示为 CIE L*a*b* [CIELAB] 色彩空间, 该空间由 CIE 于 1976 年创建,通常简称为 Lab。 从一个设备转换到另一个设备的颜色也可以使用 Lab 作为中间步骤。 Lab 是基于人类视觉实验得出的, 代表了人类可见的所有颜色范围。
Lab 是一个具有中央亮度(L)轴的直角坐标系统。 该值通常表示为无单位的数字; 为了与 CSS 其他部分兼容,也可以写为百分比。 100% 表示 L 值为 100,而不是 1.0。 L=0% 或 0 是深黑色(完全没有光) 而 L=100% 或 100 是漫反射白。
有用的是,L=50% 或 50 是中灰色,且设计上, L 的等增量在视觉上是均匀间隔的: Lab 色彩空间旨在实现感知上的均匀性。
a 和 b 轴传递色相; a 轴正值表示紫红色, 而负值则是互补色,绿色。 类似地,b 轴正值表示黄色, 负值表示互补色蓝色/紫色。 去饱和的颜色具有较小的 a 和 b 值, 并靠近 L 轴; 饱和的颜色则远离 L 轴。
光源是 D50 白光,这是一种标准化的日光光谱,色温为 5000K, 由完美漫反射体反射;它近似于晴天阳光的颜色。 D50 也是 ICC 颜色相互转换中配置文件连接空间使用的白点, 是提供 Lab 编辑功能的图像编辑器中使用的白点, 也是物理测量设备(如分光光度计和分光辐射计) 在报告 Lab 测量颜色时使用的值。
使用其他白点指定颜色的转换被称为 色度适应变换, 其模拟了人类视觉系统在适应新的照明条件时的变化。 线性布拉德福德算法 [ICC](原布拉德福德算法的简化版 [Bradford-CAT]) 是行业标准的色度适应变换, 计算非常简单,因为它只是一个矩阵乘法。
CIE LCH 与 Lab 具有相同的 L 轴, 但使用极坐标 C(色度)和 H(色相), 形成了一个极坐标的柱面坐标系统。 C 是从 L 轴的几何距离, H 是从 a 轴正向到 b 轴正向的角度。
注:Lab 和 LCH 的 L 轴 不要与 HSL 的 L 轴混淆。 例如,在 HSL 中,sRGB 颜色蓝色(#00F)和黄色(#FF0) 具有相同的 L 值(50%),即使在视觉上,蓝色要暗得多。 在 Lab 中这就非常清晰: sRGB 蓝色为 lab(29.567% 68.298 -112.0294) 而 sRGB 黄色为 lab(97.607% -15.753 93.388)。 在 Lab 和 LCH 中,如果两个颜色具有相同的 L 值, 那么它们在视觉亮度上是相同的。 HSL 和相关的极坐标 RGB 模型是为了试图 提供类似于 LCH 给 Lab 的可用性好处的 RGB, 但其准确性显著低于 Lab 和 LCH。
尽管 CIE Lab 和 LCH 得到了广泛使用, 但它们也存在一些问题,尤其是:
- 色相线性度
- 在蓝色区域(LCH 色相介于 270° 和 330° 之间), 视觉色相偏离了 LCH 的预测。 如果绘制一组相同色相且色度不同的蓝色, 这些颜色应该形成一条从中性轴延伸的直线, 但实际上形成了曲线。 换句话说, 随着一个饱和的蓝色的色度逐渐减少, 它会变得显著偏紫。
- 色相均匀性
- 虽然 LCH 中的色相通常是均匀间隔的, (且远优于 HSL 或 HWB), 但均匀性并不完美。
- 高色度差异的过度预测
- 对于高色度的颜色, 色度的变化不如中性色更明显。
这些缺陷影响了,例如, 创建均匀间隔的渐变, 将一个色彩空间映射到一个较小的色彩空间, 以及计算两个颜色之间的视觉差异。
为弥补这一点, 预测两个颜色之间视觉差异的公式 (Delta E) 随时间的推移变得更加准确 (但也更复杂)。 当前的行业标准公式, Delta E 2000, 对于缓解 Lab 和 LCH 的某些问题效果良好。 § 19.1 ΔE2000 中给出了示例实现。
但是这对色相曲率问题没有帮助。
9.2. Oklab 和 OKLCh
本节不具规范性。
测试
本节不具规范性,不需要测试。
最近,Oklab,一种改进的类 Lab 空间被开发出来 [Oklab]。 对应的极坐标形式称为 OKLCh。 它是通过对大量视觉上相似的颜色数据集进行数值优化而产生的, 与 CIE LCH 相比,其色相线性度、色相均匀性和色度均匀性都有所提高。
与 CIE Lab 一样,Oklab 有一个中心的亮度 L 轴, 通常表示为范围 [0,1] 的无单位数值; 为了与 CSS 其他部分兼容, 也可以写为百分比。100% 表示 L 值为 1.0。 L=0% 或 0.0 表示深黑色(完全没有光),而 L=100% 或 1.0 表示漫反射白。
注: 与 CIE Lab 不同,CIE Lab 假设适应漫反射白色, 而 Oklab 假设适应被定义的颜色, 这旨在使其具有比例不变性。
与 CIE Lab 一样,a 和 b 轴传递色相; a 轴正值表示紫红色, 负值表示互补色,绿色。 类似地,b 轴正值表示黄色, 负值表示互补的蓝色/紫色。
光源是 D65,与大多数 RGB 色彩空间使用的白点相同。
OKLCh 与 Oklab 具有相同的 L 轴, 但使用极坐标 C(色度)和 H(色相)。
注意:与 CIE LCH 中色度可以达到 200 或更高不同, OKLCh 色度范围约为 0.5。 CIE LCH 和 OKLCh 之间的色相角大致相似, 但不完全相同。


由于 Oklab 的感知均匀性优于 CIE Lab, 因此颜色差异可以通过 3D 空间中的距离(平方和的平方根)直接计算。 尽管计算简单, § 19.2 ΔEOK 中给出了示例实现。
9.3. 指定 Lab 和 LCH:lab() 和 lch() 函数表示法
CSS 允许直接以 Lab 和 LCH 表示颜色。
lab () =lab ( [ <percentage> | <number> | none] [ <percentage> | <number> | none] [ <percentage> | <number> | none] [ /[ <alpha-value> | none] ] ?)
百分比 | 允许用于 L, a 和 b |
---|---|
百分比参考范围 | 对于 L:0% = 0.0, 100% = 100.0 对于 a 和 b:-100% = -125, 100% = 125 |
测试
- lab-001.html (实时测试) (来源)
- lab-002.html (实时测试) (来源)
- lab-003.html (实时测试) (来源)
- lab-004.html (实时测试) (来源)
- lab-005.html (实时测试) (来源)
- lab-006.html (实时测试) (来源)
- lab-007.html (实时测试) (来源)
- lab-008.html (实时测试) (来源)
- lab-l-over-100-1.html (实时测试) (来源)
- lab-l-over-100-2.html (实时测试) (来源)
- color-valid.html (实时测试) (来源)
- color-computed-lab.html (实时测试) (来源)
- color-invalid-lab.html (实时测试) (来源)
- color-valid-lab.html (实时测试) (来源)
在Lab中, 第一个参数指定了 CIE 亮度,即 L。 这是一个介于 0% 或 0 和 100% 或 100 之间的数值。 值小于 0% 或 0 时必须在解析值时夹紧为 0%; 值大于 100% 或 100 时在解析值时夹紧为 100%。
第二和第三个参数是 Lab 色彩空间中沿 "a" 和 "b" 轴的距离, 如上一节所述。 这些值是带符号的 (允许正值和负值), 理论上是无界的 (但实际上不超过 ±160)。
还有一个可选的第四个<alpha-value> 组件, 通过斜杠分隔, 代表alpha 组件。
如果 Lab 颜色的亮度(经过夹紧后)为 0%, 或 100%,由于色域映射到显示器,该颜色将分别显示为黑色或白色。
lab ( 29.2345 % 39.3825 20.0664 ); lab ( 52.2345 40.1645 59.9971 ); lab ( 60.2345 -5.3654 58.956 ); lab ( 62.2345 % -34.9638 47.7721 ); lab ( 67.5345 -8.6911 -41.6019 ); lab ( 29.69 % 44.888 % -29.04 % )
lch () =lch ( [ <percentage> | <number> | none] [ <percentage> | <number> | none] [ <hue> | none] [ /[ <alpha-value> | none] ] ?)
百分比 | 允许用于 L 和 C |
---|---|
百分比参考范围 | 对于 L: 0% = 0.0, 100% = 100.0 对于 C: 0% = 0, 100% = 150 |
无效色相 ε | C <= 0.0015 |
测试
- lch-001.html (实时测试) (来源)
- lch-002.html (实时测试) (来源)
- lch-003.html (实时测试) (来源)
- lch-004.html (实时测试) (来源)
- lch-005.html (实时测试) (来源)
- lch-006.html (实时测试) (来源)
- lch-007.html (实时测试) (来源)
- lch-008.html (实时测试) (来源)
- lch-009.html (实时测试) (来源)
- lch-010.html (实时测试) (来源)
- lch-l-over-100-1.html (实时测试) (来源)
- lch-l-over-100-2.html (实时测试) (来源)
- color-valid.html (实时测试) (来源)
在 CIE LCH 中,第一个参数表示 CIE 的亮度 L,与 lab() 的亮度参数相同。
第二个参数是色度 C(大致表示“颜色的浓度”)。 它的最小有效值为 0,而最大值在理论上是无限的(但实际上不超过 230)。 如果提供的值为负数,则在解析值阶段将其夹紧到 0。
第三个参数是色相角 H。 它的解释方式类似于 <hue> 参数在 hsl() 中的解释方式, 但在这里色相均匀地分布在角度上,而不是与角度相同的映射。 因此,0deg 沿正 "a" 轴方向(朝向紫红色),(同样适用于 360deg、720deg 等); 90deg 沿正 "b" 轴方向(朝向芥黄色),180deg 沿负 "a" 轴方向 (朝向绿色青色),270deg 沿负 "b" 轴方向(朝向天蓝色)。
有一个可选的第四个 <alpha-value> 组件, 用斜线分隔,表示 alpha 组件。
如果 LCH 颜色的色度为 0%,则色相组件是 无效的。 如果 LCH 颜色的亮度(在夹紧后)为 0% 或 100%,则颜色将分别显示为黑色或白色, 这是由于显示器的色域映射。
lch ( 29.2345 % 44.2 27 ); lch ( 52.2345 % 72.2 56.2 ); lch ( 60.2345 59.2 95.2 ); lch ( 62.2345 % 59.2 126.2 ); lch ( 67.5345 % 42.5 258.2 ); lch ( 29.69 % 45.553 % 327.1 )
在lab或lch 中, 这些函数在此规范级别是全新的, 因此lab() 和 lch() 不 支持使用逗号分隔其所有参数的 旧颜色语法。 在这些函数中使用逗号是错误的。
9.4. 指定 Oklab 和 OKLCh:oklab() 和 oklch() 函数表示法
CSS 允许直接用 Oklab 和 OKLCh 表示颜色。
oklab () =oklab ( [ <percentage> | <number> | none] [ <percentage> | <number> | none] [ <percentage> | <number> | none] [ /[ <alpha-value> | none] ] ?)
百分比 | L、a 和 b 可以使用百分比 |
---|---|
百分比参考范围 | 对于 L:0% = 0.0,100% = 1.0 对于 a 和 b:-100% = -0.4,100% = 0.4 |
测试
- oklab-001.html (实时测试) (来源)
- oklab-002.html (实时测试) (来源)
- oklab-003.html (实时测试) (来源)
- oklab-004.html (实时测试) (来源)
- oklab-005.html (实时测试) (来源)
- oklab-006.html (实时测试) (来源)
- oklab-007.html (实时测试) (来源)
- oklab-008.html (实时测试) (来源)
- oklab-009.html (实时测试) (来源)
- oklab-l-almost-0.html (实时测试) (来源)
- oklab-l-almost-1.html (实时测试) (来源)
- oklab-l-over-1-1.html (实时测试) (来源)
- oklab-l-over-1-2.html (实时测试) (来源)
- color-valid.html (实时测试) (来源)
在 Oklab 中,第一个参数指定 Oklab 的亮度。 这是一个在 0% 或 0 和 100% 或 1.0 之间的数字。
小于 0% 或 0.0 的值必须在解析时被钳制到 0%; 大于 100% 或 1.0 的值在解析时被钳制到 100%。
第二个和第三个参数是沿 Oklab 颜色空间中的 "a" 和 "b" 轴的距离, 如前一节所述。 这些值是有符号的 (允许正值和负值) 理论上是无限的 (但实际上不超过 ±0.5)。
还有一个可选的第四个 <alpha-value> 组件, 用斜杠分隔, 表示alpha 组件。
如果 Oklab 颜色的亮度为 0% 或 0, 或者 100% 或 1.0, 则由于显示的色域映射, 颜色将分别显示为黑色或白色。
oklab ( 40.101 % 0.1147 0.0453 ); oklab ( 59.686 % 0.1009 0.1192 ); oklab ( 0.65125 -0.0320 0.1274 ); oklab ( 66.016 % -0.1084 0.1114 ); oklab ( 72.322 % -0.0465 -0.1150 ); oklab ( 42.1 % 41 % -25 % )
oklch () =oklch ( [ <percentage> | <number> | none] [ <percentage> | <number> | none] [ <hue> | none] [ /[ <alpha-value> | none] ] ?)
百分比 | 适用于 L 和 C |
---|---|
百分比参考范围 | 对于 L:0% = 0.0, 100% = 1.0 对于 C:0% = 0.0, 100% = 0.4 |
无效色相 ε | C <= 0.000004 |
测试
- oklch-001.html (实时测试) (来源)
- oklch-002.html (实时测试) (来源)
- oklch-003.html (实时测试) (来源)
- oklch-004.html (实时测试) (来源)
- oklch-005.html (实时测试) (来源)
- oklch-006.html (实时测试) (来源)
- oklch-007.html (实时测试) (来源)
- oklch-008.html (实时测试) (来源)
- oklch-009.html (实时测试) (来源)
- oklch-010.html (实时测试) (来源)
- oklch-011.html (实时测试) (来源)
- oklch-l-almost-0.html (实时测试) (来源)
- oklch-l-almost-1.html (实时测试) (来源)
- oklch-l-over-1-1.html (实时测试) (来源)
- oklch-l-over-1-2.html (实时测试) (来源)
- color-valid.html (实时测试) (来源)
在 OKLCh 中,第一个参数指定了 Oklch 亮度 L, 其解释与 oklab() 的亮度参数相同。
第二个参数是色度 C。 其最小有效值为 0, 最大值理论上没有上限 (但实际上不超过 0.5)。 如果提供的值为负值, 则在解析时将其钳制到 0。
第三个参数是色相角 H。 它的解释类似于 <hue> 的 hsl() 和 lch() 参数, 但不会以相同的方式将色相映射到角度。0deg 指向正“a”轴(朝向紫红色), (360deg、720deg 等也是如此);90deg 指向正“b”轴(朝向芥末黄),180deg 指向负“a”轴(朝向带绿色的青色), 270deg 指向负“b”轴(朝向天蓝色)。
有一个可选的第四个 <alpha-value> 分量, 用斜杠分隔, 表示 alpha 分量。
如果 OKLCh 颜色的色度为 0% 或 0, 则色相分量是无效的。 如果 OKLCh 颜色的亮度为 0% 或 0, 或 100% 或 1.0, 由于色域映射到显示器,颜色将分别显示为黑色或白色。
oklch ( 40.101 % 0.12332 21.555 ); oklch ( 59.686 % 0.15619 49.7694 ); oklch ( 0.65125 0.13138 104.097 ); oklch ( 0.66016 0.15546 134.231 ); oklch ( 72.322 % 0.12403 247.996 ); oklch ( 42.1 % 48.25 % 328.4 )
使用 oklab 或 oklch 没有任何 Web 兼容性问题, 它们在本级规范中是新引入的,因此 oklab() 和 oklch() 不 支持用逗号分隔所有参数的 旧版颜色语法。 在这些函数中使用逗号会产生错误。
9.5. 将 Lab 或 Oklab 颜色转换为 LCH 或 OKLCh 颜色
转换为极坐标形式非常简单:
- C = sqrt(a^2 + b^2)
- 如果 (C > epsilon) H = atan2(b, a) 否则 H 缺失
- L 相同
对于 a 和 b 的非常小的值(接近零的色度), 尽管视觉颜色没有从中性色轴发生变化, 但这些值的微小变化可能导致所报告的色相角剧烈摆动并基本上是随机的。 在 CSS 中,这意味着色相是 无效的, 在转换为 LCH 或 OKLCh 时被视为 缺失; 在非 CSS 环境中,这可能表现为缺失值,例如 NaN。
9.6. 将 LCH 或 OKLCh 颜色转换为 Lab 或 Oklab 颜色
转换为矩形坐标形式非常简单:
- 如果 H 缺失,a = b = 0
- 否则,
- a = C cos(H)
- b = C sin(H)
- L 保持不变
10. 预定义的色彩空间
CSS 提供了几种预定义的色彩空间, 包括 display-p3 [Display-P3], 这是一种典型的广色域空间,适用于当前的广色域显示器,prophoto-rgb,广泛用于摄影师, 以及 rec2020 [Rec.2020], 这是一种广播行业标准, 超广色域空间,几乎可以表示所有可见的真实世界色彩。
10.1. 指定预定义颜色:color() 函数
color() 函数允许在特定的、指定的 色彩空间 中指定颜色 (而不是大多数其他颜色函数操作的隐含 sRGB 色彩空间)。 它的语法如下:
color () =color ( <colorspace-params>[ /[ <alpha-value> | none] ] ?) <colorspace-params> =[ <predefined-rgb-params> | <xyz-params>] <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 } <xyz-space> = xyz | xyz-d50 | xyz-d65
测试
color 函数接受指定颜色的参数,并在显式列出的色彩空间中指定。
参数形式如下:
-
一个 <ident>,表示 预定义的色彩空间之一(例如 display-p3)。 具体的 预定义色彩空间 可能进一步限制是否可以使用 <number> 或 <percentage> 或两者。
如果 <ident> 指定的名称不是一个有效的色彩空间 (即不是 预定义色彩空间 之一), 那么该参数表示一个 无效颜色。
-
色彩空间接受的三个参数值(如 RGB 或 XYZ 值)。
超出色域的颜色具有小于 0 或 0%,或者大于 1 或 100% 的分量值。 这些并不是无效的,且会保留用于中间计算; 但是在显示时,它们会使用相对比色意图进行 CSS 色域映射, 使得值(在显示色彩空间中)在实际值时落入 0/0% 到 1/100% 的范围内。
-
一个可选的斜线分隔的 <alpha-value>。
使用 color() 没有 Web 兼容性问题, 因为它是在这个规范级别中新引入的,因此 color() 不 支持使用逗号分隔所有参数的 旧色彩语法。 在这个函数中使用逗号是错误的。
如果颜色是 无效颜色 或者 是 超出色域 的颜色, 那么该颜色 无法显示。
如果指定的颜色 可以显示, (即它不是 无效颜色 并且不是 超出色域), 那么这就是 color() 函数的实际值。
如果指定的颜色 是一个 有效颜色 但 无法显示, 那么实际值是从指定的颜色派生的,并经过 CSS 色域映射 用于显示。
color ( rec20200.42053 0.979780 0.00579 );
在 LCH 中,这种颜色是:
lch ( 86.6146 % 160.0000 136.0088 );
在 display-p3 中,这种颜色是:
color ( display-p3-0.6112 1.0079 -0.2192 );
并且在 display-p3 中超出色域 (红色和蓝色为负值,绿色大于 1)。 如果您有一个 display-p3 屏幕,那么这种颜色是:
- 有效
- 在色域内(对于 rec.2020)
- 超出色域(对于您的显示器)
- 因此 无法显示
color ( profoto-rgb0.4835 0.9167 0.2188 )
10.2. 预定义的 sRGB 颜色空间:sRGB 关键字
下面定义的 sRGB 预定义颜色空间 与用于传统 sRGB 颜色(如 rgb())的相同。
- srgb
-
srgb
[SRGB]
色彩空间接受三个数字参数,分别表示颜色的红色、绿色和蓝色分量。
色域内的颜色,其三个分量均在 [0, 1] 范围内。
白点是 D65。
[SRGB] 指定了两种观看条件:编码和典型。[ICC] 建议使用编码条件进行颜色转换和最佳观看,这些值如下表所示。
sRGB 是 CSS 的默认色彩空间,用于所有旧版颜色函数。
它具有以下特性:
x y 红色色度 0.640 0.330 绿色色度 0.300 0.600 蓝色色度 0.150 0.060 白色色度 D65 传递函数 见下文 白色亮度 80.0 cd/m2 黑色亮度 0.20 cd/m2 图像状态 显示参考 百分比 允许用于 R、G 和 B 百分比参考范围 对于 R,G,B:0% = 0.0,100% = 1.0 let sign= c< 0 ? - 1 : 1 ; let abs= Math. abs( c); if ( abs<= 0.04045 ) { cl= c/ 12.92 ; } else { cl= sign* ( Math. pow(( abs+ 0.055 ) / 1.055 , 2.4 )); } c 是经过伽马编码的红色、绿色或蓝色分量。 cl 是相应的线性光分量。
sRGB 色彩空间在 LCH 中的可视化。显示了原色和二次色。
10.3. 预定义的线性光 sRGB 颜色空间:srgb-linear 关键字
sRGB-linear 预定义颜色空间 与 srgb 相同,除了传递函数为线性光(无伽马编码)。
- srgb-linear
-
srgb-linear [SRGB]
色彩空间接受三个数字参数,
分别表示颜色的红色、绿色和蓝色分量。
色域内的颜色,其三个分量均在 [0, 1] 范围内。
白点是 D65。
它具有以下特性:
x y 红色色度 0.640 0.330 绿色色度 0.300 0.600 蓝色色度 0.150 0.060 白色色度 D65 传递函数 统一,见下文 白色亮度 80.0 cd/m2 黑色亮度 0.20 cd/m2 图像状态 显示参考 百分比 允许用于 R, G 和 B 百分比参考范围 对于 R, G, B: 0% = 0.0, 100% = 1.0 cl
= c; c 是红、绿或蓝分量。 cl 是相应的线性光分量,且与 c 相同。
为避免带状伪影,需要更高的精度用于 srgb-linear 相较于 srgb。
测试
10.4. 预定义的 Display P3 颜色空间:display-p3 关键字
- display-p3
-
display-p3 [Display-P3] 色彩空间接受三个数字参数,
分别表示颜色的红色、绿色和蓝色分量。
色域内的颜色,其三个分量均在 [0, 1] 范围内。
它使用与 [DCI-P3] 相同的主色度,
但使用 D65 白点,以及与 sRGB 相同的传递曲线。
现代显示器、电视、笔记本屏幕和手机屏幕能够显示全部或几乎全部的 display-p3 色域。
它具有以下特性:
x y 红色色度 0.680 0.320 绿色色度 0.265 0.690 蓝色色度 0.150 0.060 白色色度 D65 传递函数 与 srgb 相同 白色亮度 80.0 cd/m2 黑色亮度 0.80 cd/m2 图像状态 显示参考 百分比 允许用于 R, G 和 B 百分比参考范围 对于 R, G, B: 0% = 0.0, 100% = 1.0 在 LCH 中可视化 P3 颜色空间。图中显示了原色和次原色(但在 sRGB 中,并不是正确的颜色)。为了对比,还显示了 sRGB 的原色和次原色,作为虚线圆圈。 P3 原色具有更高的色度。
测试
- predefined-005.html (实时测试) (来源)
- predefined-006.html (实时测试) (来源)
- display-p3-001.html (实时测试) (来源)
- display-p3-002.html (实时测试) (来源)
- display-p3-003.html (实时测试) (来源)
- display-p3-004.html (实时测试) (来源)
- display-p3-005.html (实时测试) (来源)
- display-p3-006.html (实时测试) (来源)
- 2d.color.space.p3.fillText.html (P3 色彩空间填充文本) (实时测试) (来源)
- 2d.color.space.p3.fillText.shadow.html (P3 色彩空间填充文本阴影) (实时测试) (来源)
- 2d.color.space.p3.strokeText.html (P3 色彩空间描边文本) (实时测试) (来源)
- 2d.color.space.p3.to.p3.html (P3 色彩空间转换为 P3) (实时测试) (来源)
- 2d.color.space.p3.to.srgb.html (P3 色彩空间转换为 sRGB) (实时测试) (来源)
- 2d.color.space.p3.toBlob.p3.canvas.html (P3 色彩空间画布转换为 Blob) (实时测试) (来源)
- 2d.color.space.p3.toBlob.with.putImageData.html (P3 色彩空间使用 putImageData 转换为 Blob) (实时测试) (来源)
- 2d.color.space.p3.toDataURL.jpeg.p3.canvas.html (P3 色彩空间画布转换为 JPEG DataURL) (实时测试) (来源)
- 2d.color.space.p3.toDataURL.p3.canvas.html (P3 色彩空间画布转换为 DataURL) (实时测试) (来源)
- 2d.color.space.p3.toDataURL.with.putImageData.html (P3 色彩空间使用 putImageData 转换为 DataURL) (实时测试) (来源)
10.5. 预定义的 A98 RGB 颜色空间:a98-rgb 关键字
- a98-rgb
-
a98-rgb 色彩空间接受三个数字参数,
分别表示颜色的红色、绿色和蓝色分量。
色域内的颜色,其三个分量均在 [0, 1] 范围内。
传递曲线是一个伽马函数,接近但不完全等于 1/2.2。
它具有以下特性:
x y 红色色度 0.6400 0.3300 绿色色度 0.2100 0.7100 蓝色色度 0.1500 0.0600 白色色度 D65 传递函数 256/563 白色亮度 160.0 cd/m2 黑色亮度 0.5557 cd/m2 图像状态 显示参考 百分比 允许用于 R, G 和 B 百分比参考范围 对于 R, G, B: 0% = 0.0, 100% = 1.0 在 LCH 中可视化 A98 颜色空间。 图中显示了原色和次原色(但在 sRGB 中,并不是正确的颜色)。 为了对比,还显示了 sRGB 的原色和次原色,作为虚线圆圈。 a98 原色具有更高的色度,特别是在黄色、绿色和青色方面。
测试
10.6. 预定义的 ProPhoto RGB 颜色空间:prophoto-rgb 关键字
- prophoto-rgb
-
prophoto-rgb 色彩空间接受三个数字参数,
分别表示颜色的红色、绿色和蓝色分量。
色域内的颜色,其三个分量均在 [0, 1] 范围内。
传递曲线是一个伽马值为 1/1.8 的伽马函数,
在黑色附近有一个小的线性部分。
白点是 D50,与 CIE Lab 使用的白点相同。因此,
转换为 CIE Lab 不需要色度适应步骤。
ProPhoto RGB 空间使用超饱和的、非物理可实现的原色。 这些原色的选择旨在提供广色域,特别是为了在色调操作下最小化色相偏移。 它通常用于数字摄影作为宽色域的颜色空间, 用于保存摄影图像的存档版本。 prophoto-rgb 颜色空间允许 CSS 指定与这些图像中 RGB 值相同的颜色。
ProPhoto RGB 空间最初由柯达开发,并在 [Wolfe] 中进行了描述。 它由 ISO 标准化为 [ROMM],[ROMM-RGB]。
白色亮度给出一个范围,视场耀斑(也就是黑色亮度)是此范围的 0.5% 到 1.0%。
它具有以下特性:
x y 红色色度 0.734699 0.265301 绿色色度 0.159597 0.840403 蓝色色度 0.036598 0.000105 白色色度 D50 传递函数 见下文 白色亮度 160.0 到 640.0 cd/m2 黑色亮度 见文本 图像状态 显示参考 百分比 允许用于 R, G 和 B 百分比参考范围 对于 R, G, B: 0% = 0.0, 100% = 1.0 const E= 16 / 512 ; let sign= c< 0 ? - 1 : 1 ; let abs= Math. abs( c); if ( abs<= E) { cl= c/ 16 ; } else { cl= sign* Math. pow( c, 1.8 ); } c 是伽玛编码的红、绿或蓝分量。 cl 是相应的线性光分量。
在 LCH 中可视化 ProPhoto RGB 颜色空间。 图中显示了原色和次原色(但在 sRGB 中,并不是正确的颜色)。 为了对比,还显示了 sRGB 的原色和次原色,作为虚线圆圈。 ProPhoto RGB 的原色和次原色具有更高的色度,但这种超宽色域的大部分 不对应于物理上可实现的颜色。
测试
10.7. 预定义的 ITU-R BT.2020-2 颜色空间:rec2020 关键字
- rec2020
-
rec2020 [Rec.2020]
色彩空间接受三个数字参数,
分别表示颜色的红色、绿色和蓝色分量。
色域内的颜色,其三个分量均在 [0, 1] 范围内
(视频术语中的“全范围”)。
ITU Reference 2020 用于
超高清、4k 和 8k 电视。
这些原色是物理上可实现的,但实现起来很困难, 因为它们非常接近光谱轨迹。
当前显示器无法完全重现 rec2020 的全部色域。 随着显示技术的进步,覆盖率预计会逐渐提高。
它具有以下特性:
x y 红色色度 0.708 0.292 绿色色度 0.170 0.797 蓝色色度 0.131 0.046 白色色度 D65 传递函数 见下文,来自 [Rec.2020] 表 4 图像状态 显示参考 百分比 允许用于 R, G 和 B 百分比参考范围 对于 R,G,B: 0% = 0.0, 100% = 1.0 const α= 1.09929682680944 ; const β= 0.018053968510807 ; let sign= c< 0 ? - 1 : 1 ; let abs= Math. abs( c); if ( abs< β* 4.5 ) { cl= c/ 4.5 ; } else { cl= sign* ( Math. pow(( abs+ α- 1 ) / α, 1 / 0.45 )); } c 是伽玛编码的红、绿或蓝分量。 cl 是相应的线性光分量。
在 LCH 中可视化 rec2020 颜色空间。 图中显示了原色和次原色(但在 sRGB 中,并不是正确的颜色)。 为了对比,还显示了 sRGB 的原色和次原色,作为虚线圆圈。 rec2020 的原色具有更高的色度。
测试
10.8. 预定义的 CIE XYZ 颜色空间:xyz-d50、xyz-d65 和 xyz 关键字
- xyz-d50、xyz-d65、xyz
-
xyz
色彩空间接受三个数字参数,
分别表示 X、Y 和 Z 值。
它表示 CIE XYZ [COLORIMETRY] 色彩空间,
经过缩放以使漫射白的亮度 (Y) 为 1.0,
并且在必要时进行色度适应以匹配参考白。
xyz-d50 的参考白是 D50,而 xyz-d65 和 xyz 的参考白是 D65。
允许大于 1.0/100% 的值,并且不得被限制; Y 大于 1.0 的颜色表示比漫射白更亮的颜色。 小于 0/0% 的值不常见, 但可能由于色度适应而出现, 同样不得被限制。
它具有以下特性:
百分比 允许用于 X, Y, Z 百分比参考范围 对于 X, Y, Z: 0% = 0.0, 100% = 1.0
测试
- predefined-016.html (实时测试) (来源)
- xyz-001.html (实时测试) (来源)
- xyz-002.html (实时测试) (来源)
- xyz-003.html (实时测试) (来源)
- xyz-004.html (实时测试) (来源)
- xyz-005.html (实时测试) (来源)
- xyz-d50-001.html (实时测试) (来源)
- xyz-d50-002.html (实时测试) (来源)
- xyz-d50-003.html (实时测试) (来源)
- xyz-d50-004.html (实时测试) (来源)
- xyz-d50-005.html (实时测试) (来源)
- xyz-d65-001.html (实时测试) (来源)
- xyz-d65-002.html (实时测试) (来源)
- xyz-d65-003.html (实时测试) (来源)
- xyz-d65-004.html (实时测试) (来源)
- xyz-d65-005.html (实时测试) (来源)
- color-valid.html (实时测试) (来源)
10.9. 将预定义的颜色空间转换为 Lab 或 Oklab
对于所有预定义的 RGB 颜色空间,转换为 Lab 需要几个步骤,虽然在实践中,除第一个步骤外,其余步骤都是线性计算,并且可以组合在一起。
- 从伽马编码的 RGB 转换为线性光 RGB(撤销伽马编码)
- 从线性 RGB 转换为 CIE XYZ
- 如果需要,使用线性 Bradford 变换将 D65 白点(由 sRGB、display-p3、a98-rgb 和 rec2020 使用) 转换为 Lab 中使用的 D50 白点。 prophoto-rgb 已经具有 D50 白点。
- 将经过 D50 适应的 XYZ 转换为 Lab
转换为 Oklab 类似,但色度适应步骤仅对 prophoto-rgb 需要。
- 从伽马编码的 RGB 转换为线性光 RGB(撤销伽马编码)
- 从线性 RGB 转换为 CIE XYZ
- 如果需要,使用线性 Bradford 变换将 D50 白点(由 prophoto-rgb 使用) 转换为 Oklab 中使用的 D65 白点。
- 将经过 D65 适应的 XYZ 转换为 Oklab
这些转换的 JavaScript 示例代码可以在 § 18 颜色转换的示例代码 中找到。
10.10. 将 Lab 或 Oklab 转换为预定义的 RGB 颜色空间
从 Lab 转换为诸如 display-p3 或 rec2020 等预定义空间也需要多个步骤,并且在实践中,除最后一步外,其余步骤都是线性计算,并且可以组合在一起。
- 将 Lab 转换为(D50 适应的)XYZ
- 如果需要,使用线性 Bradford 变换将 Lab 使用的 D50 白点转换为 sRGB 和大多数其他 RGB 空间中使用的 D65 白点。 prophoto-rgb 不需要此步骤。
- 将(D65 适应的)CIE XYZ 转换为线性 RGB
- 将线性光 RGB 转换为 RGB(执行伽马编码)
从 Oklab 转换类似,但色度适应步骤仅对 prophoto-rgb 需要。
- 将 Oklab 转换为(D65 适应的)XYZ
- 如果需要,使用线性 Bradford 变换将 Oklab 使用的 D65 白点转换为 prophoto-rgb 中使用的 D50 白点。
- 将(D65 适应的)CIE XYZ 转换为线性 RGB
- 将线性光 RGB 转换为 RGB(执行伽马编码)
这些转换的 JavaScript 示例代码可以在 § 18 颜色转换的示例代码 中找到。
实现可能选择以其他方式实现这些步骤(例如,使用具有相对色度渲染意图的 ICC 配置文件),只要源和目标色域中的颜色的结果相同即可。
10.11. 在预定义 RGB 颜色空间之间转换
从一个预定义的 RGB 颜色空间转换到另一个需要多个步骤,其中一个步骤仅在白点不同的情况下需要。要从 src 转换到 dest:
- 从伽马编码的 srcRGB 转换为线性光 srcRGB(撤销伽马编码)
- 将线性 srcRGB 转换为 CIE XYZ
- 如果 src 和 dest 具有不同的白点,则将 XYZ 值从 srcWhite 转换为 destWhite,使用线性 Bradford 转换。
- 将 CIE XYZ 转换为线性 destRGB
- 将线性光 destRGB 转换为 destRGB(进行伽马编码)
这些预定义 RGB 颜色空间的转换的 JavaScript 示例代码可以在 § 18 颜色转换的示例代码 中找到。
10.12. 简单的 Alpha 合成
绘制时,实施必须根据 《合成与混合》第 5.1 节“简单 alpha 合成”中的规则处理 alpha 值 [Compositing]。
11. 转换颜色
测试
本节提供的算法在后面使用,不需要测试。
颜色可以从一个颜色空间转换到另一个颜色空间,前提是没有色域映射,并且每个颜色空间都可以表示超出色域的颜色(对于 RGB 空间,这意味着传递函数在扩展范围内定义),那么(受限于数值精度和舍入误差)两个颜色看起来会相同,表示相同的颜色感受。
要将源颜色空间 src 中的颜色 col1,白点为 src-white,转换为目标颜色空间 dest 中的颜色 col2,白点为 dest-white:
- 如果 src 是 圆柱极坐标颜色表示,首先将 col1 转换为对应的 矩形直角坐标颜色表示,并将其作为新的 col1。用零替换任何缺失的组件。
- 如果 src 不是线性光表示,则将其转换为线性光(撤销伽马编码),并将其作为新的 col1。
- 将 col1 转换为白点为 src-white 的 CIE XYZ,并将其记为 xyz。
- 如果 dest-white 不同于 src-white,则使用线性 Bradford 色度适应变换使 xyz 适应 dest-white,并将其作为新的 xyz。
- 如果 dest 是 圆柱极坐标颜色表示,则 dest-rect 为对应的 矩形直角坐标颜色表示。否则,令 dest-rect 为 dest。
- 将 xyz 转换为 dest,然后应用任何传递函数(伽马编码),得到 col2。
- 如果 dest 是物理输出颜色空间,如显示器,那么 col2 必须 CSS 色域映射,使其可以显示。
- 如果 dest-rect 不等于 dest,换句话说,dest 是 圆柱极坐标颜色表示,则从 dest-rect 转换为 dest,并将其作为 col2。这可能会产生缺失的组件。
12. 颜色插值
颜色插值发生在渐变、合成、滤镜、过渡、动画以及颜色混合和颜色修改函数中。
两个 <color> 值之间的插值通过执行以下步骤进行:
- 检查两种颜色的类似分量,这些分量将被沿用
- 将它们转换为给定的色彩空间, 下文将其称为插值色彩空间。 如果一种或两种颜色已处于插值色彩空间中, 此转换会将任何无效分量更改为缺失值
- (如果需要)在转换后的颜色中重新插入沿用的值
- (如果需要)根据所选的 <hue-interpolation-method> 修正色相
- 将颜色分量更改为预乘形式
- 分别对颜色的计算值的每个分量进行线性插值
- 撤销预乘
可以插值到或从 currentcolor。为此使用的数值为使用的值。
12.1. 插值的颜色空间
CSS 中的各种特性依赖于插值颜色。
混合或组合颜色时,结果会因所使用的 插值颜色空间 不同而有所差异。因此,不同的插值用途可能适用于不同的颜色空间。
-
在某些情况下,需要获得物理上混合两种彩色光的结果。在这种情况下,CIE XYZ 或 srgb-linear 颜色空间适合使用,因为它们在光强度上是线性的。
-
如果需要颜色在视觉上均匀分布(例如在渐变中),Oklab 颜色空间(以及旧的 Lab)设计为视觉均匀的。
-
如果需要避免颜色混合时变灰,即在过渡过程中最大化饱和度,OKLCh(以及旧的 LCH)非常适合。
-
最后,如果与遗留的 Web 内容的兼容性最为重要,则可以选择 sRGB 颜色空间,它既不是线性光也不是视觉上均匀的,尽管它产生的结果(过于暗或灰)较差。
这些功能统称为宿主语法。
为了允许宿主语法指示插值色彩空间, 本规范导出一个 color-interpolation-method 产生式。 它本身不被本规范使用, 仅暴露出来以便其他规范可以使用它;例如,请参阅 CSS 图像 4 § 3.1 线性渐变:linear-gradient() 表示法中的用法。
宿主语法应定义每种情况下默认的插值色彩空间应该是什么, 并且最好提供语法供作者覆盖此默认值。 如果此类语法是属性值的一部分,则应使用下面定义的 color-interpolation-method 产生式, 以便其他规范轻松参考。 这确保了 CSS 之间的一致性, 并且有关如何执行颜色插值的进一步自定义可以自动渗透到所有 CSS 中。
<color-space> = <rectangular-color-space> | <polar-color-space> <rectangular-color-space> = srgb | srgb-linear | display-p3 | a98-rgb | prophoto-rgb | rec2020 | lab | oklab | xyz | xyz-d50 | xyz-d65 <polar-color-space> = hsl | hwb | lch | oklch <hue-interpolation-method> =[ shorter | longer | increasing | decreasing] hue <color-interpolation-method> = in[ <rectangular-color-space> | <polar-color-space> <hue-interpolation-method>?]
在 <rectangular-color-space> 和 <polar-color-space> 的定义中的关键字各自引用其对应的颜色空间,这些颜色空间在 CSS 中既可以通过同名的函数语法表示,也可以(如果没有这样的函数)通过 <ident> 在 color() 函数中表示。
测试
- gradients-with-transparent.html (实时测试) (来源)
- gradient-eval-001.html (实时测试) (来源)
- gradient-eval-002.html (实时测试) (来源)
- gradient-eval-003.html (实时测试) (来源)
- gradient-eval-004.html (实时测试) (来源)
- gradient-eval-005.html (实时测试) (来源)
- gradient-eval-006.html (实时测试) (来源)
- gradient-eval-007.html (实时测试) (来源)
- gradient-eval-008.html (实时测试) (来源)
- gradient-eval-009.html (实时测试) (来源)
- gradient-none-interpolation.html (实时测试) (来源)
- legacy-color-gradient.html (实时测试) (来源)
- oklab-gradient.html (实时测试) (来源)
- srgb-gradient.html (实时测试) (来源)
- srgb-linear-gradient.html (实时测试) (来源)
- xyz-gradient.html (实时测试) (来源)
- gradient-interpolation-method-valid.html (实时测试) (来源)
- gradient-interpolation-method-invalid.html (实时测试) (来源)
- gradient-interpolation-method-computed.html (实时测试) (来源)
如果宿主语法没有定义颜色插值应在哪个颜色空间中进行,则默认使用 Oklab。
在特定实例中偏好在 sRGB 中进行插值的作者可以通过显式指定 sRGB 作为插值色彩空间来选择旧的行为, 例如在期望该结果的特定渐变上。
如果待插值的颜色超出了插值色彩空间的色域, 那么一旦转换到该空间, 它们将包含超出范围的值。
这些值不会被裁剪,而是按原样进行插值。
12.2. 插值时的缺失组件
在将两个颜色转换为 插值颜色空间 的过程中,任何 缺失组件 都会被替换为值 0。
因此,插值两个颜色的第一步是对输入颜色中的任何 缺失组件 进行分类,并将其与 插值颜色空间 的组件进行比较。如果找到任何作为 缺失组件 的 类似组件,它们将被带入并在预乘和线性插值之前重新插入转换后的颜色中。
类似组件 如下:
类别 | 组件 |
---|---|
红色 | r,x |
绿色 | g,y |
蓝色 | b,z |
亮度 | L |
色彩度 | C, S |
色相 | H |
对立 a | a |
对立 b | b |
Alpha | alpha |
注意:对于此分类的目的,XYZ 空间被视为超饱和的 RGB 空间。此外,尽管饱和度依赖于亮度,但在这里它仍与色度归为同一类别。HWB 的白度和黑度在其他颜色空间中没有对应的类似组件。
lch ( 50 % 0.02 none) color ( display-p30.7 0.5 none)
转换为:
oklch ( 56.897 % 0.0001 0 ) oklch ( 63.612 % 0.1522 78.748 )
重新插入带入的 缺失组件 后,要插值的两个颜色为:
oklch ( 56.897 % 0.0001 none) oklch ( 63.612 % 0.1522 78.748 )
如果具有带入的 缺失组件 的颜色与另一个没有该组件缺失的颜色进行插值,则 缺失组件 的值被视为另一个颜色的组件值。
因此,带入步骤必须在处理任何 无效组件 之前执行。
oklch ( 78.3 % 0.108 326.5 ) oklch ( 39.2 % 0.4 none)
实际要插值的颜色为:
oklch ( 78.3 % 0.108 326.5 ) oklch ( 39.2 % 0.4 326.5 )
而不是:
oklch ( 78.3 % 0.108 326.5 ) oklch ( 39.2 % 0.4 0 )
如果沿用的缺失分量是 alpha,则颜色必须使用此沿用的值进行预乘, 而不是使用颜色转换产生的零值。
oklch ( 0.783 0.108 326.5 /0.5 ) oklch ( 0.392 0.4 0 / none)
那么实际要插值的颜色是
oklch ( 78.3 % 0.108 326.5 /0.5 ) oklch ( 39.2 % 0.4 0 /0.5 )
得到预乘的 OKLCh 值为 [0.3915, 0.054, 326] 和 [0.196, 0.2, 0]。
如果两种颜色都缺少某个给定的分量, 则插值后的颜色 也将缺少该分量。
12.3. 带有 Alpha 的插值
当要插值的颜色不完全不透明时, 它们首先按如下方式进行预乘:
-
如果 alpha 值为 none,预乘值就是未预乘的值。否则,
-
如果任一组件值为 none,则预乘值也为 none。
-
对于直角坐标颜色系统,所有组件值都与 alpha 值相乘。
-
对于圆柱极坐标颜色坐标系,色相角不进行预乘,但其他两个轴会进行预乘。
要从预乘颜色值中获取颜色值,
为什么预乘 Alpha 有用?
使用预乘表示法插值颜色往往比非预乘表示法产生更具吸引力的过渡,尤其是在从完全不透明颜色过渡到完全透明时。
请注意,如果透明度或颜色保持不变(例如在
(不透明的红色)和
(不透明的蓝色),或
(不透明的红色)和
(透明的红色)之间进行过渡),则不论在预乘还是非预乘颜色空间中进行颜色插值,结果都是相同的。只有当两个端点之间的颜色和透明度都不同的时候,才会出现差异。
线性插值这些颜色的中点将是 [23.4% 10.2% 38.8%],使用 alpha 值 0.5,撤销预乘后的颜色为 rgb(46.8% 20.4% 77.6% / 0.5)。
线性插值的中点将是 [29.4365% 25.776 3.554],使用 alpha 值 0.5,撤销预乘后的颜色为 lab(58.873% 51.552 7.108 / 0.5)。
沿着 较短 色调弧(默认)进行线性插值的中点为 [29.4365% 40.563 31.82],使用 alpha 值 0.5,撤销预乘后的颜色为 lch(58.873% 81.126 31.82 / 0.5)。
有关 alpha 预乘和撤销预乘的示例 JavaScript 代码(适用于极坐标和直角坐标颜色空间),请参见 § 18 颜色转换示例代码。
12.4. 色调插值
对于具有色调角度的颜色函数(如 LCH、HSL、HWB 等),有多种插值方式。 由于大于 360° 的弧度通常不理想, 色调角度在插值之前会被调整 使得每个分量的插值小于 360°,通常小于 180°。
主语法可以指定以下任何一种算法用于色调插值 (以下角度单位为度,但无论如何指定,逻辑都是相同的)。 指定色调插值策略已是 <color-interpolation-method> 语法的一部分 通过 <hue-interpolation-method> 标记来完成。
除非另有说明,如果主语法未选择特定的色调插值算法,默认使用 较短 弧度。
注意: 请记住, 如果要插值的颜色尚未处于指定的插值颜色空间中, 那么将其转换会将任何无效分量变为缺失分量。
12.4.1. 较短
色调角度通过插值取起始和结束色调之间的较短弧。
角度调整使得 θ₂ - θ₁ ∈ [-180, 180]。伪 JavaScript 代码:
if( θ₂ - θ₁ >180 ) { θ₁ +=360 ; } else if( θ₂ - θ₁ <-180 ) { θ₂ +=360 ; }
12.4.2. 较长
色调角度通过插值取起始和结束色调之间的较长弧。
角度调整使得 θ₂ - θ₁ ∈ {(-360, -180], [180, 360)}。伪 JavaScript 代码:
if( 0 < θ₂ - θ₁ <180 ) { θ₁ +=360 ; } else if( -180 < θ₂ - θ₁ <=0 ) { θ₂ +=360 ; }
12.4.3. 递增
色调角度被插值为使其在从第一个颜色到第二个颜色的过程中, 始终保持递增。 如果角度增加到 360,则重置为零, 然后继续增加。
根据两个角度之间的差异, 这将看起来与较短或较长类似。但是,如果其中一个色调角度被动画化, 并且色调角度差异经过 180 度, 则插值不会翻转到另一弧。
但是,如果第二种颜色的色调被动画化为 oklch(0.7 0.1 230), 则插值的中点为 (30 + 230) * 0.5 = 130 度, 继续沿相同的递增方向, 得到另一种绿色 oklch(0.6 0.1 130) 而不是在动画的过程中翻转到对方颜色。
角度调整使得 θ₂ - θ₁ ∈ [0, 360)。伪 JavaScript 代码:
if( θ₂ < θ₁) { θ₂ +=360 ; }
12.4.4. 递减
色调角度被插值为使其在从第一个颜色到第二个颜色的过程中, 始终保持递减。 如果角度减小到 0,则重置为 360, 然后继续递减。
根据两个角度之间的差异, 这将看起来与较短或较长类似。但是,如果其中一个色调角度被动画化, 并且色调角度差异经过 180 度, 则插值不会翻转到另一弧。
但是,如果第二种颜色的色调被动画化为 oklch(0.7 0.1 230), 则插值的中点为 (30 + 360 + 230) * 0.5 = 310 度, 继续沿相同的递减方向, 得到另一种紫色 oklch(0.6 0.1 310) 而不是在动画的过程中翻转到对方颜色。
角度调整使得 θ₂ - θ₁ ∈ (-360, 0]。伪 JavaScript 代码:
if( θ₁ < θ₂) { θ₁ +=360 ; }
13. 色域映射
13.1. 色域映射简介
注意: 本节为文档其他地方描述的具体要求提供了重要的上下文。
本节非规范性内容
测试
本节不是规范性的,不需要测试。
当一个原始颜色空间中的颜色 被转换到另一个具有较小色域的目标颜色空间时, 一些颜色将超出目标色域。
对于中间颜色计算, 这些超出色域的值会被保留。 但是,如果目标是显示设备 (如屏幕或打印机), 那么超出色域的值必须转换为 一个在色域内的颜色。
色域映射是找到一个 在视觉上变化最小的在色域内的颜色的过程。
13.1.1. 裁剪
最简单且最不理想的方法 就是简单地将分量值 裁剪到显示范围内。 这会改变 三原色(对于 RGB 显示器)的比例, 导致色调偏移。
color ( srgb-linear 0.5 1 3 )
。
因为这是一个线性光颜色空间,
我们可以比较三个分量的强度,
看到蓝色光的量是绿色的三倍,
而红色光的量是绿色的一半。
蓝色主色光的量是红色的六倍。
在 OKLCh 中,这种颜色的色调角为 265.1°
如果现在将该颜色裁剪,
使其进入 sRGB 色域,
我们得到
。
蓝色光的量与绿色相同。
在 OKLCh 中,这种颜色的色调角为 196.1°,
相比原始颜色变化了 69°。
13.1.2. 最接近的颜色 (MINDE)
更好的方法是在一个感知均匀的颜色空间中通过找到最接近的在色域内的颜色进行映射 (所谓的最小 ΔE 或 MINDE)。 显然,这种技术的成功 取决于 色域映射颜色空间的均匀程度 以及所使用的 deltaE 函数的预测精度。
但是,在进行色域映射时, 色调的变化特别令人反感; 色度的变化更容易接受, 而 如果另一种选择是较大幅度的色度降低, 那么轻微的亮度变化也是可以接受的。 MINDE 对每个维度的变化赋予相同的权重, 因此产生次优的结果。
13.1.3. 色度减少
为了改进 MINDE 算法, 颜色在一个感知均匀的极坐标颜色空间中映射, 通过保持色调不变, 并减少色度直到颜色落入色域内。
color ( display-p3 1 1 0 )
)
正在映射到 sRGB 显示器。
色域映射的颜色空间为 OKLCh。
color ( display-p31 1 0 )
为
color ( srgb1 1 -0.3463 )
即为
color ( oklch0.96476 0.24503 110.23 )
通过逐步减少色度分量 直到得到的颜色落入 sRGB 色域内 (即没有分量为负值或大于 1), 得到色域映射后的颜色。
color ( oklch0.96476 0.21094 110.23 )
即为
color ( srgb0.99116 0.99733 0.00001 )
实际的实现将比线性减少收敛更快; 可以通过二分查找, 或计算恒色调和亮度线与色域边界的几何交点来实现。
13.1.4. 过度的色度减少
此外,对于某些颜色,特别是非常浅的颜色(如黄色和青色),这种简单的方法会产生次优的结果, 如果色域边界的上边缘较浅,甚至略微凹陷。 恒亮度线可能刚好位于色域边界之上, 导致在这些情况下色度过低。
颜色空间的选择会影响色域映射颜色的可接受性。
color ( display-p3 1 1 0
)
在 CIE LCH 颜色空间中逐步减少色度。
color ( display-p3 1 1 0
)
的色度逐渐降低,但这次是在 OKLCh 色彩空间中。
13.1.5. 带局部剪裁的色度减少
可以改进简单的色度减少算法: 在每一步中, 计算当前映射颜色和该颜色的剪裁版本之间的颜色差异。 如果当前颜色超出色域边界, 但它与剪裁版本之间的颜色差异 低于刚好可见差异(JND)的阈值, 则返回该颜色的剪裁版本作为映射结果。 实际上,这在每个阶段都在进行 MINDE 映射, 但受限于色调和亮度变化非常小, 因此不明显。
color ( display-p3 1 1 0
)
在 CIE LCH 颜色空间中逐步减少色度,
并使用了局部剪裁修改。
color ( display-p3 1 1 0
)
的色度逐渐降低,但这次是在 OKLCh 色彩空间中
并使用局部裁剪修改。
13.1.6. 偏离感知均匀性:色相曲率
使用 CIE LCH 颜色空间 和 deltaE2000 距离度量, 对于色相范围在 270° 至 330° 的颜色, 结果已知会产生显著的色相偏移, 从而导致次优结果。

使用 OKLCh 颜色空间 和 deltaEOK 距离度量 在所有色相角下避免了此问题。

13.2. CSS 色域映射到 RGB 目标
测试
颜色的实际值并未暴露给脚本,这使得以自动化方式进行测试变得困难。
CSS 色域映射算法 应用于 超出 RGB 显示器色域的单个标准动态范围 (SDR) CSS 颜色, 因此需要进行 CSS 色域映射。
它实现了一种相对比色意图, 色域内的颜色不变。
注意: 其他情况, 特别是映射到打印机色域, 当最大黑位显著高于零时, 需要使用不同的算法, 这些算法将对齐相应的黑点和白点, 从而在降低色度的同时, 使非常亮和非常暗的颜色发生亮度变化。
注意: 该算法适用于单个独立的颜色; 对于图像, 邻近像素之间的关系很重要, 目标是保留细节和纹理, 因此使用感知呈现意图更为合适, 在这种情况下, 色域内的颜色可能会发生变化。
CSS 色域映射发生在 OKLCh 颜色空间 中, 使用的颜色差异公式为 deltaEOK。 使用了 local-MINDE 改进。
对于在亮度轴上超出范围的颜色, 如果亮度大于或等于 1.0, 则返回目标颜色空间中的白色, 如果亮度小于或等于 0.0, 则返回目标颜色空间中的黑色。
对于二分搜索实现, 在搜索的每一步中, 计算当前映射颜色和该颜色的剪裁版本之间的 deltaEOK。 如果当前颜色 在 色域边界之外, 但它与剪裁版本之间的 deltaEOK 低于 刚好可见差异(JND) 的阈值, 则返回该颜色的剪裁版本作为映射结果。
对于几何实现, 在找到确切的交点后, 沿恒亮度线向外投射(朝向更高色度),直到以下任一情况发生:
-
投影点和该点的剪裁版本之间的 deltaEOK 超过一个 JND,或者
-
投影点的色度等于原始颜色的色度(即不要投射超过原始颜色)
然后返回该颜色的剪裁版本作为映射结果。
对于 OKLCh 颜色空间, 一个 JND 是 OKLCh 差异的 0.02。
注意: 在 CIE Lab 颜色空间中, 亮度组件的范围是 0 到 100, 使用 deltaE2000, 一个 JND 是 2。 因为 Oklab 和 OKLCh 中亮度的范围是 0 到 1, 使用 deltaEOK, 一个 JND 要小 100 倍。
13.2.1. 二分搜索色域映射算法与局部 MINDE 的示例伪代码
- 如果 destination 没有色域限制(XYZ-D65、XYZ-D50、Lab、LCH、Oklab、OKLCh),则将 origin 转换为 destination 并将其作为色域映射后的颜色返回
- 将 origin 从 origin color space 转换为 OKLCh 色彩空间,记为 origin_OKLCh
- 如果 origin_OKLCh 的亮度大于或等于 100%,则将 `oklab(1 0 0 / origin.alpha)` 转换为 destination 并将其作为色域映射后的颜色返回
- 如果 origin_OKLCh 的亮度小于或等于 0%,则将 `oklab(0 0 0 / origin.alpha)` 转换为 destination 并将其作为色域映射后的颜色返回
- 定义 inGamut(color) 函数,当传入颜色在 destination 色域内时返回 true。对于 HSL 和 HWB,当颜色在 sRGB 色域内时返回 true。
- 如果 inGamut(origin_OKLCh) 为 true,则将 origin_OKLCh 转换为 destination 并将其作为色域映射后的颜色返回
- 否则,定义 delta(one, two) 函数,返回颜色 one 与颜色 two 的 deltaEOK 值
- 将 JND 设为 0.02
- 将 epsilon 设为 0.0001
- 定义 clip(color) 函数,将 color 转换为 destination,将每个分量限制在该分量的参考范围内,并返回结果
- 将 current 设为 origin_OKLCh
- 将 clipped 设为 clip(current)
- 将 E 设为 delta(clipped, current)
-
如果 E < JND
- 返回 clipped 作为色域映射后的颜色
- 将 min 设为零
- 将 max 设为 origin_OKLCh 的 OKLCh 色度
- 定义 min_inGamut 布尔值,表示 min 是否仍在色域内,并将其设为 true
-
当 (max - min 大于 epsilon) 时,重复以下步骤
- 将 chroma 设为 (min + max) /2
- 将 current 的色度分量设为 chroma
- 如果 min_inGamut 为 true 且 inGamut(current) 也为 true,则将 min 设为 chroma 并继续重复这些步骤
-
否则,执行以下步骤:
- 将 clipped 设为 clip(current)
- 将 E 设为 delta(clipped, current)
-
如果 E < JND
- 如果 (JND - E < epsilon),返回 clipped 作为色域映射后的颜色
-
否则,
- 将 min_inGamut 设为 false
- 将 min 设为 chroma
- 否则,将 max 设为 chroma 并继续重复这些步骤
- 返回 clipped 作为色域映射后的颜色
14. 解析 <color> 值
除非为特定属性另有规定,指定的颜色将解析为 计算颜色,然后进一步解析为 使用颜色,如下所述。
测试
14.1. 解析 sRGB 值
这适用于:
它不适用于:
-
color() 使用 srgb 或 srgb-linear 颜色空间的值。
如果 sRGB 颜色由作者显式指定为命名颜色, 或作为系统颜色, 则声明值是该命名或系统颜色,转换为ASCII 小写。 计算值和使用值 是相应的 sRGB 颜色, 与指定的 alpha 分量配对 (在限制到 [0, 1] 范围后, 如果未指定则默认为不透明)。
否则,声明值、计算值和使用值 是相应的 sRGB 颜色, 与指定的 alpha 分量配对 (在限制到 [0, 1] 范围后, 如果未指定则默认为不透明)。
由于历史原因,当 sRGB 颜色中的 calc() 解析为单个值时, 声明值序列化时不带 "calc(" ")" 包装器。
同样由于历史原因, 当 calc() 简化为单个值时, 颜色值被限制在 [0.0, 255.0] 范围内。
这种限制也处理了诸如 Infinity、-Infinity 和 NaN 之类的值,它们将分别限制为 255、0 和 0。
测试
14.2. 解析 Lab 和 LCH 值
声明值、计算值和使用值 是相应的 CIE Lab 或 LCH 颜色 (在限制 L、C 和 H 后) 与指定的 alpha 分量配对 (作为 <number>,而非 <percentage>; 如果未指定则默认为不透明)。
14.3. 解析 Oklab 和 OKLCh 值
声明值、计算值和使用值 是相应的 Oklab 或 OKLCh 颜色 (在限制 L、C 和 H 后) 与指定的 alpha 分量配对 (作为 <number>,而非 <percentage>; 如果未指定则默认为不透明)。
14.4. 解析 color() 函数的值
声明值、计算值和使用值 是指定色彩空间中的颜色, 与指定的 alpha 分量配对 (作为 <number>,而非 <percentage>; 如果未指定则默认为不透明)。
对于在 xyz 颜色空间 中指定的颜色, 这是 xyz-d65 颜色空间 的别名, 计算值和使用值 采用 xyz-d65 颜色空间。
14.5. 解析其他颜色
这适用于系统颜色(包括 <deprecated-color>),transparent, 和 currentcolor。
每个 <system-color> 关键字 和 <deprecated-color> 关键字 的声明值是其自身。 计算值 是其色彩空间中的相应颜色。 然而,这类颜色不得被 "强制颜色模式"改变。
< button style = "color: ButtonText; background: ButtonFace" ></ button >
color 属性的声明值是 "ButtonText", 而计算值可能是,例如, rgb(0, 0, 0)。
transparent 的声明值是 "transparent", 而计算值和使用值是透明黑色。
currentcolor 关键字计算为其自身。
在 color 属性中, currentcolor 的使用值是 已解析的继承值。 在任何其他属性中, 其使用值是同一元素上 color 属性的使用值。
注意:这意味着如果 currentcolor 值被继承, 它是作为关键字被继承的, 而不是作为 color 属性的值, 所以后代元素将使用它们自己的 color 属性 来解析它。
< div > < p > 假设这个示例文本足够长,可以在多行中换行。</ p > </ div >
和以下 CSS:
div{ color : forestgreen; text-shadow : currentColor; } p{ color : mediumseagreen; } p::firstline{ color : yellowgreen; }
继承的 text-shadow 属性在第一行片段上的使用值将是 yellowgreen。
测试
15. 序列化<color> 值
本节更新并替换了 CSS 对象模型中关于序列化 CSS 值部分中与序列化 <color> 值相关的内容。
在本节中,规范中使用的字符串及其对应的字符如下。
字符串 | 字符 |
---|---|
" " | U+0020 空格 |
"#" | U+0023 数字符号 |
"," | U+002C 逗号 |
"-" | U+002D 连字符 |
"." | U+002E 句号 |
"/" | U+002F 斜线 |
"none" | U+006E 小写字母 n U+006F 小写字母 o U+006E 小写字母 n U+0065 小写字母 e |
字符串 "." 应作为小数点分隔符使用,无论地区如何,且不应有千位分隔符。
对于支持缺少的颜色组件的语法形式, 值 none(等同于 NONE,nOnE 等)应以全小写的字符串“none”进行序列化。
15.1. 序列化 alpha 值
这适用于任何可以接受可选 alpha 值的<color>值。 这不适用于 opacity 属性。
如果在被限制到范围 [0, 1] 后,alpha 为 1,则在序列化中省略它;默认值为 1(完全不透明)。
如果 alpha 的值为 1 以外的任何值,则按照下面描述显式包含在序列化中。
如果值内部表示为 0 到 255 之间的整数(即 8 位无符号整数),请按以下步骤操作:
- 设 alpha 为给定的整数。
- 如果存在一个 0 到 100 之间的整数,当它乘以 2.55 并四舍五入到最接近的整数(如果两个值同等接近则向上取整)时等于 alpha,则设 rounded 为该整数除以 100。
- 否则,将 rounded 设为 alpha 除以 0.255 并四舍五入到最接近的整数(如果两个值同等接近则向上取整),再除以 1000。
- 将 rounded 序列化为<number> 的结果返回。
否则,返回给定值的序列化结果(作为 <number>,而不是 <percentage>)。
例如,如果 alpha 存储为 8 位无符号整数 237,整数 93 满足条件,因为 Math.round(93 * 2.55) 等于 237,因此 alpha 序列化为“0.93”。
但是,如果 alpha 存储为 8 位无符号整数 236,则不存在这样的整数(92 映射到 235,而 94 映射到 240),因此 236 ÷ 0.255 = 925.490196078,alpha 序列化为“0.92549”(不超过 6 位数字,去除尾随零)。
<number> 值以十进制表示,使用 "." 字符作为小数点分隔符。不得省略前导零,尾随零必须省略。
alpha 值保留的精度,以及序列化值中的小数位数,本规范中未定义,但必须至少足以进行整数百分比值的往返。因此,序列化值必须至少包含两位小数(除非已去除尾随零)。值必须向 +∞ 取整,而非截断。
例如,alpha 值为 12.3456789% 时,可以序列化为“0.12”或“0.123”或“0.1234”或“0.12346”(向 +∞ 取整,因为后续数字是 6)或任何相同形式的更长四舍五入序列化。
由于在解析时会对超出有效范围的 <alpha-value> 进行限制, 因此声明值将被限制。 然而,根据 CSS 值 4 § 10.12 范围检查,使用 calc() 指定的 <alpha-value> 在序列化指定形式时不会被限制; 但计算值会被限制。
15.2. 序列化 sRGB 值
以下 sRGB 值的序列化形式:
派生自声明值。
当序列化由作者设置为 CSS 命名颜色、 系统颜色、 已弃用颜色 或 transparent 的属性值时,因此对于声明值, 会保留 ASCII 小写关键字值。 对于计算值和使用值, 使用相应的 sRGB 值。
因此,transparent 的序列化声明值是字符串 "transparent", 而 transparent 的序列化计算值是字符串 "rgba(0, 0, 0, 0)"。
对于所有其他 sRGB 值, 声明值、计算值和使用值 是相应的 sRGB 值。
在序列化期间, 任何缺失值 都会转换为 0。
15.2.1. sRGB 值的 HTML 兼容序列化
如果以下所有条件都为真:
- 色彩空间为 sRGB
- alpha 值为 1
- RGB 分量值在内部表示为 0 到 255(含)之间的整数(即 8 位无符号整数)
- 请求 HTML 兼容序列化
那么相应的 sRGB 值将按如下方式序列化为 6 位十六进制颜色表示法:
一个由七个字符组成的字符串,包含字符“#”,紧随其后的是红色分量、绿色分量和蓝色分量的两位十六进制表示,顺序如此,使用 ASCII 小写十六进制数字。不允许有空格。
context.fillStyle ="rgb(255, 0, 255)" console.log ( context.fillStyle); //"#ff00ff"
色彩空间为 sRGB,每个分量的表示为 8 位, 数据格式不会产生 none 值,也不支持扩展范围值, 并且 alpha 值为 1。
HTML 兼容的序列化是字符串“#ff00ff”(而不是“#FF00FF”)。
否则,对于 sRGB,使用 sRGB 值的 CSS 序列化,对于其他色彩空间,使用 <color> 值的相关序列化。
context.fillStyle ="lab(29% 39 20)" ; console.log ( context.fillStyle); //"lab(29 39 20)"
CSS 序列化是字符串 "lab(29 39 20)"。
context.fillStyle ="#ff00ffed" ; console.log ( context.fillStyle); //"rgba(255, 0, 255, 0.93)"
alpha 值不为 1,因此 CSS 序列化是字符串 "rgba(255, 0, 255, 0.93)"。
15.2.2. sRGB 值的 CSS 序列化
相应的 sRGB 值使用 rgb() 或 rgba() 形式 (取决于(限制后的)alpha 值是否恰好为 1), 函数名称的所有字母均为ASCII 小写。
为保持兼容性,sRGB 组件值以<number> 形式序列化,而不是 <percentage>。同样为了兼容性,组件值以十进制序列化,范围为 [0-255],不论它们存储的位深度如何。
如前所述,单位 alpha 值不会显式序列化。此外,为了保持兼容性,如果 alpha 恰好为 1,则使用 rgb() 形式,隐式表示 alpha;否则使用 rgba() 形式,显式表示 alpha 值。
为了保持兼容性,使用带逗号分隔符的传统形式;每个逗号后面跟一个 ASCII 空格。这包括用于分隔 rgba() 中蓝色分量和 alpha 值的逗号(而不是斜线)。
hwb ( 740 deg 20 % 30 % /50 % )
首先标准化为:
hwb ( 20 20 % 30 % /50 % )
然后转换为 sRGB 并序列化为:
rgba ( 178.5 , 93.5 , 51 , 0.5 )
返回结果的精度如下所述。
注意: 与 CSS Color 3 相反,rgb() 函数的参数是 <number> 类型,而不是 <integer>。因此,任何高于八位精度的内容都用小数部分表示。
保留 sRGB 组件值的精度,即序列化值中的有效数字位数,本规范中未定义,但至少必须足以进行八位值的往返。值必须向 +∞ 取整,而非截断。
注意: 期望从 getComputedStyle 返回的颜色值为 <integer> 组件值的脚本编写者,建议更新它们以支持 <number> 值。
例如:
rgb ( 146.064 107.457 131.223 )
现在是有效的,等同于:
rgb ( 57.28 % 42.14 % 51.46 % )
符合规范的序列化形式为字符串 "rgb(146.06, 107.46, 131.2)"。
任何组件值中的尾随零必须被省略;如果小数部分由全零组成,也必须省略小数点。这意味着以整数组件值指定的 sRGB 颜色将以向后兼容的整数值序列化。
15.3. 序列化 Lab 和 LCH 值
lch() 和 lab() 值的序列化形式 派生自计算值,并使用 lab() 或 lch() 形式, 函数名称使用ASCII 小写字母。
分量值以十进制序列化; L、a、b 和 C 分量值 序列化为 <number>, 酌情使用 Lab 百分比参考范围或 LCH 百分比参考范围 执行百分比到数字的转换; 因此 0% L 映射到 0, 100% L 映射到 100。 必须使用单个 ASCII 空格字符 " " 作为分量值之间的分隔符。
任何组件值中的尾随小数部分零必须省略;如果小数部分全为零,小数点也必须省略。
保留 lab() 组件值的精度,即序列化值中的有效数字位数,本规范未定义,但由于广色域,必须足够以进行 0 到 100 之间的 L 值以及 ±127 之间的 a 和 b 值的往返操作,至少需要 16 位精度;这将导致至少有三位小数,除非尾随零已被省略。(建议内部存储为半浮点数或浮点数)。值必须 向 +∞ 取整,而非截断。
注意: 超宽色域空间中的 a 和 b 值可以超出 ±125。例如,所有的 prophoto-rgb 主色和次色都超过了此范围,但在 ±200 之内。
如前所述,单位 alpha 值不会显式序列化。非单位 alpha 值必须显式序列化,并且字符串 " / "(一个 ASCII 空格,然后斜杠,然后另一个空格)必须用于将 b 组件值与 alpha 值分隔开。
以下值的序列化形式为:
lch ( 56.2 % 83.6 357.4 /93 % )
字符串 "lch(56.2 83.6 357.4 / 0.93)",而不是 "lch(56.2% 83.6 357.4 / 0.93)"
15.4. 序列化 Oklab 和 OKLCh 值
oklch() 和 oklab() 值的序列化形式 派生自计算值,并使用 oklab() 或 oklch() 形式, 函数名称使用ASCII 小写字母。
分量值以十进制序列化; L、a、b 和 C 分量值 序列化为 <number>, 酌情使用 Oklab 百分比参考范围或 OKLCh 百分比参考范围 执行百分比到数字的转换; 因此 0% L 映射到 0, 100% L 映射到 1.0。 必须使用单个 ASCII 空格字符 " " 作为分量值之间的分隔符。
以下值的序列化形式为:
oklab ( 54.0 % -0.10 -0.02 )
字符串 "oklab(0.54 -0.1 -0.02)",而不是 "oklab(54 -0.1 -0.02)" 或 "oklab(54% -0.1 -0.02)"
任何组件值中的尾随小数部分零必须省略;如果小数部分全为零,小数点也必须省略。
以下值的序列化形式为:
oklch ( 56.43 % 0.0900 123.40 )
字符串 "oklch(0.5643 0.09 123.4)",而不是 "oklch(0.5643 0.0900 123.40)"。
保留 oklab() 组件值的精度,即序列化值中的有效数字位数,本规范未定义,但由于广色域,必须足够以进行 0 到 1(0% 到 100%)之间的 L 值,以及 ±0.5 之间的 a、b 和 C 值的往返操作,至少需要 16 位精度;这将导致至少有五位小数,除非尾随零已被省略。(建议内部存储为半浮点数或浮点数)。值必须 向 +∞ 取整,而非截断。
注意: 超宽色域空间中的 a、b 和 C 值可以超出 ±0.5。例如,prophoto-rgb 的绿色和蓝色主色的 C 值分别为 0.526 和 1.413,超出了该范围。
如前所述,单位 alpha 值不会显式序列化。非单位 alpha 值必须显式序列化,并且字符串 " / "(一个 ASCII 空格,然后斜杠,然后另一个空格)必须用于将最终的颜色组件值(b 或 C)与 alpha 值分隔开。
15.5. 序列化 color() 函数的值
color() 值的序列化形式来源于 计算值,并使用 color() 形式,函数名和色彩空间名中的字母使用 ASCII 小写。
组件值以十进制形式序列化,作为 <number>。各组件值之间,以及色彩空间名和第一个颜色组件之间,必须使用单个 ASCII 空格字符 " " 作为分隔符。
以下值的序列化形式为:
color ( dIsPlAy-P30.964 0.763 0.787 )
字符串 "color(display-p3 0.96 0.76 0.79)",如果保留两位小数。注意 0.787 四舍五入为 0.79,而不是截断到 0.78。
任何组件值中的尾随小数部分零必须省略;如果小数部分全为零,小数点也必须省略。
以下值的序列化形式为:
color ( rec20200.400 0.660 0.340 )
字符串 "color(rec2020 0.4 0.66 0.34)",而不是 "color(rec2020 0.400 0.660 0.340)"。
如果色彩空间为 sRGB,则在序列化结果中仍需显式指定色彩空间。
对于预定义的色彩空间,往返所需的最低精度如下:
色彩空间 | 最小位数 |
---|---|
srgb | 10 |
srgb-linear | 12 |
display-p3 | 10 |
a98-rgb | 10 |
prophoto-rgb | 12 |
rec2020 | 12 |
xyz、xyz-d50、xyz-d65 | 16 |
(推荐内部存储为每个组件 16 位,半浮点或浮点)。值必须 向 +∞ 取整,而非截断。
注意: 与传统形式如 rgb()、hsl() 等相比,color(srgb) 有更高的最小精度要求。因此,鼓励希望获得更高精度的样式表作者使用 color(srgb) 形式。
如前所述,单位 alpha 值不会显式序列化。非单位 alpha 值必须显式序列化,并且字符串 " / "(一个 ASCII 空格,然后斜杠,然后另一个空格)必须用于将最终的颜色组件值与 alpha 值分隔开。
以下值的序列化形式为:
color ( prophoto-rgb0.2804 0.40283 0.42259 /85 % )
字符串 "color(prophoto-rgb 0.28 0.403 0.423 / 0.85)",如果保留三位小数。
15.6. 序列化其他颜色
这适用于 currentcolor。
该值的序列化形式来源于 计算值,并且颜色名称中的字母使用 ASCII 小写。
currentColor 的序列化形式为字符串 "currentcolor"。
16. 序列化 <opacity-value>
这适用于 opacity 属性。
指定的给定不透明度值序列化为 <number>,而不是 <percentage>。
此 <number> 值以十进制表示, 小数点分隔符为 "." 字符。 前导零不得省略。 尾随零必须省略。
超出 [0,1] 范围的不透明度值 在序列化的指定值中保留,不进行限制。
保留不透明度值的精度, 以及序列化值中的小数位数, 本规范未定义, 但必须至少足以 往返整数百分比值。 因此,序列化值必须包含 至少两位小数 (除非已删除尾随零)。 值必须向 +∞ 四舍五入,而不是截断。
17. 默认样式规则
以下样式表是说明性的,而非规范性的。此样式表可作为实现 HTML 文档默认样式的一部分。
/* 桌面用户代理的传统超链接颜色 */ :link{ color : LinkText; } :visited{ color : VisitedText; } :active{ color : ActiveText; }
18. 颜色转换的示例代码
本节不是规范性的。
测试
本节不是规范性的,因此不需要测试。
为了更清晰地表达,使用了一个库进行矩阵乘法。(这比内联所有的乘法和加法更易读)。矩阵采用列主序排列。
// 颜色转换的示例代码 // 转换也可以使用 ICC 配置文件和颜色管理系统完成 // 为了清晰起见,使用了一个库来进行矩阵乘法(multiply-matrices.js) // 标准白点,由 4 位数 CIE x,y 色度定义 const D50= [ 0.3457 / 0.3585 , 1.00000 , ( 1.0 - 0.3457 - 0.3585 ) / 0.3585 ]; const D65= [ 0.3127 / 0.3290 , 1.00000 , ( 1.0 - 0.3127 - 0.3290 ) / 0.3290 ]; // 与 sRGB 相关的函数 function lin_sRGB( RGB) { // 将一组 sRGB 值转换为 // 其中在色域内的值在范围 [0 - 1] 内 // 转换为线性光(未压缩)形式。 // https://en.wikipedia.org/wiki/SRGB // 扩展的传递函数: // 对于负值,线性部分沿轴反射进行扩展, // 然后使用反射的幂函数。 return RGB. map( function ( val) { let sign= val< 0 ? - 1 : 1 ; let abs= Math. abs( val); if ( abs<= 0.04045 ) { return val/ 12.92 ; } return sign* ( Math. pow(( abs+ 0.055 ) / 1.055 , 2.4 )); }); } function gam_sRGB( RGB) { // 将线性光 sRGB 值在范围 0.0-1.0 内转换为 // 伽马校正的形式 // https://en.wikipedia.org/wiki/SRGB // 扩展的传递函数: // 对于负值,线性部分沿轴反射延伸, // 然后使用反射的幂函数 return RGB. map( function ( val) { let sign= val< 0 ? - 1 : 1 ; let abs= Math. abs( val); if ( abs> 0.0031308 ) { return sign* ( 1.055 * Math. pow( abs, 1 / 2.4 ) - 0.055 ); } return 12.92 * val; }); } function lin_sRGB_to_XYZ( rgb) { // 将线性光 sRGB 值数组转换为 CIE XYZ // 使用 sRGB 自身的白点 D65(无色度适配) var M= [ [ 506752 / 1228815 , 87881 / 245763 , 12673 / 70218 ], [ 87098 / 409605 , 175762 / 245763 , 12673 / 175545 ], [ 7918 / 409605 , 87881 / 737289 , 1001167 / 1053270 ], ]; return multiplyMatrices( M, rgb); } function XYZ_to_lin_sRGB( XYZ) { // 将 XYZ 转换为线性光 sRGB var M= [ [ 12831 / 3959 , - 329 / 214 , - 1974 / 3959 ], [ - 851781 / 878810 , 1648619 / 878810 , 36519 / 878810 ], [ 705 / 12673 , - 2585 / 12673 , 705 / 667 ], ]; return multiplyMatrices( M, XYZ); } // 与 display-p3 相关的函数 function lin_P3( RGB) { // 将 display-p3 RGB 值数组在范围 0.0 - 1.0 内 // 转换为线性光(未压缩)形式。 return lin_sRGB( RGB); // 与 sRGB 相同 } function gam_P3( RGB) { // 将线性光 display-p3 RGB 值数组在范围 0.0-1.0 内转换为 // 伽马校正的形式 return gam_sRGB( RGB); // 与 sRGB 相同 } function lin_P3_to_XYZ( rgb) { // 将线性光 display-p3 值数组转换为 CIE XYZ // 使用 D65(无色度适配) // http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html var M= [ [ 608311 / 1250200 , 189793 / 714400 , 198249 / 1000160 ], [ 35783 / 156275 , 247089 / 357200 , 198249 / 2500400 ], [ 0 / 1 , 32229 / 714400 , 5220557 / 5000800 ], ]; return multiplyMatrices( M, rgb); } function XYZ_to_lin_P3( XYZ) { // 将 XYZ 转换为线性光 P3 var M= [ [ 446124 / 178915 , - 333277 / 357830 , - 72051 / 178915 ], [ - 14852 / 17905 , 63121 / 35810 , 423 / 17905 ], [ 11844 / 330415 , - 50337 / 660830 , 316169 / 330415 ], ]; return multiplyMatrices( M, XYZ); } // prophoto-rgb 函数 function lin_ProPhoto( RGB) { // 将一组 prophoto-rgb 值转换为 // 其中在色域内的颜色在范围 [0.0 - 1.0] 内 // 转换为线性光(未压缩)形式。 // 传递曲线为 gamma 1.8,具有一个小的线性部分 // 扩展的传递函数 const Et2= 16 / 512 ; return RGB. map( function ( val) { let sign= val< 0 ? - 1 : 1 ; let abs= Math. abs( val); if ( abs<= Et2) { return val/ 16 ; } return sign* Math. pow( abs, 1.8 ); }); } function gam_ProPhoto( RGB) { // 将一组线性光 prophoto-rgb 值(范围 0.0-1.0) // 转换为伽马校正形式 // 传递曲线为 gamma 1.8,具有一个小的线性部分 // TODO 对于负值,在轴的反射上扩展线性部分,然后在其下方添加幂次 const Et= 1 / 512 ; return RGB. map( function ( val) { let sign= val< 0 ? - 1 : 1 ; let abs= Math. abs( val); if ( abs>= Et) { return sign* Math. pow( abs, 1 / 1.8 ); } return 16 * val; }); } function lin_ProPhoto_to_XYZ( rgb) { // 将一组线性光 prophoto-rgb 值转换为 CIE D50 XYZ // 矩阵无法用有理形式表示,但计算精度达 64 位 // 参见 https://github.com/w3c/csswg-drafts/issues/7675 var M= [ [ 0.79776664490064230 , 0.13518129740053308 , 0.03134773412839220 ], [ 0.28807482881940130 , 0.71183523424187300 , 0.00008993693872564 ], [ 0.00000000000000000 , 0.00000000000000000 , 0.82510460251046020 ] ]; return multiplyMatrices( M, rgb); } function XYZ_to_lin_ProPhoto( XYZ) { // 将 D50 XYZ 转换为线性光 prophoto-rgb var M= [ [ 1.34578688164715830 , - 0.25557208737979464 , - 0.05110186497554526 ], [ - 0.54463070512490190 , 1.50824774284514680 , 0.02052744743642139 ], [ 0.00000000000000000 , 0.00000000000000000 , 1.21196754563894520 ] ]; return multiplyMatrices( M, XYZ); } // a98-rgb 函数 function lin_a98rgb( RGB) { // 将一个范围在 0.0 - 1.0 的 a98-rgb 值数组转换为线性光(未压缩)形式。 // 现在也接受负值。 return RGB. map( function ( val) { let sign= val< 0 ? - 1 : 1 ; let abs= Math. abs( val); return sign* Math. pow( abs, 563 / 256 ); }); } function gam_a98rgb( RGB) { // 将一个线性光 a98-rgb 值数组(范围在 0.0-1.0)转换为伽马校正形式。 // 现在也接受负值。 return RGB. map( function ( val) { let sign= val< 0 ? - 1 : 1 ; let abs= Math. abs( val); return sign* Math. pow( abs, 256 / 563 ); }); } function lin_a98rgb_to_XYZ( rgb) { // 将线性光 a98-rgb 值数组转换为 CIE XYZ。 // http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html // 相较于 https://www.adobe.com/digitalimag/pdfs/AdobeRGB1998.pdf 第 4.3.5.3 节有更高的数值精度。 // 以下值是根据 R G B W 的色度坐标从原理出发计算得出的。 // 参见 matrixmaker.html。 var M= [ [ 573536 / 994567 , 263643 / 1420810 , 187206 / 994567 ], [ 591459 / 1989134 , 6239551 / 9945670 , 374412 / 4972835 ], [ 53769 / 1989134 , 351524 / 4972835 , 4929758 / 4972835 ], ]; return multiplyMatrices( M, rgb); } function XYZ_to_lin_a98rgb( XYZ) { // 将 CIE XYZ 转换为线性光 a98-rgb。 var M= [ [ 1829569 / 896150 , - 506331 / 896150 , - 308931 / 896150 ], [ - 851781 / 878810 , 1648619 / 878810 , 36519 / 878810 ], [ 16779 / 1248040 , - 147721 / 1248040 , 1266979 / 1248040 ], ]; return multiplyMatrices( M, XYZ); } // Rec. 2020 相关函数 function lin_2020( RGB) { // 将一个范围在 0.0 - 1.0 的 Rec.2020 RGB 值数组转换为线性光(未压缩)形式。 // ITU-R BT.2020-2 第 4 页。 const α= 1.09929682680944 ; const β= 0.018053968510807 ; return RGB. map( function ( val) { let sign= val< 0 ? - 1 : 1 ; let abs= Math. abs( val); if ( abs< β* 4.5 ) { return val/ 4.5 ; } return sign* ( Math. pow(( abs+ α- 1 ) / α, 1 / 0.45 )); }); } function gam_2020( RGB) { // 将一个线性光 Rec.2020 RGB 值数组(范围在 0.0-1.0)转换为伽马校正形式。 // ITU-R BT.2020-2 第 4 页。 const α= 1.09929682680944 ; const β= 0.018053968510807 ; return RGB. map( function ( val) { let sign= val< 0 ? - 1 : 1 ; let abs= Math. abs( val); if ( abs> β) { return sign* ( α* Math. pow( abs, 0.45 ) - ( α- 1 )); } return 4.5 * val; }); } function lin_2020_to_XYZ( rgb) { // 将一个线性光 Rec.2020 值数组转换为 CIE XYZ,使用 D65(无色度适应)。 // http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html var M= [ [ 63426534 / 99577255 , 20160776 / 139408157 , 47086771 / 278816314 ], [ 26158966 / 99577255 , 472592308 / 697040785 , 8267143 / 139408157 ], [ 0 / 1 , 19567812 / 697040785 , 295819943 / 278816314 ], ]; // 实际计算的 0 值为 4.994106574466076e-17 return multiplyMatrices( M, rgb); } function XYZ_to_lin_2020( XYZ) { // 将 CIE XYZ 转换为线性光 Rec.2020。 var M= [ [ 30757411 / 17917100 , - 6372589 / 17917100 , - 4539589 / 17917100 ], [ - 19765991 / 29648200 , 47925759 / 29648200 , 467509 / 29648200 ], [ 792561 / 44930125 , - 1921689 / 44930125 , 42328811 / 44930125 ], ]; return multiplyMatrices( M, XYZ); } // 色度适应 function D65_to_D50( XYZ) { // 从 D65 到 D50 的 Bradford 色度适应。 // 下方矩阵是三次操作的结果: // - 从 XYZ 转换为视网膜锥体域。 // - 根据不同参考白点调整各成分比例。 // - 转换回 XYZ。 // 参见 https://github.com/LeaVerou/color.js/pull/354/files var M= [ [ 1.0479297925449969 , 0.022946870601609652 , - 0.05019226628920524 ], [ 0.02962780877005599 , 0.9904344267538799 , - 0.017073799063418826 ], [ - 0.009243040646204504 , 0.015055191490298152 , 0.7518742814281371 ] ]; return multiplyMatrices( M, XYZ); } function D50_to_D65( XYZ) { // 从 D50 到 D65 的 Bradford 色度适应。 // 参见 https://github.com/LeaVerou/color.js/pull/360/files var M= [ [ 0.955473421488075 , - 0.02309845494876471 , 0.06325924320057072 ], [ - 0.0283697093338637 , 1.0099953980813041 , 0.021041441191917323 ], [ 0.012314014864481998 , - 0.020507649298898964 , 1.330365926242124 ] ]; return multiplyMatrices( M, XYZ); } // CIE Lab 和 LCH function XYZ_to_Lab( XYZ) { // 假设 XYZ 是相对于 D50 的,转换为 CIE Lab。 // 基于 CIE 标准,该标准现在将这些定义为有理分数。 var ε= 216 / 24389 ; // 6^3/29^3 var κ= 24389 / 27 ; // 29^3/3^3 // 计算 xyz,即相对于参考白点缩放后的 XYZ。 var xyz= XYZ. map(( value, i) => value/ D50[ i]); // 现在计算 f。 var f= xyz. map( value=> value> ε? Math. cbrt( value) : ( κ* value+ 16 ) / 116 ); return [ ( 116 * f[ 1 ]) - 16 , // L 500 * ( f[ 0 ] - f[ 1 ]), // a 200 * ( f[ 1 ] - f[ 2 ]) // b ]; // L 的范围为 [0,100]。在 CSS 中使用时,加上百分号。 } function Lab_to_XYZ( Lab) { // 将 Lab 转换为 D50 适配的 XYZ // http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html var κ= 24389 / 27 ; // 29^3/3^3 var ε= 216 / 24389 ; // 6^3/29^3 var f= []; // 计算 f,从与亮度相关的项开始 f[ 1 ] = ( Lab[ 0 ] + 16 ) / 116 ; f[ 0 ] = Lab[ 1 ] / 500 + f[ 1 ]; f[ 2 ] = f[ 1 ] - Lab[ 2 ] / 200 ; // 计算 xyz var xyz= [ Math. pow( f[ 0 ], 3 ) > ε? Math. pow( f[ 0 ], 3 ) : ( 116 * f[ 0 ] - 16 ) / κ, Lab[ 0 ] > κ* ε? Math. pow(( Lab[ 0 ] + 16 ) / 116 , 3 ) : Lab[ 0 ] / κ, Math. pow( f[ 2 ], 3 ) > ε? Math. pow( f[ 2 ], 3 ) : ( 116 * f[ 2 ] - 16 ) / κ]; // 通过参考白点缩放 xyz 来计算 XYZ return xyz. map(( value, i) => value* D50[ i]); } function Lab_to_LCH( Lab) { var epsilon= 0.0015 ; var chroma= Math. sqrt( Math. pow( Lab[ 1 ], 2 ) + Math. pow( Lab[ 2 ], 2 )); // Chroma var hue= Math. atan2( Lab[ 2 ], Lab[ 1 ]) * 180 / Math. PI; if ( hue< 0 ) { hue= hue+ 360 ; } if ( chroma<= epsilon) { hue= NaN ; } return [ Lab[ 0 ], // L is still L chroma, // Chroma hue// Hue, in degrees [0 to 360) ]; } function LCH_to_Lab( LCH) { // 从极坐标形式转换回 return [ LCH[ 0 ], // L 仍然是 L LCH[ 1 ] * Math. cos( LCH[ 2 ] * Math. PI/ 180 ), // a LCH[ 1 ] * Math. sin( LCH[ 2 ] * Math. PI/ 180 ) // b ]; } // OKLab 和 OKLCH // https://bottosson.github.io/posts/oklab/ // XYZ <-> LMS 矩阵重新计算以保持一致的参考白点 // 详见 https://github.com/w3c/csswg-drafts/issues/6642#issuecomment-943521484 // 重新计算为 64 位精度 // 详见 https://github.com/color-js/color.js/pull/357 function XYZ_to_OKLab( XYZ) { // 给定相对于 D65 的 XYZ,转换为 OKLab var XYZtoLMS= [ [ 0.8190224379967030 , 0.3619062600528904 , - 0.1288737815209879 ], [ 0.0329836539323885 , 0.9292868615863434 , 0.0361446663506424 ], [ 0.0481771893596242 , 0.2642395317527308 , 0.6335478284694309 ] ]; var LMStoOKLab= [ [ 0.2104542683093140 , 0.7936177747023054 , - 0.0040720430116193 ], [ 1.9779985324311684 , - 2.4285922420485799 , 0.4505937096174110 ], [ 0.0259040424655478 , 0.7827717124575296 , - 0.8086757549230774 ] ]; var LMS= multiplyMatrices( XYZtoLMS, XYZ); // JavaScript 的 Math.cbrt 返回的是符号匹配的立方根 // 如果移植到其他语言,请小心 // 特别是如果使用通用的幂函数时 return multiplyMatrices( LMStoOKLab, LMS. map( c=> Math. cbrt( c))); // L 的范围是 [0,1]。用于 CSS 时,乘以 100 并加上百分号 } function OKLab_to_XYZ( OKLab) { // 给定 OKLab,将其转换为相对于 D65 的 XYZ var LMStoXYZ= [ [ 1.2268798758459243 , - 0.5578149944602171 , 0.2813910456659647 ], [ - 0.0405757452148008 , 1.1122868032803170 , - 0.0717110580655164 ], [ - 0.0763729366746601 , - 0.4214933324022432 , 1.5869240198367816 ] ]; var OKLabtoLMS= [ [ 1.0000000000000000 , 0.3963377773761749 , 0.2158037573099136 ], [ 1.0000000000000000 , - 0.1055613458156586 , - 0.0638541728258133 ], [ 1.0000000000000000 , - 0.0894841775298119 , - 1.2914855480194092 ] ]; var LMSnl= multiplyMatrices( OKLabtoLMS, OKLab); return multiplyMatrices( LMStoXYZ, LMSnl. map( c=> c** 3 )); } function OKLab_to_OKLCH( OKLab) { var epsilon= 0.000004 ; var hue= Math. atan2( OKLab[ 2 ], OKLab[ 1 ]) * 180 / Math. PI; var chroma= Math. sqrt( OKLab[ 1 ] ** 2 + OKLab[ 2 ] ** 2 ); if ( hue< 0 ) { hue= hue+ 360 ; } if ( chroma<= epsilon) { hue= NaN ; } return [ OKLab[ 0 ], // L is still L chroma, hue]; } function OKLCH_to_OKLab( OKLCH) { return [ OKLCH[ 0 ], // L is still L OKLCH[ 1 ] * Math. cos( OKLCH[ 2 ] * Math. PI/ 180 ), // a OKLCH[ 1 ] * Math. sin( OKLCH[ 2 ] * Math. PI/ 180 ) // b ]; } // 预乘透明度转换 function rectangular_premultiply( color, alpha) { // 给定一个矩形正交色彩空间中的颜色 // 以及一个 alpha 值 // 返回预乘后的形式 return color. map(( c) => c* alpha) } function rectangular_un_premultiply( color, alpha) { // 给定一个预乘后的矩形正交色彩空间中的颜色 // 以及一个 alpha 值 // 返回实际的颜色 if ( alpha=== 0 ) { return color; // 避免除以零 } return color. map(( c) => c/ alpha) } function polar_premultiply( color, alpha, hueIndex) { // 给定一个柱状极坐标色彩空间中的颜色 // 以及一个 alpha 值 // 返回预乘后的形式 // hueIndex 表示颜色数组中的哪个条目对应色调角度 // 例如在 OKLCH 中是 2 // 而在 HSL 中是 0 return color. map(( c, i) => c* ( hueIndex=== i? 1 : alpha)) } function polar_un_premultiply( color, alpha, hueIndex) { // 给定一个柱状极坐标色彩空间中的颜色 // 以及一个 alpha 值 // 返回实际的颜色 // hueIndex 表示颜色数组中的哪个条目对应色调角度 // 例如在 OKLCH 中是 2 // 而在 HSL 中是 0 if ( alpha=== 0 ) { return color; // 避免除以零 } return color. map(( c, i) => c/ ( hueIndex=== i? 1 : alpha)) } // 可以轻松定义便捷函数,例如 function hsl_premultiply( color, alpha) { return polar_premultiply( color, alpha, 0 ); }
19. ΔE2000和ΔEOK颜色差异的示例代码
本节非规范性。
测试
本节非规范性,不需要测试。
19.1. ΔE2000
最简单的颜色差异指标,ΔE76, 仅仅是在Lab颜色空间中的欧几里得距离。 虽然这作为一个初步近似是可以接受的, 但如印刷和织物染色等对颜色要求较高的行业 很快就开发出了改进的公式。 目前最广泛使用的公式是ΔE2000。 它修正了与ΔE76相比的一些已知的非对称性和非线性。 由于公式复杂, 并且对各种中间计算的符号依赖性很强, 实现常常出错 [Sharma]。
下面的示例代码已通过验证,具有五个有效数字, 使用由[Sharma]发布的成对Lab值和期望的ΔE2000测试套件, 并且是正确的。
// deltaE2000 是对 deltaE76 和 deltaE94 的统计学显著改进 // 并且推荐由 CIE 和 Idealliance 使用 // 尤其适用于颜色差异小于 10 deltaE76 的情况 // 但是它非常复杂 // 许多实现存在小错误! /** * @param {number[]} reference - CIE Lab 值数组:L 为 0..100,a 和 b 大约为 -150..150 * @param {number[]} sample - CIE Lab 值数组:L 为 0..100,a 和 b 大约为 -150..150 * @return {number} 样本颜色与参考颜色的差异程度 */ function deltaE2000( reference, sample) { // 给定参考色和样本色, // 都在 CIE Lab 中, // 计算 deltaE 2000。 // 此实现假定参数加权因子 kL, kC 和 kH // (用于观看条件的影响) // 都为 1,这也是常见的情况。 let [ L1, a1, b1] = reference; let [ L2, a2, b2] = sample; let C1= Math. sqrt( a1** 2 + b1** 2 ); let C2= Math. sqrt( a2** 2 + b2** 2 ); let Cbar= ( C1+ C2) / 2 ; // 平均色度 // 从平均色度计算 a 轴不对称因子 // 使得接近中性的颜色的 JND 椭圆变为圆形 let C7= Math. pow( Cbar, 7 ); const Gfactor= Math. pow( 25 , 7 ); let G= 0.5 * ( 1 - Math. sqrt( C7/ ( C7+ Gfactor))); // 通过不对称因子缩放 a 轴 let adash1= ( 1 + G) * a1; let adash2= ( 1 + G) * a2; // 从缩放后的 a 和原始 b 轴计算新的色度 let Cdash1= Math. sqrt( adash1** 2 + b1** 2 ); let Cdash2= Math. sqrt( adash2** 2 + b2** 2 ); // 计算新的色相,如果是真正的中性色则色相为 0 const π= Math. PI; const r2d= 180 / π; const d2r= π/ 180 ; let h1= ( adash1=== 0 && b1=== 0 ) ? 0 : Math. atan2( b1, adash1); let h2= ( adash2=== 0 && b2=== 0 ) ? 0 : Math. atan2( b2, adash2); if ( h1< 0 ) { h1+= 2 * π; } if ( h2< 0 ) { h2+= 2 * π; } h1*= r2d; h2*= r2d; // 亮度和色度的差异,符号很重要 let ΔL= L2- L1; let ΔC= Cdash2- Cdash1; // 色相差异,注意获取正确的符号 let hdiff= h2- h1; let hsum= h1+ h2; let habs= Math. abs( hdiff); let Δh; if ( Cdash1* Cdash2=== 0 ) { Δh= 0 ; } else if ( habs<= 180 ) { Δh= hdiff; } else if ( hdiff> 180 ) { Δh= hdiff- 360 ; } else if ( hdiff< - 180 ) { Δh= hdiff+ 360 ; } else { console. log( "the unthinkable has happened" ); } let ΔH= 2 * Math. sqrt( Cdash2* Cdash1) * Math. sin( Δh* d2r/ 2 ); let Ldash= ( L1+ L2) / 2 ; let Cdash= ( Cdash1+ Cdash2) / 2 ; let Cdash7= Math. pow( Cdash, 7 ); let hdash; if ( Cdash1== 0 && Cdash2== 0 ) { hdash= hsum; } else if ( habs<= 180 ) { hdash= hsum/ 2 ; } else if ( hsum< 360 ) { hdash= ( hsum+ 360 ) / 2 ; } else { hdash= ( hsum- 360 ) / 2 ; } let lsq= ( Ldash- 50 ) ** 2 ; let SL= 1 + (( 0.015 * lsq) / Math. sqrt( 20 + lsq)); let SC= 1 + 0.045 * Cdash; let T= 1 ; T-= ( 0.17 * Math. cos(( hdash- 30 ) * d2r)); T+= ( 0.24 * Math. cos( 2 * hdash* d2r)); T+= ( 0.32 * Math. cos((( 3 * hdash) + 6 ) * d2r)); T-= ( 0.20 * Math. cos((( 4 * hdash) - 63 ) * d2r)); let SH= 1 + 0.015 * Cdash* T; let Δθ= 30 * Math. exp( - 1 * ((( hdash- 275 ) / 25 ) ** 2 )); let RC= 2 * Math. sqrt( Cdash7/ ( Cdash7+ Gfactor)); let RT= - 1 * Math. sin( 2 * Δθ* d2r) * RC; let dE= ( ΔL/ SL) ** 2 ; dE+= ( ΔC/ SC) ** 2 ; dE+= ( ΔH/ SH) ** 2 ; dE+= RT* ( ΔC/ SC) * ( ΔH/ SH); return Math. sqrt( dE); // Yay!!! };
19.2. ΔEOK
由于 Oklab 不存在 CIE Lab 的色相线性、色相均匀性和色度非线性的问题,因此颜色差异度量不需要对它们进行修正,因此在 Oklab 颜色空间中的颜色差异度量就是简单的欧几里得距离。
// 计算 deltaE OK // 简单的平方和的平方根 /** * @param {number[]} reference - OKLab 值数组:L 范围 0..1,a 和 b 范围 -1..1 * @param {number[]} sample - OKLab 值数组:L 范围 0..1,a 和 b 范围 -1..1 * @return {number} 样本颜色与参考颜色的差异度 */ function deltaEOK( reference, sample) { let [ L1, a1, b1] = reference; let [ L2, a2, b2] = sample; let ΔL= L1- L2; let Δa= a1- a2; let Δb= b1- b2; return Math. sqrt( ΔL** 2 + Δa** 2 + Δb** 2 ); }
附录 A:已废弃的 CSS 系统颜色
CSS 的早期版本定义了几个额外的系统颜色。然而,这些颜色关键字已经被废弃,因为它们对于原来的用途(使网站元素看起来像它们的本地操作系统对应部分)已经不够充分,并且会增加安全风险,容易使网页“伪装”成本地操作系统对话框,从而增加指纹识别面,损害用户隐私。
用户代理必须支持这些关键字,并且为了减轻指纹识别,必须将它们映射到下方列出的(未废弃的)系统颜色。作者不得使用这些关键字。
已废弃的系统颜色表示为<deprecated-color>子类型,并定义为:
- ActiveBorder
- 活动窗口边框。与ButtonBorder相同。
- ActiveCaption
- 活动窗口标题。与Canvas相同。
- AppWorkspace
- 多文档界面的背景色。与Canvas相同。
- Background
- 桌面背景。与Canvas相同。
- ButtonHighlight
- 面对光源的 3D 元素边框的颜色,使这些元素通过一层围绕的边框看起来具有 3D 效果。与ButtonFace相同。
- ButtonShadow
- 远离光源的 3D 元素边框的颜色,使这些元素通过一层围绕的边框看起来具有 3D 效果。与ButtonFace相同。
- CaptionText
- 标题、大小框和滚动条箭头框中的文本。与CanvasText相同。
- InactiveBorder
- 非活动窗口边框。与ButtonBorder相同。
- InactiveCaption
- 非活动窗口标题。与Canvas相同。
- InactiveCaptionText
- 非活动标题中的文本颜色。与GrayText相同。
- InfoBackground
- 工具提示控件的背景色。与Canvas相同。
- InfoText
- 工具提示控件的文本颜色。与CanvasText相同。
- Menu
- 菜单背景。与Canvas相同。
- MenuText
- 菜单中的文本。与CanvasText相同。
- Scrollbar
- 滚动条的灰色区域。与Canvas相同。
- ThreeDDarkShadow
- 3D 元素远离光源的两条边框中较暗的一条(通常是外层边框)的颜色,使这些元素看起来具有 3D 效果。与ButtonBorder相同。
- ThreeDFace
- 3D 元素的表面背景颜色,这些元素通过两层同心边框看起来具有 3D 效果。与ButtonFace相同。
- ThreeDHighlight
- 3D 元素面对光源的两条边框中较亮的一条(通常是外层边框)的颜色,使这些元素看起来具有 3D 效果。与ButtonBorder相同。
- ThreeDLightShadow
- 3D 元素面对光源的两条边框中较暗的一条(通常是内层边框)的颜色,使这些元素看起来具有 3D 效果。与ButtonBorder相同。
- ThreeDShadow
- 3D 元素远离光源的两条边框中较亮的一条(通常是内层边框)的颜色,使这些元素看起来具有 3D 效果。与ButtonBorder相同。
- Window
- 窗口背景。与Canvas相同。
- WindowFrame
- 窗口框架。与ButtonBorder相同。
- WindowText
- 窗口中的文本。与CanvasText相同。
测试
- deprecated-sameas-001.html (实时测试) (来源)
- deprecated-sameas-002.html (实时测试) (来源)
- deprecated-sameas-003.html (实时测试) (来源)
- deprecated-sameas-004.html (实时测试) (来源)
- deprecated-sameas-005.html (实时测试) (来源)
- deprecated-sameas-006.html (实时测试) (来源)
- deprecated-sameas-007.html (实时测试) (来源)
- deprecated-sameas-008.html (实时测试) (来源)
- deprecated-sameas-009.html (实时测试) (来源)
- deprecated-sameas-010.html (实时测试) (来源)
- deprecated-sameas-011.html (实时测试) (来源)
- deprecated-sameas-012.html (实时测试) (来源)
- deprecated-sameas-013.html (实时测试) (来源)
- deprecated-sameas-014.html (实时测试) (来源)
- deprecated-sameas-015.html (实时测试) (来源)
- deprecated-sameas-016.html (实时测试) (来源)
- deprecated-sameas-017.html (实时测试) (来源)
- deprecated-sameas-018.html (实时测试) (来源)
- deprecated-sameas-019.html (实时测试) (来源)
- deprecated-sameas-020.html (实时测试) (来源)
- deprecated-sameas-021.html (实时测试) (来源)
- deprecated-sameas-022.html (实时测试) (来源)
- deprecated-sameas-023.html (实时测试) (来源)
附录 B:已废弃的古怪十六进制颜色
当 CSS 在怪癖模式下解析时,<quirky-color>是一种仅在某些属性中有效的<color>类型:
它在包含或引用这些属性的属性中无效,例如background简写属性,或在函数表示法中如color-mix()
此外,虽然<quirky-color>在解析受影响的属性时必须作为<color>有效,但在@supports规则中,它在CSS.supports()
方法中无效。
<quirky-color>可以表示为<number-token>,<dimension-token>,或<ident-token>,根据以下规则:
-
如果是<ident-token>,则标记的表示必须包含恰好 3 或 6 个字符,且全部为十六进制数字。它表示具有相同值的<hex-color>。
-
如果是<number-token>,则必须设置其整数标志。
序列化整数的值。如果序列化后的值少于 6 个字符,则在其前面添加“0”字符,直到达到 6 个字符。它表示具有相同值的<hex-color>。
-
如果是<dimension-token>,则必须设置其整数标志。
序列化整数的值,并附加标记单位的表示。如果结果少于 6 个字符,则在其前面添加“0”字符,直到达到 6 个字符。它表示具有相同值的<hex-color>。
(换句话说,怪癖模式允许在没有前导“#”的情况下编写十六进制颜色,但具有奇怪的解析规则。)
测试
奇特的十六进制颜色
致谢
除了那些为 CSS Color 3 做出贡献的人之外,编辑们还要感谢 Emilio Cobos Álvarez、Alexey Ardov、Chris Bai、Amelia Bellamy-Royds、Lars Borg、Mike Bremford、Andreu Botella、Dan Burzo、Max Derhak、fantasai、Simon Fraser、Devon Govett、Phil Green、Dean Jackson、Andreas Kraushaar、Pierre-Anthony Lemieux、Tiaan Louw、Cameron McCormack、Romain Menke、Chris Murphy、Isaac Muse、 Jonathan Neal、Chris Needham、Björn Ottosson、Christoph Päper、Brad Pettit、Xidorn Quan、Craig Revie、 Melanie Richards、Florian Rivoal、Jacob Rus、Joseph Salowey、Simon Sapin、Igor Snitkin、Lea Verou、Mark Watson、James Stuckey Weber、Sam Weinig 和 Natalie Weizenbaum。
更改记录
自 2024 年 2 月 13 日候选推荐草案以来的变更
- 阐明了在 color 属性内部,使用的是已解析的继承值(而非原始继承值)
- 列出了颜色类别,例如解析为 sRGB 或支持旧版颜色语法的颜色类别
- 添加了色相归一化示例
- 更正了类似分量表,alpha 缺失,但在正文中描述为类似
- 将不透明度值的序列化收集并阐明到一个章节中
- 阐明了围绕 color-interpolation-method 和宿主语法的措辞
- 定义了用于返回缺失色相的 epsilon
- 对具有缺失色相的消色差颜色使用了更精确的定义(足够接近中心轴)
- 统一使用“颜色分量”而非“颜色通道”(两者之前都在使用)。
- 在未定义或解释的情况下使用了相关色温。添加了信息性参考。
- 导出了术语“预乘”,并始终链接到它
- 已弃用和未弃用系统颜色的等效性不再处于风险之中
- 阐明了“解析 CSS <color>”算法的预期用途
- 为 HTML 兼容序列化添加了更正的示例
- 删除了对 HTML 兼容序列化中缺失值的检查,它们将已经被转换为零
- 移动了关于缺失值变为 0 的说明,使其同时适用于 HTML 兼容序列化和 CSS 序列化
- 为 sRGB 添加了 HTML 兼容的十六进制序列化
- 添加了另一个 xyz-d65 和 xyz-d50 示例
- 阐明了 XYZ 中的哪个分量 (Y) 对应于亮度
- 阐明了 CSS 色域映射适用于实际值而非使用值
- 从 hslToRgb 示例代码中删除了色相归一化,因为输入在解析时已经归一化
- 更正了色域映射算法第 4 步的伪代码
- 阐明了插值是组合两种颜色的最常见情况,但不是唯一情况。
- 确保 deltaE 表中文字具有足够的对比度
- 删除了术语 <absolute-color-function> 的其余用法,为保持一致性改用 <absolute-color> function
- 更新了致谢部分
- 添加了色域网格图
- 根据声明值而非指定值描述了 CSSOM 序列化
- 添加了亮度的导出定义
- 添加了 <opacity-value> 的产生式规则
- 阐明了 hslToRgb 的结果何时在 [0,1] 范围内
- 阐明了 RGB 空间一旦线性化就是可加的
自 2022 年 11 月 1 日的候选推荐草案以来的更改
- 添加了序列化 uint8_t alpha 的步骤,从 cssom-1 中移动
- 恢复了解析时对 HSL 负饱和度的钳制为 0,这是 CSS Color 3 的当前互操作行为
- 插值时,始终转换颜色空间,以便无效的组件成为缺失的组件
- 澄清了何时从序列化中省略 alpha 为 1
- 移除了对色相角度的重复约束为 [0,360],因为这已经完成了
- 修正了 ActiveCaption 的描述,它是一个背景
- 区分了不透明度和 alpha。不透明度属性现在使用 opacity-value(其钳制行为与 alpha-value 不同)
- 澄清了在预乘之前进行前向运算
- 更新了色域映射算法
- 修复了一些关于色相插值的问题
- 澄清了 HWB 的白色或黑色达到 100% 并不足以构成无色彩,关键是其总和
- 避免在 RGB 到 HSL 转换中返回负饱和度;调整色相指向“另一侧”
- 对 ProPhoto 使用 64 位精确矩阵,它没有有理数形式
- 重新计算 Oklab 矩阵以达到 64 位精度(与之前 32 位精度下的结果相同)
- 即使目标未被限定,在色域映射中仍然一致地返回目标颜色空间的 GMA 输出
- 添加了解释为什么 Oklab 的一个 JND 为 0.02 而不是 2
- 澄清了解析 sRGB 值不适用于 color() 函数
- 将 alpha 值定义上移至不透明度属性,澄清不透明度指定值不被钳制
- 系统颜色现在明确允许伪装,以保护隐私
- 修正了 D50 到 D65 的逆色度适应矩阵
- 一致区分线性 Bradford 和原始、更复杂的 Bradford 色度适应算法
- 在色域映射算法中,返回剪裁后的结果,避免不必要的步骤
- 将色度适应矩阵更新为更高精度
- 添加了“解析 css 颜色”的算法,以便非 CSS 规范使用颜色时不必重新发明机制
- 澄清几何色域映射不能将色度投射回原始颜色之外
- 在色域映射讨论中使用术语“几何”而不是“分析”
- 将 HSL 的叙述与语法保持一致(百分比和数字均可接受)
- 修正了 LCH alpha 插值示例,错误地未预乘色相角度
- 修正了 sRGB 和 display-p3 传递函数。(仅当一个分量具有精确值 10.31475 / 255 时才会影响结果,这在每分量 8 或 10 位的情况下是不可能的)
- 澄清了系统颜色的指定值仍然是它们本身
- 添加了对 PNG cICP 块标记图像的提及
- 描述了传递 0/360 时色相增加和减少的行为
- 将 HSL 中无力的描述与其他极坐标颜色模型对齐
- 明确定义了颜色插值的操作顺序
- 添加了关于 calc() 中退化数值常量的提及
- 澄清了 sRGB 中 calc() 具有早期解析和钳制结果的行为
- 澄清了 HWB 色相具有与 HSL 色相相同的缺点
- 添加了亮度与明度的比较和图示
- 添加了色相插值关键字的描述和示例
- 对无色 HWB 颜色使用规范化叙述
- 修正了色相插值角度范围;[0,360) 而不是 [0,360]
- 表达了当 L=0% 或 100% 时显示为黑或白是由于色域映射。移除了错误的无力声明
- 移除了令人困惑的“表示黑色”和“表示白色”的评论
- 澄清了对手 a 和 b 是类比的
- 使用参考范围而不是叙述性描述来定义 RGB 组件,以保持一致性
- 明确参考了百分比转换为数字时 Lab、LCH、Oklab、OKLCh 序列化的百分比参考范围
- 要求 Oklab 插值,移除之前的“可以”,并描述了显式退出
- 将 Lab、LCH、Oklab 和 OKLCh 教程部分标记为非规范性。将一些定义移出非规范部分
- 澄清了插值时,在颜色空间转换之前进行类比组件的检查
- 从 CSS Color 5 回移了 hwb() 语法更改和参考范围
- 定义前向运算必须在无力操作之前进行
- 澄清了在传统 rgb() 语法中必须是全数字或全百分比的颜色组件
- 澄清了对于传统语法,颜色组件必须是全百分比或全数字
- 添加了在 calc() 中指定超出范围的 alpha 的示例
- 将带修剪后尾随零的颜色序列化示例放置到相关文本
- 澄清了 currentColor 的解析
- 更新了致谢部分
- 停止声称无色颜色具有缺失的 a、b 或色度
- 将 HSL 和 HWB 更改为无界色域,以促进来回转换
- 定义 HSL 的百分比参考范围
- 现代颜色语法 hsl() 和 hsla() 允许混合数字和百分比分量
- 现代颜色语法 rgb() 和 rgba() 允许混合数字和百分比分量
- 定义术语“现代颜色语法”(“传统颜色语法”已定义)
- 一致使用术语“类比组件”
- 更改为允许所有预定义的色彩空间进行插值
- 澄清了对于 color(),需要三个参数(RGB 或 XYZ)
- 澄清了命名颜色、系统颜色和透明的序列化
- 定义 Lab、LCH、Oklab、OKLCh 的指定值
- 定义其他 sRGB 颜色的指定值
- 定义命名颜色和系统颜色的指定值
- 在解析值时间钳制 alpha、明度、色度和色相
- 移除对高光白和 CIE 明度的提及
- 不再要求保留指定的色相;钳制到 [0, 360]
- 在示例中保持明度和数字的序列化一致性
- 轻微的拼写错误和编辑性澄清
自 2022 年 7 月 5 日的候选推荐草案以来的更改
- 移除了色相插值的“指定”值
- 更精确地定义了色相插值角度,保持 360 度的差异
- 添加了预乘运算中携带前向 alpha 的示例
- 澄清了 L=100% 时 a,b 和 C,h 无效,表示白色
- 移除了对 L=400 的随意提及,它适用于 hdr-CIELAB 而非 CIE Lab
- 一致地使用 Oklab 和 OKLCh 的大小写
- 将有效颜色、无效颜色、超出色域和在色域内的定义移动到术语部分
- 修正了“更长”色相插值的定义
- 进一步澄清了主机语法的概念
- 改进了颜色样本的可访问性
- 明确指出传统形式不支持“none”
- 从色相生成中移除了“none”,因为它在传统语法中不允许
- 移除了一些与 CMYK 和 CMYKOGV 相关的残余引用,移动到 CSS Color 5
- 澄清了插值颜色中缺失的值是如何前向传递的
- 更新了 xyz-params 的语法,使其接受数字和百分比,以与叙述保持一致
- 确保所有示例和图示都有 ID,自引用链接
- 澄清了对实现者来说阅读色域映射介绍的重要性
- 移除了剩余的自定义色彩空间提及(该功能已移至 CSS Color 5)
- 重构了 <color> 和 <alpha-value> 的语法
- 编辑性重构以获得更好的阅读顺序
- 更新了色域映射算法的伪代码,移除不必要的 deltaE 调用
自 2022 年 6 月 28 日的工作草案以来的更改
- 更新了候选推荐的状态
自 2022 年 4 月 28 日的工作草案以来的更改
- 将不透明度属性移动到模块顶部,紧邻颜色属性,进入详细内容之前
- 改进了对 color 属性的描述,特别是其对其他属性的影响
- 修正了等于模 360 颜色的更长色相调整方程
- 添加了两个新的系统颜色:AccentColor 和 AccentColorText
- 在新部分中描述了整体的颜色空间转换步骤
- 考虑了 none alpha 在预乘和反预乘中的影响
自 2021 年 12 月 15 日的工作草案以来的更改
- 使系统颜色完全解析,但禁止在强制颜色模式中更改它们
- 移除了对 color() 函数中参数数量不正确的宽容处理
- 将 CIE Lightness 和 OK Lightness 的序列化更改为数字而非百分比
- 将已废弃的系统颜色等价标记为风险项
- 为 CIE 和 OK L,a,b,C 的百分比值添加了参考范围
- 指出有用于执行和撤销预乘运算的示例代码,适用于矩形和极坐标颜色空间
- 为色域映射叙述以及伪代码添加了超出范围的钳制
- 添加了 ProPhoto RGB / ROMM 的规范性参考
- 修正了 sRGB 和 Display P3 参考围绕的黑点值
- 添加了 Display P3 的规范性参考
- 避免了在色域减少中出现无限循环,对比白色或比黑色更暗的颜色
- 澄清了 none 值的序列化
- 澄清了 Oklab 中非传统颜色的插值选择加入
- 定义了预乘运算的工作原理,涉及 none 值
- 澄清了在 RGB 中缺失的值序列化为 0
- 澄清了与 none 值一起使用 calc() 的行为
- 系统颜色中拼写错误和大小写不一致的问题
- 添加了 SelectedItem 和 SelectedItemText 的示例
- 明确提到遗留颜色的存在与否
- 添加了 CIE XYZ 的规范性参考
- 添加了 HWB 和 HSL 的规范性参考
- 澄清了 hwb() 不是传统语法,因此不支持旧的逗号分隔形式
- 澄清了只有遗留颜色会进行色域映射,其他颜色是无界的
- 使用不同术语,分光光度计和分光辐射计
- 修复了一些小拼写错误,并进行了语法改进
自 2021 年 6 月 1 日的工作草案以来的更改
- 添加了色域映射部分,并定义了 CSS 色域映射算法为 OKLCh 中的色度缩减,使用局部 MINDE
- color(xyz ...) 的计算值为 color(xyz-d65 ...)
- 将 srgb-linear 添加到插值颜色空间中
- 更新了来自 Colors 3 的更改部分
- 添加了解析 Oklab 和 OKLCh 值的部分
- 添加了 srgb-linear 颜色空间
- 根据 CSSWG 决议将 @color-profile 和 device-cmyk 移至 5 级
- 定义了插值颜色空间
- 澄清了矩阵是行优先的,并链接到矩阵乘法库
- 将旧的安全与隐私部分拆分为单独的部分
- 定义了怪癖模式下的古怪十六进制颜色
- 移除了 device-cmyk 中的后备颜色
- 未声明默认值的主机语法现在默认使用 Oklab
- 添加了 deltaE OK 的示例代码
- 添加了 OKlab 和 OKLCh 的示例转换代码
- 添加了 oklab() 和 oklch() 函数 添加了 Oklab 和 OKLCh 的描述
- 添加了 CIE LCH 的缺陷描述
- 允许颜色的所有组件通过 none 关键字“缺失”,定义了组件在某些情况下何时“无效”并自动变为缺失,并将所有对“NaN”组件的引用修正为使用“缺失”概念
- 定义了明确的 x,y 白点值,并在整个过程中保持一致
- 定义了主机语法的术语
- 定义了解决覆盖颜色上下文的背景
- 添加了一对新的系统颜色
- 修正了 HSL 和 HWB 的示例代码
- 用无错误版本替换了 HSL 值表
- 根据 WG 决议添加 Lea Verou 为共同编辑
- 澄清了色相角度是无界的
- 修正了 MarkText 示例
- 添加了图示,修正了示例
- 一些编辑性澄清
- 修正了一些小拼写错误和标记错误
自 2020 年 11 月 12 日的工作草案以来的更改
- 指出在接近中性的 Lab 值转换为 LCH 时的不确定色相问题
- 澄清了 RGB 和 Lab 互换中的哪些步骤是线性组合
- 在 @color-profile 中添加了组件描述符,用于 CSS Color 5
- 所有预定义的 RGB 色彩空间均定义为扩展范围
- 澄清了在颜色插值之前没有色域映射或色域裁剪步骤
- 澄清了传统 sRGB 语法的插值
- 从 color() 中移除了 lab 选项
- 列出了在预定义色彩空间之间互换的步骤
- 一致使用“色彩空间”这一术语(两个词)
- 提供了有关选择用于混合的色彩空间的更多指导
- 重新计算了一个示例以提高精度
- 添加了色相插值示例
- 通过移除后备选项简化了 color() 语法
- 澄清了可以从 @color-profile 链接的 ICC 配置文件类型
- 移除了对罕见 ICC 命名颜色的支持
- 提高了标准白点色度精度
- 移除了对一个预定义色彩空间描述中的商标
- 重新措辞使插值在插值空间方面更加通用
- 修正了可访问性考虑部分
- 澄清了 color() 的色彩空间参数是必需的,即使是 sRGB
- 澄清了 currentColor 不仅限于 sRGB
- 对 sRGB 到 XYZ 到 sRGB 矩阵进行了小的修正,以提高往返精度
- 澄清了 rec2020 传递函数,并引用了正确的 ITU Rec BT.2020-2 参考
- 修正了后备示例,以使用正确的语法
- 不强制非传统颜色在伽马编码空间中进行插值
- 定义了预乘 alpha 插值
- 开始处理到 currentColor 的插值
- 定义了包含 NaN 的色相插值
- 使颜色插值更加通用
- 定义插值为 Lab 中,覆盖为 LCG
- 对色相插值进行了修正
- 定义了色相角度插值
- 添加了插值部分
- 修正了一些示例中的语法
- 澄清了 color() 中允许百分比的组件
- 更改了 lch() 的序列化方式,不再作为 lab() 序列化
- 对于 color() 中的非传统 sRGB,组件精度最低为 10 位
- color() 中的色彩空间不再是可选的
- 在 lab() 和 color(lab) 之间保持一致的最低精度
- 澄清了 color() 函数的后备过程:第一个有效的在色域内的颜色,否则第一个有效颜色,然后映射色域,否则为透明黑
- 澄清了不透明度属性与具有不透明度的颜色之间的差异,特别是在渲染重叠文本字形时
- 添加了 ΔE2000 的示例代码(经过验证)
- 添加了之前未定义的术语“色度”的定义,并给出了示例;定义了色度图
- 添加了颜色加法性的解释和示例
- 为 WPT 测试添加了源链接
- 导出颜色和有效颜色的定义,以供其他规范引用
- 定义序列化时每个组件的最低位数
- 更新了“适用于”定义(CSS 的普遍更改)
- 为预定义色彩空间添加了图像状态(显示参考或场景参考)
- 列出了白点相关色温(例如 D65),以便于与色度坐标区分
- 澄清了四舍五入的方向为 +∞
- 修正了拼写错误、标记修正、链接修正
自 2019 年 11 月 5 日的工作草案以来的更改
- 导出一些术语以供其他规范使用
- 将 WCAG 2.0 要求更新为 2.1
- 完整指定序列化中使用的 Unicode 字符
- 定义特殊命名颜色的序列化
- 定义 device-cmyk() 的序列化
- 定义 color() 的序列化
- 以最大程度兼容网络的方式完全定义 RGB 的序列化
- 定义 Lab 和 LCH 的序列化
- 完全定义 alpha 值的序列化
- 一致性检查,以避免意外的 RFC2119
- 为所有示例添加 ID 以便引用
- 将已解析颜色和序列化颜色部分分开
- (安全性)ICC 配置文件不包含可执行代码
- 定义对已配置颜色的超出范围含义
- 澄清了超出范围的钳制
- 添加了指定值的示例
- 澄清了计算值
- 通过对已废弃的系统颜色进行强制映射来抵抗指纹识别
- 添加了关于标准化 X11 颜色的历史和原因的解释性注释
- 修正了 hwb 示例代码
- 为 MacBeth 色块添加了 DeltaE2000 值的表
- 添加了关于 ICC 配置文件互联网媒体类型的注释
- 添加了对 PNG sRGB 块的参考
- 澄清了 CMYK 到 Lab 的互换
- 澄清了 RGB 到 Lab 的互换
- 更多对 HSL 和 LCH 的比较
- 更多对 Rec BT.2020 色彩空间的描述
- 更新了对 prophoto-rgb 的描述
- 移除了值定义部分中重复的“关键字”
- 添加了无效颜色的示例
- 添加了包含多个后备的示例
- 修复了一些拼写错误和标记修正
- 澄清了未声明自定义色彩空间的处理
- 澄清了一些示例和解释性说明
- 处理有效和无效 ICC 配置文件的处理
- 定义了对具有显式标记色彩空间的图像的处理
- 定义了 4k、SDR 视频的色彩空间
- 声明用户对比度设置必须优先
- 澄清了系统颜色在强制颜色模式之外的含义
- 更新了默认样式规则
- 在 color() 中添加了 CIE XYZ 色彩空间
- 更清楚地说明了色相角度,明确允许 NaN
- 改进了系统颜色配对部分,要求 AA 可访问对比度
- 警告了重叠字形和不透明度属性之间的交互
- 修正了颜色定义中的语法
- 改进了对 Highlight/HighlightText 的描述
- 修正了 prophoto-rgb 的传递函数
- 为 prophoto-rgb 原色提供了更高的精度
- 开始定义“无法显示”的概念
- 移除了有关画布表面的段落
- 添加了 buttonborder、mark 和 marktext 系统颜色
- 添加了反向转换,sRGB 到 HWB
- 澄清了极坐标空间是圆柱形的,而非球形的
- 添加了可访问性考虑部分
- 开始描述色度缩减色域映射,而不是按分量剪裁
- 修正了 rec2020 的白色色度
- 通过 @color-profile 使 device-cmyk 可用;更新了 CMYK 到颜色的算法,仅在最后手段时使用简单转换
- 添加了面向打印的 CMYK 和 KCMYOGV 示例
- 用户定义的色彩空间现在使用虚线标识符,使预定义色彩空间可扩展且无冲突
- 在 color() 函数中添加了 lab 选项
- 添加了 CIE Lab 的规范性参考
- 阐明了 prophoto-rgb 使用 D50 白点,因此不需要适应
- 澄清了在 LCH 中增加角度的方向
- 澄清了颜色名称对 ASCII 不区分大小写
- “color”属性的初始值现在为 CanvasText
- 根据 CSS WG 决议移除了令人困惑的 gray() 函数
- 将零散的定义收集到新的颜色术语部分
- 添加了有用的图示和更多的示例
- 一些小的编辑澄清、拼写检查、修复拼写错误、bikeshed 标记修正
自 2016 年 7 月 5 日的工作草案以来的更改
- 将 Lab 和 LCH 中的明度更改为百分比,以提高与 CSS 的兼容性
- 明确了颜色值的钳制
- 现在允许使用百分比透明度
- 定义术语 sRGB 和线性光 sRGB,供其他规范使用
- 添加了新的 CSS 系统颜色列表;将 Text 重命名为 CanvasText
- 使系统颜色关键字计算为它们自身
- 为系统颜色添加计算/使用条目
- 重写了未废弃系统颜色的介绍,使其使用集中于强制颜色模式而非通用使用
- 在预定义色彩空间中使用一致的连字符
- 恢复了关于非不透明元素在没有定位时仍然绘制在图层上的文本
- "color" 属性的初始值现在为黑色
- 澄清了 LCH 中的色相是模 360 度(现已撤销此更改)
- 澄清了 LCH 和 Lab 中 L 的允许范围及 L=100 的含义
- 更新了用于视频的色彩空间的参考
- 添加了 prophoto-rgb 预定义色彩空间
- 修正了 display-p3 的黑白亮度水平
- 澄清了 display-p3 的传递函数
- 添加了 a98-rgb 色彩空间,修正了原始色度的表格
- 澄清了 currentColor 的计算值不是解析后的颜色
- 更新了示例中的语法以符合最新规范
- 移除了 color-mod() 函数
- 从属性定义表中删除了“媒体”项
- 导出并一致使用“透明黑”和“不透明黑”
- 澄清了计算值(如百分比)
- 澄清了颜色组件所需的精度和四舍五入行为
- 澄清了“color”属性对颜色字体字形没有影响(除非特别引用,例如使用 currentColor)
- 澄清了颜色值如何解析
- 澄清了 HSL、HWB 和命名颜色解析为 sRGB
- 简化了从 device-cmyk 到 sRGB 的转换
- 将以前使用逗号的颜色语法描述为“遗留的”;将示例更改为不带逗号的形式
- 移除了要求显示的颜色必须限制在设备色域内的多余要求(似乎没有其他选项!)
- 将 P3 重命名为 display-p3;避免声称它是 DCI P3,因为它们并不相同
- 改进了对“color()”函数参数的描述
- 禁止在“@color-profile”标识符中使用预定义的色彩空间
- 为“color”、“color-adjust”和“opacity”属性定义添加规范顺序
- 将 alpha 合成定义从 SVG11 切换到 CSS 合成
- 澄清示例转换代码是非规范性的
- 添加了安全和隐私考虑
- 更新了多个参考文献至最新版本
- 将内联问题转换为 GitHub 问题的链接
- 一些小的编辑澄清、格式和标记改进
来自 Colors 3 的更改
与 CSS Color 3 相比,主要的变化是 CSS 颜色不再局限于 sRGB 的窄色域。
为了支持这一点,添加了几个全新的功能:
其他技术变更:
- <color> 的序列化现在在此处指定,而不是在 CSS 对象模型中指定
- hwb() 函数,用于以 HWB 表示法指定 sRGB 颜色。
- 添加了命名颜色 rebeccapurple。
此外,还进行了一些语法更改:
- rgb() 和 rgba() 函数现在接受 <number> 而不是 <integer>。
- hsl() 和 hsla() 函数现在接受 <angle> 和 <number> 作为色相。
- rgb() 和 rgba(),以及 hsl() 和 hsla() 现在是彼此的别名 (它们都有一个可选的 alpha)。
- rgb()、rgba()、hsl() 和 hsla() 都获得了一种新的语法, 该语法由空格分隔的参数和一个可选的斜杠分隔的不透明度组成。 现在所有颜色函数都使用这种语法形式, 以符合 CSS 的函数表示法设计原则。
- <alpha-value> 的所有用法现在都接受 <percentage> 和 <number>。
- 添加了 4 位和 8 位十六进制颜色,以指定透明度。
- 添加了 none 值,用于表示无效分量。
20. 安全性考虑
系统颜色,如果它们实际上对应于用户的系统颜色,则会带来安全风险,因为它们使恶意软件网站更容易创建看起来像是来自系统的用户界面。然而,由于现在有几个系统颜色被定义为“通用”,因此认为此风险已得到缓解。
21. 隐私性考虑
本规范定义了“系统”颜色,理论上可能会暴露用户操作系统设置的详细信息,这是一种指纹识别风险。
22. 可访问性考虑
本规范鼓励作者不要仅使用颜色作为区分特征。
本规范鼓励浏览器确保特定系统颜色前景/背景对之间的足够对比度。曾考虑过使用具有特定 AA 或 AAA 对比度的更严格要求,但由于浏览器通常只是传递操作系统做出的颜色选择,或由用户选择(用户可能有特定要求,包括对偏头痛或癫痫发作患者降低对比度),CSSWG 无法要求特定的对比度水平。