合成与混合 第1级

W3C 候选推荐草案,

关于本文档的更多详情
此版本:
https://www.w3.org/TR/2024/CRD-compositing-1-20240321/
最新发布版本:
https://www.w3.org/TR/compositing-1/
编辑草案:
https://drafts.fxtf.org/compositing-1/
以前版本:
历史记录:
https://www.w3.org/standards/history/compositing-1/
实现报告:
https://wpt.fyi/results/css/compositing
反馈:
CSSWG 问题库
GitHub
https://github.com/w3c/fxtf-drafts/labels/compositing-1
编辑:
(Google)
前编辑:
Rik Cabanier (时为 Adobe Systems Inc.)
(佳能信息系统研究澳大利亚)
测试套件:
https://wpt.fyi/results/css/compositing/

摘要

合成描述了如何将不同元素的形状组合成单个图像。对于合成有多种可能的方法。以前版本的 SVG 和 CSS 使用了简单 Alpha 合成。在这种模型中,每个元素都会渲染到自己的缓冲区中,然后使用 Porter Duff source-over 操作符与其背景合并。此规范将定义一个新的合成模型,基于简单 Alpha 合成模型扩展,提供以下功能:

此外,本规范将定义用于混合和组隔离的 CSS 属性,以及 globalCompositeOperation 属性的特性。CSS 是一种用于描述结构化文档 (如 HTML 和 XML) 在屏幕、纸张等上的渲染语言。

本文档的状态

本节描述了本文档在发布时的状态。 当前 W3C 发布物的列表和该技术报告的最新修订版可在 W3C 技术报告索引 https://www.w3.org/TR/ 找到。

本文档由 CSS 工作组 作为候选推荐草案发布,采用 推荐路径。 发布为候选推荐不表示 W3C 及其成员的认可。 候选推荐草案整合了工作组打算包含在后续候选推荐快照中的前一个候选推荐的变更。

这是一个草案文档,可能随时更新、替换或被其他文档废弃。 除非作为正在进行的工作,否则引用此文档是不合适的。

请通过在 GitHub 上提交问题(首选)反馈意见,并在标题中包括规范代码“compositing”,例如: “[compositing] …评论摘要…”。 所有问题和评论均归档。 另外,反馈也可以发送到(归档)公共邮件列表 www-style@w3.org

本文档受 2023年11月03日 W3C 进程文档 管辖。

本文档由根据 W3C 专利政策 运营的小组制作。 W3C 维护了与该小组交付物相关的任何专利披露的公共列表; 该页面还包含披露专利的说明。 个人如果实际知道某项专利,并认为该专利包含基本权利要求,必须按照W3C 专利政策第6节披露信息。

1. 简介

本小节为非规范性内容。
本文档的第一部分描述了用于控制 CSS 中合成的属性。 第二部分将描述 Porter Duff 合成和混合的算法。

2. 阅读本文档

除非另有说明,否则本文档的每个部分都是规范性的。

2.1. 模块交互

本规范定义了一组 CSS 属性,这些属性影响应用这些属性的元素的视觉渲染;这些效果在元素根据 视觉格式化模型[CSS21] 中定位和大小调整后应用。其中某些属性的值会导致创建包含块,或创建层叠上下文

background-blend-mode 属性还基于 CSS 背景与边框模块中的属性[CSS3BG]进行扩展。

本规范还增强了 第 14.2 节 简单 alpha 合成 中的规则,来自 [SVG11]简单 alpha 合成,来自 [CSS-COLOR-4]

本模块还扩展了 globalCompositeOperation 属性。

2.2.

本规范遵循 CSS 属性定义约定,来自 [CSS21]。本规范中未定义的值类型在 CSS 第 2 版修订版 [CSS21] 中定义。其他 CSS 模块可能会扩展这些值类型的定义:例如,当与本模块结合使用时,[CSS-COLOR-4] 扩展了本规范中使用的 <color> 值类型的定义。

除定义中列出的特定于属性的值外, 本规范中定义的所有属性也接受 inherit 关键字作为其属性值。为了可读性,未显式重复该值。

3. 在 CSS 中指定混合

3.1. 图形操作顺序

合成模型必须遵循 SVG 合成 模型 [SVG11]:首先应用任何滤镜效果,然后进行剪裁、遮罩、混合和合成。

3.2. HTML 特定行为

CSS 中创建层叠上下文的所有内容必须视为“隔离”组。HTML 元素本身不应创建组。

应用混合的元素,必须与该元素所属的层叠上下文 [CSS21]中的所有底层内容进行混合。

HTML 文档的根元素是文档元素

3.3. SVG 特定行为

默认情况下,每个元素都必须创建一个非隔离组

但是,SVG 中的某些操作会创建隔离组。如果使用以下功能之一,组必须变为隔离的:

SVG 的根元素是SVG 元素

3.4. CSS 属性

3.4.1. mix-blend-mode 属性

混合模式定义了必须用于将颜色与背景混合的公式。 此行为在混合中有更详细的描述。

名称: mix-blend-mode
值: <blend-mode>
初始值: normal
应用于: 所有元素。在 SVG 中,它适用于容器元素图形元素图形引用元素[SVG11]
继承:
百分比: N/A
计算值: 按指定
规范顺序: 按语法
动画类型: 离散
媒体: 视觉

属性 <blend-mode> 的语法如下:

<blend-mode> =
  normal |
  darken | multiply | color-burn |
  lighten | screen | color-dodge |
  overlay | soft-light | hard-light |
  difference | exclusion |
  hue | saturation | color | luminosity

normal 以外的混合模式应用于元素,必须创建一个新的层叠上下文 [CSS21]。然后必须将该组与包含该元素的层叠上下文进行混合和合成。

测试

给定以下示例标记:

<body>
  <img src="ducky.png">
</body>

以及以下样式规则:

body { background-color: lime; }

... 将产生以下结果:

文件中鸭子图片与绿色背景的示例

部分透明的图片在绿色背景上

如果我们将样式规则更改为包括混合:

body { background-color: lime; }
img { mix-blend-mode: multiply; }

... 输出将是图像与 <body> 元素的绿色背景进行混合。

鸭子图片与文件绿色背景混合的示例

透明图像在绿色背景上的混合效果。

给定以下 SVG 代码:

<svg>
  <circle cx="40" cy="40" r="40" fill="red">
  <circle cx="80" cy="40" r="40" fill="lime">
  <circle cx="60" cy="80" r="40" fill="blue">
</svg>

以及以下样式规则:

circle { mix-blend-mode: screen; }

... 输出将是三个圆的混合效果。每个圆从底部到顶部依次渲染。元素重叠的区域中,混合模式会改变颜色。

三个圆形以屏幕混合模式混合的示例

屏幕混合模式下三个圆的混合示例

在以下样式表和文档片段中:

body { background-color: lime; }
div { background-color: red; width: 200px; opacity: .95}
img { mix-blend-mode: difference; }

<body>
  <div>
     <img src="ducky.png">
  </div>
</body>

... <div> 元素上的 不透明度 导致创建了一个层叠上下文。这创建了一个新的组,因此图像不会与 <body> 的颜色混合。

鸭子图片与文件绿色背景混合的示例

在层叠上下文中的混合示例。

请注意图像没有与绿色背景混合。

给定以下示例标记:

<body>
   <div>
     <p>overlay 混合在文本上</p>
   </div>
</body>

以及以下样式规则:

div { background-image: url('texture.png'); }
@font-face {
  font-family: "Mythos Std";
  src: url("http://myfontvendor.com/mythos.otf");
}
p {
  mix-blend-mode: overlay;
  font-family: "Mythos Std"
}
带有覆盖混合效果的文字在纹理图像上

带有混合覆盖效果的文字在图像上

3.4.2. isolation 属性

在 SVG 中,这定义了一个元素是否是隔离的。
对于 CSS,将 isolation 设置为 isolate 会将元素变成一个层叠上下文。

默认情况下,元素使用 auto 关键字,这意味着它们不是隔离的。 但是,会导致创建层叠上下文的操作 [CSS21] 必须导致组被隔离。这些操作在 'HTML 特定行为''SVG 特定行为' 中描述。

名称: isolation
值: <isolation-mode>
初始值: auto
应用于: 所有元素。在 SVG 中,它适用于容器元素图形元素图形引用元素[SVG11]
继承:
百分比: N/A
计算值: 按指定
规范顺序: 按语法
动画类型: 离散
媒体: 视觉

属性 <isolation-mode> 的语法如下:

<isolation-mode> = auto | isolate
测试

在 CSS 中,背景图像或 img 的内容必须始终渲染到隔离组中。
例如,如果你通过 img 标签链接到一个 SVG 文件,则该 SVG 的作品不会与内容的背景混合。

在 SVG 中,mask 始终创建一个隔离组。

3.4.3. background-blend-mode 属性

定义每个背景层的混合模式。

每个背景层必须与其下方的元素背景层以及元素的背景颜色混合。背景层不得与元素背后的内容混合,而是必须像在隔离组中渲染一样运行。

background-blend-mode 属性的描述如下:

名称: background-blend-mode
值: <blend-mode>#
初始值: normal
应用于: 所有 HTML 元素
继承:
百分比: N/A
计算值: 按指定
规范顺序: 按语法
动画类型: 离散
媒体: 视觉
测试

列表中的 background-blend-mode 必须按与 background-image 相同的顺序应用 [CSS3BG]。这意味着列表中的第一个元素将应用于顶部的图层。如果属性没有足够的逗号分隔值来匹配图层数量,UA 必须通过重复值列表来计算其使用值,直到有足够的值。

如果使用 background 简写 [CSS3BG],则该元素的 background-blend-mode 属性必须重置为其初始值。

给定以下示例标记:

<body>
   <div></div>
</body>

以及以下样式规则:

body { background-color: lime; }
div {
  width: 200px;
  height: 200px;
  background-size: 200px 200px;
  background-repeat:no-repeat;
  background-image: linear-gradient(to right, #000000 0%,#ffffff 100%), url('ducky.png');
  background-blend-mode: difference, normal;
}
带有鸭子图片和渐变背景混合的 div 示例

两个背景图像的混合。

注意,渐变并未与 body 的颜色混合。相反,它保留了原始颜色。

4. 在 Canvas 2D 中指定合成和混合

canvas 2d 上下文定义了 globalCompositeOperation 属性,该属性用于设置当前的合成和混合操作符。

该属性接受以下值:

‘globalCompositeOperation’
值: <blend-mode> | <composite-mode>
初始值: source-over

<composite-mode> 属性的语法如下:

<composite-mode> = clear | copy | source-over | destination-over | source-in |    
destination-in | source-out | destination-out | source-atop |
destination-atop | xor | lighter
测试

5. 合成简介

合成是将图形元素与其背景进行组合的过程。

在本规范描述的模型中,整体合成操作分为两步 - Porter-Duff 合成混合。 混合步骤决定了图形元素与背景的颜色如何相互作用。

通常,先执行混合步骤,然后再进行 Porter-Duff 合成步骤。 在混合步骤中,计算图形元素和 背景 颜色混合的结果色。图形元素的颜色将被此结果色替换。 然后,使用指定的合成操作符将图形元素与 背景 进行合成。

注意: 形状由形状的数学描述定义。某一点要么在形状内部,要么不在。没有渐变。

注意: 不透明度使用与每个特定点的颜色值一起存储的 alpha 值来描述。alpha 值在 0 和 1 之间,包括这两个值。 值为 0 表示该像素在该点上没有覆盖,因此是透明的;即没有几何体的颜色贡献,因为几何体没有覆盖该像素。值为 1 表示像素完全不透明;几何体完全覆盖了该像素。

5.1. 简单 alpha 合成

简单 alpha 合成的公式为

co = Cs x αs + Cb x αb x (1 - αs)

其中

注意: 所有值都在 0 到 1 之间。

合成后的像素值 (co) 是通过加上源图形元素 [Cs x αs] 和背景 [Cb x αb x (1 - αs)] 的贡献得出的。 对于图形元素和背景,颜色值乘以 alpha 以确定颜色的贡献量。 Alpha 值为 0 意味着颜色不贡献,而部分 alpha 值意味着颜色贡献了一部分。 背景的贡献进一步根据图形元素的不透明度减少。 从概念上讲,(1 - αs) 的背景显示在图形元素后面,这意味着如果图形元素完全不透明 (αs=1),则背景不会显示。

上面列出的简单 alpha 合成公式给出了结果色,该结果色是背景色和图形元素色的加权平均值,权重由背景和 图形元素的 alpha 决定。 合成结果的 alpha 值是合成元素的贡献 alpha 之和。 合成结果的 alpha 值公式为

αo = αs + αb x (1 - αs)

其中

通常,更有效的做法是存储颜色和不透明度的 预乘值。 预乘值为

cs = Cs x αs

其中

因此,使用预乘值的简单 alpha 合成公式变为

co = cs + cb x (1 - αs)

要提取预乘值的颜色分量,公式为:

Co = co / αo

5.1.1. 简单 alpha 合成的示例

显示 alpha 合成的简单框

这是最基本的情况。它由一个用实色填充的形状(α = 1)组成。 该形状与空背景进行合成。空背景对合成结果没有影响。

Cs = RGB(1,0,0)
αs = 1
Cb = RGB(0,0,0)
αb = 0

co = Cs x αs + Cb x αb x (1 - αs)
co = RGB(1,0,0) x 1 + RGB(0,0,0) x 0 x (1 - 1)
co = RGB(1,0,0) x 1
co = RGB(1,0,0)

简单形状

这是一个更复杂的示例。没有透明度,但两个形状相交。

在相交区域应用合成公式,得出:

Cs = RGB(0,0,1)
αs = 1
Cb = RGB(1,0,0)
αb = 1

co = Cs x αs + Cb x αb x (1 - αs)
co = RGB(0,0,1) x 1 + RGB(1,0,0) x 1 x (1 - 1)
co = RGB(0,0,1) x 1 + RGB(1,0,0) x 1 x 0
co = RGB(0,0,1) x 1
co = RGB(0,0,1)

计算合成结果的 alpha 值

αo = αs + αb x (1 - αs)
αo = 1 + 1 x (1 - 1)
αo = 1

计算合成结果的颜色分量

Co = co / αo
Co = RGB(0, 0, 1) / 1
Co = RGB(0, 0, 1)

不透明盒子上方透明盒子的交互作用

这是一个示例,其中形状具有一定的透明度,但 背景 完全不透明。

在相交区域应用合成公式,得出:

Cs = RGB(0,0,1)
αs = 0.5
Cb = RGB(1,0,0)
αb = 1

co = Cs x αs + Cb x αb x (1 - αs)
co = RGB(0,0,1) x 0.5 + RGB(1,0,0) x 1 x (1 - 0.5)
co = RGB(0,0,1) x 0.5 + RGB(1,0,0) x 0.5
co = RGB(0.5,0,0.5)

计算合成结果的 alpha 值

αo = αs + αb x (1 - αs)
αo = 0.5 + 1 x (1 - 0.5)
αo = 1

计算合成结果的颜色分量

Co = co / αo
Co = RGB(0.5, 0, 0.5) / 1
Co = RGB(0.5, 0, 0.5)

两个透明盒子的交互作用

图 4 显示了一个示例,其中形状和 背景 都是透明的。

在相交区域应用合成公式,得出:

Cs = RGB(0,0,1)
αs = 0.5
Cb = RGB(1,0,0)
αb = 0.5

co = Cs x αs + Cb x αb x (1 - αs)
co = RGB(0,0,1) x 0.5 + RGB(1,0,0) x 0.5 x (1 - 0.5)
co = RGB(0,0,1) x 0.5 + RGB(1,0,0) x 0.25
co = RGB(0.25, 0, 0.5)

计算合成结果的 alpha 值

αo = αs + αb x (1 - αs)
αo = 0.5 + 0.5 x (1 - 0.5)
αo = 0.75

计算合成结果的颜色分量

Co = co / αo
Co = RGB(0.25, 0, 0.5) / 0.75
Co = RGB(0.33, 0, 0.66)

6. 合成和混合的通用公式

合成和混合的通用公式允许选择合成运算符和混合函数,包含两个步骤。 这些函数中使用的术语将在以下章节中详细描述。

进行原位混合

Cs = (1 - αb) x Cs + αb x B(Cb, Cs)

合成

Co = αs x Fa x Cs + αb x Fb x Cb

其中:

7. 背景计算

背景 是元素背后的内容,是与元素合成的部分。 这意味着背景是合成所有先前元素的结果。

7.1. 背景计算示例

简单背景计算的示例

该示例包含两个简单形状。蓝色形状的背景包括红色形状的右下角。 虚线显示了合成蓝色形状时检查的区域。

带有 alpha 值的背景示例

背景中的形状具有 alpha 值。在计算背景时,背景形状的 alpha 值被保留。

8. 合成组

合成组允许更好地控制合成与背景的交互。可以使用组来指定组内的合成效果将如何与场景中已经存在的内容(背景)进行交互。

合成组可以由任意数量的元素组成,并且可以包含其他合成组。

合成组的默认属性不会导致与没有组时的视觉差异。参见 组不变性

合成组通过首先将组的元素合成到初始背景上来渲染。结果是一个包含颜色和 alpha 信息的单一元素。然后将该元素合成到组背景上。 需要确保组背景只对最终合成做出一次贡献。

初始背景
初始背景是用于合成组第一个元素的背景。在非隔离组中,这将与组背景相同,而在隔离组中则为完全透明的背景。
组背景
组背景是合成所有元素(不包括组中的第一个元素)的结果。

8.1. 组不变性

简单 alpha 合成的一个重要特性是其组不变性。该行为在本规范中描述的更复杂的模型中得以保留。 添加或删除具有默认属性的分组不应显示视觉差异。

so: A + B + C = A + (B + C) = (A + B) + C

当向组中添加诸如 isolate 之类的属性,或使用 normal 以外的混合模式或 source-over 以外的 Porter Duff 合成操作符时,组可能不再具有不变性。

8.2. 隔离组

在隔离组中,初始背景应为黑色且完全透明。

在这种情况下,初始背景与组背景不同。只有当组的计算颜色、形状和 alpha 与组背景合成时,才会发生与组背景的交互。

有关隔离组对合成的影响的描述,请参见 '隔离组和 Porter Duff 模式'。 有关隔离组对混合的影响的描述,请参见 '组隔离对混合的影响'。

8.3. 根元素组

隔离组 的根元素是根元素组。所有其他元素和组都合成到该组中。根元素的背景(如果指定)被绘制到 根元素组中,然后应用任何滤镜、剪裁路径、遮罩和不透明度, 在合成到 根组 中之前(如果存在)。

测试

8.4. 根组

根组包含整个画布,并包含(或位于)网页根元素的根元素组之下。

浏览器通常使用无限的白色、100% 不透明的根组进行最终合成,但这不是必需的。

9. 高级合成功能

简单 alpha 合成 使用 source-over Porter Duff 合成操作符。

Porter Duff 合成基于像素模型,其中两个形状(源和目标)可能对像素的最终颜色做出贡献。像素被分为四个子像素区域,每个区域代表源和目标的可能组合。[PORTERDUFF]

四个区域分别是:

仅源
只有源对像素颜色做出贡献
仅目标
只有目标对像素颜色做出贡献
两者
源和目标 - 源和目标都可能组合定义像素颜色
无源或目标 - 两者都不对最终像素颜色做出贡献

注意:目标与背景同义。在本节中使用“目标”这一术语,因为这是使用 Porter Duff 合成时的标准。此外,合成操作符名称中使用了 destination

受 Porter Duff 影响的区域概述

每个区域对最终像素颜色的贡献由该像素的形状覆盖范围和使用的操作符定义。 覆盖范围用 alpha 表示。完整的 alpha (1) 表示完全覆盖,而 alpha 为零 (0) 表示没有覆盖。 这意味着子像素中每个区域的面积取决于对像素贡献的每个形状的覆盖范围。 每个区域的面积可以通过以下公式计算:

两者 αs x αb
仅源 αs x (1 – αb)
仅目标 αb x (1 – αs)
(1 – αs) x (1 – αb)

上图表示源和目标的覆盖范围均为 0.5。

两者 = 0.5 x 0.5 = 0.25
仅源 = 0.5 (1 – 0.5) = 0.25
仅目标 = 0.5(1 – 0.5) = 0.25
无 = (1 – 0.5)(1 – 0.5) = 0.25

因此,在此示例中,每个区域的覆盖范围为 0.25。

9.1. Porter Duff 合成操作符

Lucasfilm 的 Thomas Porter 和 Tom Duff 的开创性论文定义了合成的代数并开发了十二个“Porter Duff”操作符。这些操作符控制着图形对象重叠形成的四个子像素区域的混合结果,这些图形对象具有 alpha 或像素覆盖通道/值。操作符使用了四个区域的所有实际组合。

共有 12 个基本的 Porter Duff 操作符,满足源和目标的所有可能组合。

从每个操作符的几何表示可以看出,每个形状的贡献表示为输出总覆盖范围的一个分数。 例如,在 source-over 模式中,源的可能贡献为全部 (1),目标的可能贡献为剩余的部分 (1 – αs)。这由源和目标的覆盖范围修改,以得出像素最终覆盖范围的公式:

αo = αs x 1 + αb x (1 – αs)

分数项 Fa(此示例中的 1)和 Fb(此示例中的 1 – αs)由每个操作符定义,并指定可能对最终像素值贡献的形状分数。 覆盖范围的通用公式为:

αs x Fa + αb x Fb

结合颜色,得到 Porter Duff 的通用公式

co = αs x Fa x Cs + αb x Fb x Cb

其中:

9.1.1. 清除

没有启用的区域。

Porter Duff 清除示例

Fa = 0; Fb = 0
co = 0
αo = 0

9.1.2. 复制

只有源会显示。

Porter Duff 复制示例

Fa = 1; Fb = 0
co = αs x Cs
αo = αs

9.1.3. 目标

只有目标会显示。

Porter Duff 目标示例

Fa = 0; Fb = 1
co = αb x Cb
αo = αb

9.1.4. 源覆盖

源被放置在目标上方。

Porter Duff 源覆盖示例

Fa = 1; Fb = 1 – αs
co = αs x Cs + αb x Cb x (1 – αs)
αo = αs + αb x (1 – αs)

9.1.5. 目标覆盖

目标被放置在源上方。

Porter Duff 目标覆盖示例

Fa = 1 – αb; Fb = 1
co = αs x Cs x (1 – αb) + αb x Cb
αo = αs x (1 – αb) + αb

9.1.6. 源内

与目标重叠的源替换目标。

Porter Duff 源内示例

Fa = αb; Fb = 0
co = αs x Cs x αb
αo = αs x αb

9.1.7. 目标内

与源重叠的目标替换源。

Porter Duff 目标内示例

Fa = 0; Fb = αs
co = αb x Cb x αs
αo = αb x αs

9.1.8. 源外

源被放置在目标之外的地方。

Porter Duff 源外示例

Fa = 1 – αb; Fb = 0
co = αs x Cs x (1 – αb)
αo = αs x (1 – αb)

9.1.9. 目标外

目标被放置在源之外的地方。

Porter Duff 目标外示例

Fa = 0; Fb = 1 – αs
co = αb x Cb x (1 – αs)
αo = αb x (1 – αs)

9.1.10. 源顶置

与目标重叠的源替换目标。目标被放置在其他地方。

Porter Duff 源顶置示例

Fa = αb; Fb = 1 – αs
co = αs x Cs x αb + αb x Cb x (1 – αs)
αo = αs x αb + αb x (1 – αs)

9.1.11. 目标顶置

与源重叠的目标替换源。源被放置在其他地方。

Porter Duff 目标顶置示例

Fa = 1 - αb; Fb = αs
co = αs x Cs x (1 - αb) + αb x Cb x αs
αo = αs x (1 - αb) + αb x αs

9.1.12. 异或 (XOR)

源和目标的非重叠区域被组合。

Porter Duff 异或示例

Fa = 1 - αb; Fb = 1 – αs
co = αs x Cs x (1 - αb) + αb x Cb x (1 – αs)
αo = αs x (1 - αb) + αb x (1 – αs)

9.1.13. 更亮

显示源图像和目标图像的总和。它在 Porter Duff 论文中被定义为 plus 操作符 [PORTERDUFF]

Fa = 1; Fb = 1
co = αs x Cs + αb x Cb;
αo = αs + αb

9.2. 组合群组行为与Porter Duff模式

在隔离的群组内组合元素时,这些元素会被组合在透明的黑色初始背景上。如果群组中的底层元素使用依赖背景的Porter Duff组合操作符,比如 destinationsource-indestination-indestination-outsource-atop, 那么组合结果将会是空的。群组内后续的元素将与第一次组合的结果进行组合。

10. 混合

混合是组合的一个方面,它计算源元素和背景重叠区域的颜色混合。
概念上,源元素中的颜色在与背景混合时被保留在原地。混合后,修改过的源元素与背景进行组合。 实际上,这通常是一步完成的。
混合计算不能使用预乘色值。

“混合”公式定义为:

Cm = B(Cb, Cs)

其中:

混合公式的结果必须被限制在颜色范围的最小和最大值之间。

混合函数的结果受背景透明度的调制。完全不透明的背景允许混合函数完全实现。透明背景会导致最终结果是源颜色和混合颜色之间的加权平均,权重由背景透明度控制。 新颜色的值变为:

Cr = (1 - αb) x Cs + αb x B(Cb, Cs)

其中:

带透明度的混合示例

此示例展示了一个红色矩形带有混合模式,并放置在一组具有不同不透明度的绿色矩形上方。

请注意,随着背景透明度的降低,顶部矩形颜色逐渐向红色过渡。

注意:以下公式给出了源和背景交叠区域的颜色值,然后与指定的Porter Duff组合公式进行组合。对于简单的alpha混合,公式变为:

简单alpha混合:
    co = cs + cb x (1 - αs)
写为非预乘形式:
    αo x Co = αs x Cs + (1 - αs) x αb x Cb
现在将混合结果代入Cs:
    αo x Co = αs x ((1 - αb) x Cs + αb x B(Cb, Cs)) + (1 - αs) x αb x Cb
            = αs x (1 - αb) x Cs + αs x αb x B(Cb, Cs) + (1 - αs) x αb x Cb

10.1. 可分离混合模式

如果结果颜色的每个分量完全由组成的背景和源颜色的相应分量确定,则这种混合模式称为可分离的,即混合公式分别应用于每组相应的分量。

以下每种混合模式都将在每个颜色分量上应用混合函数B(Cb, Cs)。为简化起见,本章中的所有示例都使用源覆盖组合。

10.1.1. 正常混合模式

这是默认属性,指定无混合。混合公式简单地选择源颜色。

B(Cb, Cs) = Cs
正常混合示例

10.1.2. 正片叠底混合模式

源颜色与目标颜色相乘并替换目标颜色。

结果颜色总是与源或目标颜色一样深或更深。将任何颜色与黑色相乘会产生黑色,将任何颜色与白色相乘会保留原始颜色。

B(Cb, Cs) = Cb x Cs
正片叠底混合示例

10.1.3. 滤色混合模式

先乘以背景和源颜色值的补色,然后补充结果。

结果颜色总是与两个组成颜色中的任一个一样亮或更亮。用白色滤色产生白色;用黑色滤色保持原始颜色不变。效果类似于同时将多个幻灯片投影到一个屏幕上。

B(Cb, Cs) = 1 - [(1 - Cb) x (1 - Cs)]
          = Cb + Cs -(Cb x Cs)
滤色混合示例

10.1.4. 叠加混合模式

根据背景颜色值对颜色进行相乘或滤色处理。

源颜色叠加在背景上,同时保留其高光和阴影。背景颜色不会被替换,而是与源颜色混合以反映背景的亮度或暗度。

B(Cb, Cs) = 硬光(Cs, Cb)

叠加是硬光混合模式的反向。请参阅硬光的定义以获取公式。

叠加混合示例

10.1.5. 变暗混合模式

选择背景和源颜色中较暗的颜色。

当源颜色较暗时,背景将被替换;否则保持不变。

B(Cb, Cs) = min(Cb, Cs)
变暗混合示例

10.1.6. 变亮混合模式

选择背景和源颜色中较亮的颜色。

当源颜色较亮时,背景将被替换;否则保持不变。

B(Cb, Cs) = max(Cb, Cs)

如果结果超出范围,必须向下取整。

变亮混合示例

10.1.7. 颜色减淡混合模式

使背景颜色变亮以反映源颜色。使用黑色绘制不会产生任何变化。

if(Cb == 0)
    B(Cb, Cs) = 0
else if(Cs == 1)
    B(Cb, Cs) = 1
else
    B(Cb, Cs) = min(1, Cb / (1 - Cs))
颜色减淡混合示例

10.1.8. 颜色加深混合模式

使背景颜色变暗以反映源颜色。使用白色绘制不会产生任何变化。

if(Cb == 1)
    B(Cb, Cs) = 1
else if(Cs == 0)
    B(Cb, Cs) = 0
else
    B(Cb, Cs) = 1 - min(1, (1 - Cb) / Cs)
颜色加深混合示例

10.1.9. 硬光混合模式

根据源颜色值对颜色进行相乘或滤色处理。效果类似于用强烈的聚光灯照射背景

if(Cs <= 0.5)
    B(Cb, Cs) = 正片叠底(Cb, 2 x Cs)
else
    B(Cb, Cs) = 滤色(Cb, 2 x Cs -1)

请参阅正片叠底滤色的定义以获取它们的公式。

硬光混合示例

10.1.10. 柔光混合模式

根据源颜色值对颜色进行变暗或变亮处理。效果类似于用柔和的聚光灯照射背景

    if(Cs <= 0.5)
        B(Cb, Cs) = Cb - (1 - 2 x Cs) x Cb x (1 - Cb)
    else
        B(Cb, Cs) = Cb + (2 x Cs - 1) x (D(Cb) - Cb)
with
    if(Cb <= 0.25)
        D(Cb) = ((16 * Cb - 12) x Cb + 4) x Cb
    else
        D(Cb) = sqrt(Cb)
柔光混合示例

10.1.11. 差值混合模式

从较亮的颜色中减去两种组成颜色中的较暗者。

用白色绘制会反转背景颜色;用黑色绘制不会产生任何变化。

B(Cb, Cs) = | Cb - Cs |
差值混合示例

10.1.12. 排除混合模式

产生类似于差值模式的效果,但对比度较低。用白色绘制会反转背景颜色;用黑色绘制不会产生任何变化。

B(Cb, Cs) = Cb + Cs - 2 x Cb x Cs
排除混合示例

10.2. 不可分离混合模式

不可分离的混合模式结合所有颜色分量,而不是像可分离的那样单独考虑每个分量。 所有这些混合模式概念上都涉及以下步骤:

  1. 背景和源颜色从混合颜色空间转换为中间的色相-饱和度-亮度表示。
  2. 背景和源颜色中选择的色相、饱和度和亮度组件组合创建新颜色。
  3. 将结果转换回原始颜色空间。

不可分离的混合模式公式使用几个辅助函数:

    Lum(C) = 0.3 x Cred + 0.59 x Cgreen + 0.11 x Cblue

    ClipColor(C)
        L = Lum(C)
        n = min(Cred, Cgreen, Cblue)
        x = max(Cred, Cgreen, Cblue)
        if(n < 0)
            C = L + (((C - L) × L) / (L - n))

        if(x > 1)
            C = L + (((C - L) × (1 - L)) / (x - L))

        return C

    SetLum(C, l)
        d = l - Lum(C)
        Cred = Cred + d
        Cgreen = Cgreen + d
        Cblue = Cblue + d
        return ClipColor(C)

    Sat(C) = max(Cred, Cgreen, Cblue) - min(Cred, Cgreen, Cblue)

The subscripts min, mid, and max in the next function refer to the color
components having the minimum, middle, and maximum values upon entry to the function.

    SetSat(C, s)
        if(Cmax > Cmin)
            Cmid = (((Cmid - Cmin) x s) / (Cmax - Cmin))
            Cmax = s
        else
            Cmid = Cmax = 0
        Cmin = 0
        return C;

10.2.1. 色相混合模式

使用源颜色的色相以及背景颜色的饱和度和亮度创建颜色。

B(Cb, Cs) = SetLum(SetSat(Cs, Sat(Cb)), Lum(Cb))
色相混合示例

10.2.2. 饱和度混合模式

使用源颜色的饱和度以及背景颜色的色相和亮度创建颜色。如果在背景的纯灰色区域(无饱和度)上使用此模式绘制,不会产生任何变化。

B(Cb, Cs) = SetLum(SetSat(Cb, Sat(Cs)), Lum(Cb))
饱和度混合示例

10.2.3. 颜色混合模式

使用源颜色的色相和饱和度以及背景颜色的亮度创建颜色。这保留了背景的灰度级,非常适合为单色图像着色或为彩色图像着色。

B(Cb, Cs) = SetLum(Cs, Lum(Cb))
颜色混合示例

10.2.4. 亮度混合模式

使用源颜色的亮度以及背景颜色的色相和饱和度创建颜色。此效果与颜色模式相反。

B(Cb, Cs) = SetLum(Cb, Lum(Cs))
亮度混合示例

10.3. 隔离组对混合的影响

注意: 在下面的例子中,用于构造纸飞机的元素位于一个组内。每个元素的混合模式都设置为 multiply。

左边的飞机是普通组,右边的飞机是一个隔离组

在隔离组中,组内的元素被组合到一个空的初始背景上,这阻止了组内的元素与背景相乘。 在普通组中,组内的元素组合到包含土地和天空的初始背景上。因此,飞机的元素与土地和天空相乘。 在这两种情况下,组合成的结果都通过正常的混合模式(应用于组的默认混合模式)与土地和天空组合。

隔离组混合示例

隐私注意事项

此规范未报告任何新的隐私问题。

安全注意事项

重要的是,混合和合成操作的时间与源像素和目标像素无关。操作的实现方式必须确保无论像素值如何,操作所需的时间始终相同。

如果不遵守此规则,攻击者可能会推断出信息并发动计时攻击。

计时攻击是一种基于研究操作发生所需时间的方法,用于获取受保护的内容。如果,例如,绘制红色像素比绘制绿色像素花费更多时间,攻击者可能在没有访问元素内容的情况下重建元素的粗略图像。

更改

相对于2015年1月13日候选推荐标准做出了以下更改:

相对于2014年2月20日候选推荐标准做出的更改:

相对于2014年1月7日最后一次工作草案做出的更改:

相对于2013年10月10日工作草案做出的更改:

测试

符合性

文档约定

符合性要求通过描述性声明和 RFC 2119 术语的组合来表达。规范中的“必须”(MUST)、“不得”(MUST NOT)、“需要”(REQUIRED)、“应”(SHALL)、“不应”(SHALL NOT)、“应”(SHOULD)、“不应”(SHOULD NOT)、“推荐”(RECOMMENDED)、“可以”(MAY)和“可选”(OPTIONAL)等关键词应按 RFC 2119 的描述进行解释。 然而,为了可读性,本规范中这些词汇并没有全部大写。

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

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

这是一个信息性示例。

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

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

告示是需要特别关注的规范性部分,使用样式声明,像这样: UA 必须提供可访问的替代方案。

测试

与本规范内容相关的测试可能会记录在类似于此的“测试”块中。任何此类块都是非规范性的。


符合性类别

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

样式表
CSS 样式表
渲染器
解释样式表语义并渲染使用它们的文档的用户代理
创作工具
编写样式表的用户代理

如果样式表中使用的语法符合通用 CSS 语法和本模块中每个功能定义的语法,则该样式表符合本规范。

如果渲染器除了按照相关规范解释样式表外,还通过正确解析并渲染文档来支持本规范中定义的所有功能,则该渲染器符合本规范。然而,由于设备限制而无法正确渲染文档并不意味着 UA 不符合规范。(例如,UA 不需要在单色显示器上渲染颜色。)

如果创作工具编写的样式表在语法上符合通用 CSS 语法和本模块中每个功能的语法,并满足本模块描述的样式表的所有其他符合性要求,则该创作工具符合本规范。

部分实现

为了使作者能够利用向前兼容的解析规则分配回退值,CSS 渲染器必须将无法使用的级别支持的任何规则、属性、属性值、关键字以及其他语法构造视为无效,并按适当方式忽略它们。特别是,用户代理不得选择性忽略不支持的组件值并在单个多值属性声明中应用支持的值:如果任何值被视为无效(如不支持的值必须这样),CSS 要求忽略整个声明。

不稳定和专有功能的实现

为了避免与未来稳定的 CSS 功能发生冲突,CSSWG 建议遵循最佳实践来实现不稳定功能和专有扩展到 CSS。

非实验性实现

一旦规范进入候选推荐阶段,可以进行非实验性实现,且实现者应发布任何 CR 级别功能的无前缀实现,前提是他们能够证明这些功能根据规范被正确实现。

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

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

CR 退出标准

为了将本规范推进到建议推荐阶段,每个功能至少需要有两个独立的、可互操作的实现。每个功能可以由不同的产品集实现,不要求所有功能都由单一产品实现。为满足此标准,以下术语定义如下:

独立的
每个实现必须由不同的方开发,且不能共享、重用或派生自另一合格实现使用的代码。与本规范的实现无关的代码部分不受此要求的约束。
可互操作的
通过官方 CSS 测试套件中的相应测试用例,或者如果实现不是 Web 浏览器,则通过等效的测试。每个相关的测试在测试套件中应有等效的测试创建,如果使用此类用户代理(UA)声称互操作性,则必须有一个或多个其他 UA 也能以相同的方式通过这些等效测试以实现互操作性。等效测试必须公开供同行评审。
实现
一个用户代理,它:
  1. 实现了规范。
  2. 向公众开放。该实现可以是正式发布的产品,也可以是其他公开可用的版本(如测试版、预览版或“每夜构建”)。非正式发布的产品必须至少实现这些功能一个月,以证明其稳定性。
  3. 不是实验性的(即,专为通过测试套件而设计的版本,且不打算继续作为常规使用版本)。

该规范将至少保持候选推荐状态六个月。

索引

本规范定义的术语

由引用定义的术语

参考文献

规范性参考文献

[CSS-COLOR-4]
Tab Atkins Jr.; Chris Lilley; Lea Verou. CSS Color Module Level 4. 2022年11月1日. CR. URL: https://www.w3.org/TR/css-color-4/
[CSS-MASKING-1]
Dirk Schulze; Brian Birtles; Tab Atkins Jr.. CSS Masking Module Level 1. 2021年8月5日. CR. URL: https://www.w3.org/TR/css-masking-1/
[CSS-VALUES-4]
Tab Atkins Jr.; Elika Etemad. CSS Values and Units Module Level 4. 2023年12月18日. WD. URL: https://www.w3.org/TR/css-values-4/
[CSS21]
Bert Bos 等. 级联样式表 第2级修订版 (CSS 2.1) 规范. 2011年6月7日. REC. URL: https://www.w3.org/TR/CSS21/
[CSS3BG]
Elika Etemad; Brad Kemper. CSS Backgrounds and Borders Module Level 3. 2023年12月19日. CR. URL: https://www.w3.org/TR/css-backgrounds-3/
[HTML]
Anne van Kesteren 等. HTML 标准. 现行标准. URL: https://html.spec.whatwg.org/multipage/
[RFC2119]
S. Bradner. 在RFC中指示需求等级的关键字. 1997年3月. 最佳现行实践. URL: https://datatracker.ietf.org/doc/html/rfc2119
[SVG11]
Erik Dahlström 等. 可缩放矢量图形 (SVG) 1.1 (第二版). 2011年8月16日. REC. URL: https://www.w3.org/TR/SVG11/

参考性参考文献

[PORTERDUFF]
Thomas Porter; Tom Duff. 数字图像合成. 1984年7月.

属性索引

名称 初始值 适用于 继承性 百分比 动画类型 规范顺序 计算值 媒体
background-blend-mode <blend-mode># normal 所有HTML元素 no N/A 离散 按语法 按指定 视觉
isolation <isolation-mode> auto 所有元素。在SVG中,它适用于容器元素、图形元素和图形引用元素。[SVG11] no N/A 离散 按语法 按指定 视觉
mix-blend-mode <blend-mode> normal 所有元素。在SVG中,它适用于容器元素、图形元素和图形引用元素。[SVG11] no N/A 离散 按语法 按指定 视觉