CSS躬行记(7)——合成

简介:   在图形编辑软件中,可以按特定地方式处理不同图层的合成,最新的CSS规范也引入了该功能,并提供了mix-blend-mode和background-blend-mode两个属性。混合模式(blending mode)是一种数学算法,可计算元素重叠部分的颜色值,目前已定义了十多种不同的混合模式。

  在图形编辑软件中,可以按特定地方式处理不同图层的合成,最新的CSS规范也引入了该功能,并提供了mix-blend-mode和background-blend-mode两个属性。混合模式(blending mode)是一种数学算法,可计算元素重叠部分的颜色值,目前已定义了十多种不同的混合模式。


一、元素混合


  元素混合是指将元素和其背后内容(backdrop,也叫背着物)混合,由mix-blend-mode属性设置混合模式。元素背后既可以是另一个元素,也可以是父元素的背景,并且声明了mix-blend-mode属性的元素被称为前景。注意,不同层叠上下文中的元素不能混合。接下来会对已有的混合模式逐个讲解,并给出相应的计算公式,下面列出的是会用到的符号含义。

  (1)Cr:计算后的颜色值。

  (2)B:进行混合的公式。

  (3)Cs:前景中的颜色。

  (4)Cb:元素背后的颜色(backdrop color)。

1)darken

  比较Cb和Cs的颜色分量(即R、G和B),选择较暗的颜色,即保留较小值。

B(Cb, Cs) = min(Cb, Cs)

  下面将img元素的mix-blend-mode属性定义为darken,父元素div声明了渐变背景。在下图中,左侧是img和div默认的混合效果,右侧是使用了darken混合后的效果。


<style>
  div {
    background: linear-gradient(to right, rgb(48,129,242) 10%, rgb(255,204,0) 66%, rgb(255,102,0));
  }
  img {
    mix-blend-mode: darken;
  }
</style>
<div>
  <img src="./avatar.png" />
</div>


91.png


2)lighten

  与darken类似,但选择较亮的颜色,即保留较大值,效果如下图所示。

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


92.png


3)difference

  取Cb和Cs颜色分量之差的绝对值,用较浅的颜色减去较深的颜色,效果如下图所示。


B(Cb, Cs) = | Cb - Cs |


93.png

4)exclusion

  与difference类似,但对比度更低,颜色更柔和,效果如下图所示。

B(Cb, Cs) = Cb + Cs - 2 x Cb x Cs


94.png


5)multiply

  将Cb和Cs中的颜色分量相乘,得到较暗的颜色,效果如下图所示。

B(Cb, Cs) = Cb x Cs


95.png


6)screen

  将Cb和Cs的颜色反转,然后相乘,最后再反转,效果如下图所示。

B(Cb, Cs) = 1 - [(1 - Cb) x (1 - Cs)]


96.png


7)overlay

  当Cb的颜色比Cs的颜色深时,执行multiply渲染;当Cb的颜色比Cs的颜色浅时,执行screen渲染,效果如下图所示。

B(Cb, Cs) = HardLight(Cs, Cb)97.png8)hard-light

  也是对multiply和screen的综合应用,但判断条件与overlay相反,效果如下图所示。

if(Cs <= 0.5)
    B(Cb, Cs) = Multiply(Cb, 2 x Cs)
else
    B(Cb, Cs) = Screen(Cb, 2 x Cs -1)

98.png


9)soft-light

  与hard-light类似,但颜色更加柔和,效果如下图所示。


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)


99.png


10)color-dodge

  不改变颜色,但会将其调亮,效果如下图所示。

if(Cb == 0)
    B(Cb, Cs) = 0
else if(Cs == 1)
    B(Cb, Cs) = 1
else
    B(Cb, Cs) = min(1, Cb / (1 - Cs))


100.png


11)color-burn

  与color-dodge的作用相反,将颜色调暗,效果如下图所示。

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)


  接下来的四个混合模式不操作颜色分量,而是以不同的方式合并Cs和Cb的色相、饱和度、亮度和颜色,会用到几个辅助函数,如下所示。


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)
    SetSat(C, s)
        if(Cmax > Cmin)
            Cmid = (((Cmid - Cmin) x s) / (Cmax - Cmin))
            Cmax = s
        else
            Cmid = Cmax = 0
        Cmin = 0
        return C;


12)hue

  将Cb的颜色的饱和度与亮度跟Cs中对应位置的色相合并,效果如下图所示。

B(Cb, Cs) = SetLum(SetSat(Cs, Sat(Cb)), Lum(Cb))


101.png


13)saturation

  将Cb的颜色的色相与亮度跟Cs中对应位置的饱和度合并,效果如下图所示。

B(Cb, Cs) = SetLum(SetSat(Cb, Sat(Cs)), Lum(Cb))


102.png


14)color

  将Cb的颜色的亮度跟Cs中对应位置的色相与饱和度合并,效果如下图所示。

B(Cb, Cs) = SetLum(Cs, Lum(Cb))


103.png

15)luminosity

  将Cb的颜色的色相与饱和度跟Cs中对应位置的亮度合并,效果如下图所示。

B(Cb, Cs) = SetLum(Cb, Lum(Cs))


104.png


二、背景混合


  背景混合适合一个元素包含多个背景的情况,由background-blend-mode属性设置混合模式。当混合多个背景时,会从后往前进行混合。如果包含背景色,那么首先由背景色与最下层的背景图混合,其结果再与次下层的背景图混合,以此类推。

  在下面的示例中,包含两个div元素,都使用lighten混合,其中第二个div元素包含背景色。两个元素的混合效果如下图所示,左侧无背景色,右侧有背景色。


<style>
  div {
    background: url(./avatar.png) no-repeat center,
            url(./lake.png);
    background-size: 40% 40%, cover;
    background-blend-mode: lighten;
  }
  .color {
    background-color: #F60;
  }
</style>
<div></div>
<div class="color"></div>


image.png


 注意,background-blend-mode属性可接收多种混合模式,用逗号分隔,样式如下,效果如下图所示。

div {
  background-blend-mode: lighten, hard-light;
}


106.png


三、隔离


  在合成的过程中,还可通过isolation属性隔离混合,即让那些元素自成一组。注意,isolation属性需要声明到某个容器元素中,并且不能和混合模式存在于同一个元素上。

  接下来用一个简单的例子来演示isolation属性的用法,首先创建HTML结构,section是img的祖先元素,div是img的父元素。


<section>
  <div>
    <img src="./avatar.png" class="blend" />
  </div>
</section>
<section>
  <div class="isolation">
    <img src="./avatar.png" class="blend" />
  </div>
</section>


  然后添加CSS样式,将混合模式声明在img元素上,第二个div元素定义了isolation属性。得到的效果如下图所示,左侧的祖先元素的背景会与图像混合,而右侧因为发生了隔离,所以就不会与背景混合。


section {
  background: linear-gradient(to right, #3081F2 10%, #FC0 66%, #F60);
}
.blend {
  mix-blend-mode: lighten;
}
.isolation {
  isolation: isolate;
}


107.png


  注意,建立层叠上下文的元素可自动独立,而不受isolation属性的影响,能发生层叠上下文的情形包括:

  (1)文档根元素,例如html元素。

  (2)相对或绝对定位且z-index属性值不为auto的元素。

  (3)固定或粘滞定位的元素。

  (4)弹性盒的子元素,且z-index属性值不为auto。

  (5)网格容器的子元素,且z-index属性值不为auto。

  (6)opacity属性值小于1的元素。

  (7)mix-blend-mode属性值不为normal的元素。

  (8)transform、filter、perspective、clip-path、mask、mask-image和mask-border属性值不为none的元素。

  (9)isolation属性值为isolate的元素。

  (10)-webkit-overflow-scrolling属性值为touch的元素。

  (11)contain属性值为layout、paint或包含它们其中之一的合成值(例如strict、content)的元素。

  (12)为will-change定义任一属性。

相关文章
CSS3 自定义字体的常识与使用
CSS3 自定义字体的常识与使用
86 0
|
7月前
|
前端开发 Python
分享83个CSS3特效,总有一款适合您
分享83个CSS3特效,总有一款适合您
67 4
|
7月前
|
前端开发 Python
分享85个CSS3特效,总有一款适合您
分享85个CSS3特效,总有一款适合您
85 2
|
7月前
|
移动开发 JavaScript 前端开发
分享87个CSS3特效,总有一款适合您
分享87个CSS3特效,总有一款适合您
84 1
|
前端开发
CSS特效集锦(9款 , 总有一款是你喜欢的)
主要是: 穿越时空特效, 图片放大镜, 3D相册, 立方体相册, 昼夜更替特效, 飘雪, 七彩雨, 签名生成器, 水波纹动画等
CSS特效集锦(9款 , 总有一款是你喜欢的)
|
前端开发 JavaScript 容器
【CSS畅想】萤星漫舞,我用CSS绘制了一个属于夏日的回忆
用技术实现梦想,用梦想打开创意之门。萤星漫舞,我用CSS绘制了一个属于夏日的回忆
238 1
|
前端开发 JavaScript 程序员
H5+css+JavaScript满屏彩色泡泡小特效(适合表白哦~做完发给让你每天想念的人吧~)
H5+css+JavaScript满屏彩色泡泡小特效(适合表白哦~做完发给让你每天想念的人吧~)
197 0
|
前端开发
奇思妙想 CSS 文字动画 (下)
奇思妙想 CSS 文字动画 (下)
419 0
奇思妙想 CSS 文字动画 (下)
|
前端开发
奇思妙想 CSS 文字动画 (上)
奇思妙想 CSS 文字动画
305 0
奇思妙想 CSS 文字动画 (上)
|
设计模式 前端开发 JavaScript
现代CSS进化史
现代CSS进化史
223 0

热门文章

最新文章