前端开发者学堂 - fedev.cn

CSS中的合成与混合模式

发布于 Blueed

如果你是一个设计师,你很可能已经遇到或者总有一天会遇到混合效果。混合在图形和印刷设计方面是使用最频繁的效果之一。你可以通过混合文字和纹理背景来给文字添加纹理,通过把图片混合营造出图片融合的错觉,并创造出广泛而丰富多彩的效果,如果对混合控制没有达到如此精细的程度是不可能创造出这些效果的。

CSS中的合成与混合模式

Graphics editors such as Photoshop or Illustrator come with a set of blending modes. Blend modes allow you to specify how you want your elements to blend together, thus changing the colors of the area where these elements intersect. Each mode uses a specific color formula to mix the colors of the source and the destination.

例如Photoshop或Illustrator这样的制图软件自带了一系列混合模式。混合模式让你可以指定混合的元素,从而改变元素交叉区域的颜色。每个模式使用特定颜色公式来混合基色和目标色。

不同的模式产生不同最终结果。既然我们提到了目标元素,那么在我们讨论不同混合模式前,让我们快速的了解一下合成的概念,以及它和CSS中的混合有什么关系。

##合成是什么?

合成是图形元素与背景结合。

背景元素后面的内容并且也是元素与之合成的内容。

CSS中的合成与混合模式

合成定义了你将要绘制的元素会如何与画布上已经绘制的元素混合。源元素是你想要绘制的元素,目标元素是已经绘制的元素(背景)。

所以,如果你有两个元素,这些元素重叠在一起,你可以把位于上层的元素当做源元素,另一个元素位于它下层的部分是目标元素。

使用不同的混合操作(共有16种),你可以指定两个重叠元素的哪些部分被绘制,哪些不绘制。

CSS中的合成与混合模式

这些混合操作叫做Porter Duff混合操作。这些操作指定源和目标的哪些部分被绘制,混合模式指定图形元素(源)上的颜色如何与背景(目标)混合。上面图片中的插图来自合成和混合规范。在HTML5 Canvas的背景中,这些操作通过globalCompositeOperation属性指定,可以用来把背景裁切成特定图形,例如文字,从而在画布上创建纹理填充文本的效果。我已经在Codrops上的这篇文章中提到了这个过程。

总之,Porter Duff合成和混合是对于交叉元素的总体合成操作。根据规范,“首先进行混合步骤,然后进行Porter-Duff合成步骤。在混合步骤中,会计算混合元素的合成色以及背景。图形元素的颜色被合成色替代。图形元素随后使用指定合成操作与背景合成。”

因此,处理两个相交或重叠的元素的方法是基于一个混合模式混合颜色,然后只绘制合成操作指定的部分。

在CSS中,没有办法指定合成操作。默认使用的合成操作是源元素-覆盖。源元素和目标元素都保留,使用指定混合模式混合它们重叠的区域。

合成和混合规则提出前,CSS只有一种合成操作:简单alpha合成。这是opacity属性的作用。改变元素的不透明度,浏览器中元素变透明从而使背景显示出来。

如今,已经有两个主要的属性让我们可以指定16种可用混合模式的一种来混合元素和背景图片。这两个属性是 background-blend-modemix-blend-mode。让我们都来了解一下。

##混合背景层:background-blend-mode属性

background-blend-mode属性,像名字一样,用来给元素背景层指定一个混合模式。背景层可以是图片,或背景色。

换句话说,background-blend-mode允许你把元素的背景图片和它背后的图片和/或背景色混合在一起。

如果这个元素有超过一张的背景图,你可以指定多个混合模式-每个混合模式用在一个背景图上并且列表上的第一个混合模式对应背景图列表中的第一张背景图,以此类推。

随后,背景层与元素的背景层以及元素的背景色混合。意味着,如果你有两张背景图和一个背景色:

background-image: url(first-image.png), url(second-image.png);
background-color: orange;
background-blend-mode: screen, multiply;

背景图second-image.png会使用multiply模式和背景色混合,背景图first-image.png会使用screen模式和第二张图片以及背景色混合。(提示:第一张背景图位于上层,随后一张位于下层。)

注意元素的背景层不能和元素后面的内容混合,它们必须表现得被渲染成一个隔离组

还要注意如果使用了background的速记形式,这个元素的background-blend-mode属性必须重置成初始值。

##混合模式

既然每个背景层可以指定混合模型来与它下面的层混合。但是我们可以用哪些混合模式选项呢?

CSS里有16中可用的混合模式:normal (默认混合模式代表没有添加混合模式), multiply, screen, overlay, darken, lighten, color-dodge, color-burn, hard-light, soft-light, difference, exclusion, hue, saturation, colorluminosity

例如,每个滤镜应用在图片上时,会产生不同的最终结果-图片的颜色为会根据你选择的模式变化。

###normal

默认模式指定没有混合。混合公式简单得选择基色。

###multiply

基色和目标色复合后替换目标色。合成色至少与基色或目标色一样深。任何颜色与黑色复合得到黑色。任何颜色与白色复合保持初始颜色。

###screen

把背景色的互补色与基色混合,取结果的互补色。合成色至少和两个构成色一样浅。**任何颜色与白色滤色产生白色;和黑色滤色颜色不变。**效果类似于在一个屏幕上投影多个幻灯片。

###overlay

对颜色正片叠底或滤色依赖于背景色值。基色覆盖背景同时保留高光和阴影。背景色没有被替换但是与基色混合来反映背景的亮暗。

###darken

选择背景和基色的较暗部分。背景被基色中较暗的部分替换;否则,保持不变。

###lighten

选择背景和基色中较亮的部分。背景被基色中较亮的部分替换;否则,保持不变。

###color-dodge

减淡背景色来反映基色。黑色绘制的部分不变。

###color-burn

加深背景色来反映基色。白色绘制的部分不变。

###hard-light

对颜色正片叠底或滤色依赖于基色值。效果类似于在背景上用强聚光灯照射。

###soft-light

使颜色变暗或变亮,取决于基色值。效果类似于在背景上用发散的聚光灯照射。

###difference

从较浅的颜色中减去两个组成颜色的较深部分。白色绘制的部分背景反色;黑色绘制的部分不变。

###exclusion

产生类似于差值模式的效果但是对比度更低。白色绘制的部分背景反色;黑色绘制的部分不变。

###hue

创建于基色的色相、饱和度和亮度相同的颜色。

###saturation

创建饱和度与基色相同,色相和亮度与背景色相同的颜色。在背景是纯灰(没有饱和度)的区域使用这个模式不产生改变。

###color

创建色相和量度和基色相同,饱和度和背景色相同的颜色。保持背景的灰度并且对于给单色图片或图片着色很有用。

###luminosity

创建亮度和基色相同,色相和饱和度与背景色相同的颜色。这个模式产生的效果和Color模式相反。你可以用这个模式创建和许多网页头部图片效果一样的单色图片效果。

下面图片展示了在一张图片上应用不同混合模式的结果,跟上述提到的顺序一致,从左上角开始。

CSS中的合成与混合模式

要获取更多这些混合模式的信息,我推荐你SLR Lounge博客上的这篇文章。这篇文章被称为混合模式终极视觉指南,确实包括一些关于混合模式非常好的解释。

从个人角度而言,我认为即使眼前有每个模式的定义,要预测出对一张图片应用这些模式的结果依然是很难的(几乎不可能)。

在大多数情况下,选择合适的混合模式将会是经历一系列试验和错误的结果。如果你用过Instagram那么一定知道有时候你会尝试每一个可用的滤镜,一个个应用,直到你获得了想要的效果。(我就这样做!)这在css混合模式中,几乎是一样的。

因此,我创建了一个简单的互动演示你可以用来为达到想要效果选择正确的混合模式。

CSS中的合成与混合模式

上传一张图片,选择想要混合的背景色。实时预览(缩略图)的背景色会随着你在拾色器中的移动实时更新。点击缩略图会在更大的预览区域预览选择的混合模式。

在线案例

当然,只有在支持background-blend-mode属性的浏览器中才能看见效果。要获取更多浏览器支持信息,参考CanIUse.com上的支持性表格

除了演示例子中的把背景图和背景色混合,你也可以把文字和有背景的元素混合。

然而要把分离元素混合到一起需要除了background-blend-mode之外的属性。下面让我们来看一看。

##将元素与背景中的元素混合:mix-blend-mode属性

我们之前提到,背景元素背后的部分也是元素与之复合的部分。

元素背后的部分可以是任何东西-包括其他元素。这里会产生有趣的效果。试想一下当页面向下滚动时固定的头部和内容混合,或者文字和背景上的图片混合,或者文字和其他文字混合等等。

使用mix-blend-mode属性把元素混合在一起。

mix-blend-mode属性类似于background-blend-mode属性,使用相同的混合模式值。所以你可以指定任何混合模式来达到不同的混合效果。

例如,下面图片中的文字与下方图片使用mix-blend-mode: difference混合,表现出水泡穿过并且在文字上方的错觉。这个效果的原理是difference模式下的颜色反转。

CSS中的合成与混合模式

这幅图片与文字重叠的地方是文字背景,也是混合的地方。你可以在这里查看在线演示。

使用mix-blend-mode,你可以创建许多创造性效果-远不止我在这片文章中列的这些。你可以创建的一个特别有趣的效果是-穿透的文字。没有CSS混合模式的话,你需要CSS遮罩和/或背景裁剪,以及一些CSS hackery来创建这些效果并使之生效。

通过混合模式,再一次使用difference混合模式,你可以再一次借助反色过程创造这样的效果。

下面图片实际展示了效果。这不过是一段·文字,位于一张图片上方并且与之混合。

CSS中的合成与混合模式

这很酷,不是吗?你可以在这里查看在线演示。

值得注意的是你选择的色彩严重影响最终结果。也就是说,互动演示让你更简单快速得选择正确颜色来到达这一效果。

在这个互动演示中,你可以选择在预览区域添加编辑文字,给文字赋予样式并使用mix-blend-mode与预览图片混合。下面是这个例子的截图。

CSS中的合成与混合模式

在线案例

当我们讨论把元素混合在一起时,只有在提到层级时才有意义,尤其是考虑到它们会对把什么样的元素如何混合在一起产生影响。

根据规范,在元素上应用除normal外的混合模式必须在它之上建立一个新的层级,形成一组。这个组必须被包含这个元素的层级混合并复合。

另外,应用了混合的元素,必须和所有这个元素所属层级的底层内容混合。它不会和背景外的内容混合。

例如,下面的图片展示了用overlay模式混合两张图片的结果(在线演示)

"CSS中的合成与混合模式"

上面这个简单例子的代码如下:

<div class="container">
  <img src="path/to/destination.png" alt="" />
  <div class="img-wrapper">
    <img src="path/to/source.png" alt="" class="source"/>
  </div>
</div>

我把上方的图片(.source)包裹在我想要创建层叠环境的一个div中。因为当给opacity属性一个除了默认值(1)之外的值时会导致新层的创建,我将用到这一。

.img-wrapper {
  opacity: .99;
}

(去在线例子尝试)

通过创建层叠环境,.source图片不再和底部图片混合,因为后者在包含前者的层叠环境之外。

这是因为我们把图片和(和任何其他.img-wrapper背景的内容)元素的其余部分隔离了,因此它们不会再和背景混合。

这把我们引入了isolation属性。在我们继续前,注意mix-blend-mode属性也可以应用在SVG元素上,用来把重叠的SVG元素混合在一起。事实上,CSS混合事例的logo就是把mix-blend-mode应用在三个方形上组成的。你可以看到三个方形重叠的区域由于颜色混合的应用有不同的颜色。

mix-blend-mode属性的浏览器支持不像background-blend-mode属性一样广泛。更多细节,参考CanIUse.com上的支持性表格

##隔离元素:isolation属性

当一个能导致层叠环境创建的属性应用在元素上时,我们称这个元素被隔离。上一节的最后一个例子是一个这种情况的例子。

另一方面,你可以使用isolation属性来隔离元素。

在SVG中,这个属性定义一个元素是否被隔离。在CSS中,设置isolationisolate会把元素变为层叠环境,因此影响元素的内容是否会和这个环境外的背景混合。默认的,isolation属性被设置为auto-代表着它们没有被隔离。

如果我们回到之前两个混合图片的例子,我们可以使用isolation属性而不是opacity属性来防止上层图片与它后面的图片混合。

.img-wrapper {
  isolation: isolate;
}

这和之前的例子中使用opacity有一样的效果。如果你在线上例子中使用这个规则而不是opacity,会得到一样的结果。

注意通过在元素上创建层叠环境,你把元素的内容隔离并且防止它们和这个元素的背景混合。然而,你仍然可以给整个环境应用混合模式来把它与背景混合。

而且,如果你正在用background-blend-mode属性,isolation就没有必要了因为背景层一定不会和元素后面的内容混合,规范中规定,它们必须表现出被渲染在一个隔离组中(元素自身)。这就是为什么isolation属性和mix-blend-mode一起用时有效,和background-blend-mode属性一起用时无效。

##注意:图形操作的顺序

CSS混合模式,滤镜遮罩,都可以应用在相同元素上。但是哪个效果会首先应用呢?

根据规范,首先任何滤镜效果会被应用,然后是任何裁剪,遮罩,混合以及复合。

##总结

通过CSS的所有可用图形操作,我们有了更多浏览器中设计的可能性-这尤其有趣如果你-像我们一样-不使用图形编辑器并且不知道怎么使用它们。

Adobe的网页平台团队进行了庞大的工作来把它们的工具的图形能力移植到网页上。从滤镜,到混合模式,裁切和遮罩,甚至CSS Shapes,我们将获得更多网页端的控制布局和图形的能力。

使用CSS混合模式可以创造许多创造性的效果,结合其他技术,它们打开了一闪通往无尽创造可能性的大门。我希望你喜欢这篇文章并发现它有用。感谢阅读!

本文根据@SaraSoueidan的《Compositing And Blending In CSS》所译,整个译文带有我们自己的理解与思想,如果译得不好或有不对之处还请同行朋友指点。如需转载此译文,需注明英文出处:http://sarasoueidan.com/blog/compositing-and-blending-in-css/

Blueed

现居上海。正在学习前端的道路上,欢迎交流。个人博客:Blueed.me,微博:@Ivan_z3

如需转载,烦请注明出处:https://www.fedev.cn/css3/compositing-and-blending-in-css.htmlAir Jordan IX High