Old browser

This article shows off HTML5 features, don't you think it would be a good idea to read it with a browser that supports these features so you can see them?

CSS Blend Modes Explained

CSS Blend modes can be used on modern browsers to achieve a variety of pretty cool effects.
In this article we'll see how to use the mix-blend-mode and background-blend-mode properties, and see some examples of these blend modes in action.

You are free to copy, modify and use this code as you wish.

Introduction

There are 2 CSS properties that have to do with blending:

  • mix-blend-mode specifies how the contents of an elements will blend with the elements behind them and the background.
    Note that the blending is only between sibling elements. Elements that belong to different branches of the DOM tree will blend normally, even if they overlap visually.
  • background-blend-mode specifies how multiple backgrounds in this element will blend with each other (such as a background-color and a background-image)

Both properties are not inheritable.

An interesting thing is that the alpha channel does not blend like the other components, instead it can be used to weaken/strengthen the effect, and as transparency, depending which blending mode you use.
The effect, of course, is applied after other image filters (like an SVG blur or a sepia effect).

mix-blend-mode

mix-blend-mode specifies how the contents of an elements will blend with the elements behind them and the background.
Let's take a look at all the currently available blending modes.
We'll be using 3 overlapping elements with different colors:

<div style="position:relative; width:18em; height:18em; margin-left:auto; margin-right:auto;" id="testElement">
  <div style="position:absolute; width:60%; height:60%; top:0; left:0; background-color:#ff8533;"></div>
  <div style="position:absolute; width:60%; height:60%; top:0; right:0; background-color:#705dff;"></div>
  <div style="position:absolute; width:60%; height:60%; bottom:0; left:20%; background-color:#50d472;"></div>
</div>
Notice that I didn't use pure red, green and blue because it makes some effects do nothing. The colors I chose have different hue, different saturation and different luminosity.
The mix-blend-mode property has to be applied to the children of testElement.
mix-blend-mode: normal

Elements blend normally, also known as alpha blending. This is the default blending.

mix-blend-mode: screen

The RGB components are added together. Also known as additive rendering. Useful for creating nebulae and similar effects.

mix-blend-mode: multiply

The RGB components are multiplied. Useful for colorizing black and white images.

mix-blend-mode: difference

A subtraction is performed between the elements' RGB components. The result, of course, is different depending on the z-index.

mix-blend-mode: hue

When element B is drawn in front of element A, the resulting color has B's hue and A's saturation and lightness.

mix-blend-mode: saturation

When element B is drawn in front of element A, the resulting color has B's saturation and A's hue and lightness.

mix-blend-mode: luminosity

When element B is drawn in front of element A, the resulting color has B's lightness and A's saturation and hue.

mix-blend-mode: color

When element B is drawn in front of element A, the resulting color has B's hue and saturation and A's lightness. Useful for colorizing any image.

mix-blend-mode: exclusion

A XOR is performed between the RGB components.

mix-blend-mode: lighten

When element B is drawn in front of element A, the resulting color has the highest value for each RGB component.

mix-blend-mode: darken

When element B is drawn in front of element A, the resulting color has the lowest value for each RGB component.

mix-blend-mode: overlay

A mix between screen and multiply. Can be seen as a linear interpolation between black, B's value, and white, using A's lightness as interpolation factor.

mix-blend-mode: color-burn

The darker is A, the more its color is used. Blending with white produces no difference.
This darkens the image.

mix-blend-mode: color-dodge

The brighter is B, the more its color affects A. Blending with white gives white. Blending with black produces no difference.
This lightens the image.

mix-blend-mode: hard-light

Same as overlay, but with A and B swapped.

mix-blend-mode: soft-light

This is a variation of hard-light. The implementation of this is not well defined so it might look different in different rendering engines.
More about this blend mode can be found on Wikipedia.

background-blend-mode

background-blend-mode specifies how multiple backgrounds in this element will blend with each other (such as a background-color and a background-image).
Let's take a look at all the currently available blending modes.
We'll be using an element with these 2 background images:

<div id="testElement2" style="width:100%;height:30em;background-image:url('bkimg1.jpg'),url('bkimg2.jpg');background-size:cover;background-position:center;"></div>
We will apply the background-blend-mode property to testElement2.
One important thing to know is that when you're using multiple background images, they don't stack like you would expect: the first image is drawn on top of the second, not the other way around! Also, when using both background-image and background-color, background-image is drawn on top.
Its content will blend normally, so you can use mix-blend-mode on the element's children for more blending fun.
background-blend-mode: normal

Backgrounds blend normally, also known as alpha blending. This is the default blending.

background-blend-mode: screen

The RGB components are added together. Also known as additive rendering. Useful for creating nebulae and similar effects.

background-blend-mode: multiply

The RGB components are multiplied. Useful for colorizing black and white images.

background-blend-mode: difference

A subtraction is performed between the elements' RGB components. The result, of course, is different depending on the order in which the images are drawn.

background-blend-mode: hue

When element B is drawn in front of element A, the resulting color has B's hue and A's saturation and lightness.

background-blend-mode: saturation

When element B is drawn in front of element A, the resulting color has B's saturation and A's hue and lightness.

background-blend-mode: luminosity

When element B is drawn in front of element A, the resulting color has B's lightness and A's saturation and hue.

background-blend-mode: color

When element B is drawn in front of element A, the resulting color has B's hue and saturation and A's lightness. Useful for colorizing any image.

background-blend-mode: exclusion

A XOR is performed between the RGB components.

background-blend-mode: lighten

When element B is drawn in front of element A, the resulting color has the highest value for each RGB component.

background-blend-mode: darken

When element B is drawn in front of element A, the resulting color has the lowest value for each RGB component.

background-blend-mode: overlay

A mix between screen and multiply. Can be seen as a linear interpolation between black, B's value, and white, using A's lightness as interpolation factor.

background-blend-mode: color-burn

The darker is A, the more its color is used. Blending with white produces no difference.
This darkens the image.

background-blend-mode: color-dodge

The brighter is B, the more its color affects A. Blending with white gives white. Blending with black produces no difference.
This lightens the image.

background-blend-mode: hard-light

Same as overlay, but with A and B swapped.

background-blend-mode: soft-light

This is a variation of hard-light. The implementation of this is not well defined so it might look different in different rendering engines.
More about this blend mode can be found on Wikipedia.

Example 1: Colorizing a black and white image

Bad Kingdom
HTML
<div style="min-height:30em;background-image:url('html5cool/blend/barn.jpg');background-size:cover;background-position:center;overflow:hidden;">
  <span style="mix-blend-mode:multiply; font-family:'Titillium'; font-size:8em; color:#A00000; margin-left:0.2em;">
    Bad Kingdom
  </span>
</div>

Example 2: Overlapping colored letters

L e z z o
HTML
<div class="container">
  <span class="letter" style="color:#C0C000">L</span>
  <span class="letter" style="color:#C000C0">e</span>
  <span class="letter" style="color:#4040C0">z</span>
  <span class="letter" style="color:#40C040">z</span>
  <span class="letter" style="color:#C04040">o</span>
</div>
CSS
div.container{
  background-color:#FFFFFF;
  min-height:2em;
  text-align:center;
  letter-spacing:-0.24em;
  font-family:'Segoe UI','Roboto';
  font-weight:600;
  font-size:5em;
}
span.letter{
  mix-blend-mode:multiply;
}

Example 3: Simple procedural Nebula

We can combine the 2 properties we've seen and add some animations to procedurally generate a nebula with a few lines of code.

CSS
div.nebula{
  position:relative;
  background-image:url('stars.png');
  overflow:hidden;
}
@keyframes slowrot{
  0%{transform:rotate(0deg);}
  100%{transform:rotate(360deg);}
}
div.particle{
  position:absolute;
  background-blend-mode:multiply;
  mix-blend-mode:screen;
  animation:slowrot infinite linear;
  background-size:100% 100%;
}
JS
function generateNebula(container,n){
  var cw=container.clientWidth, ch=container.clientHeight, particleSize=(cw>ch?cw:ch)/2;
  container.innerHTML="";
  for(var i=0;i<n;i++){
    var d=document.createElement("div");
    d.className="particle";
    d.style.animationDuration=(180*(0.8+Math.random()*0.5))+"s";
    if(Math.random()<0.5)d.style.animationDirection="reverse";
    d.style.backgroundImage="url('neb"+(~~(4*Math.random()))+".png')";
    var size=particleSize*(0.8+Math.random()*0.4);
    d.style.width=d.style.height=size+"px";
    d.style.left=(Math.random()*cw-size/2)+"px";
    d.style.top=(Math.random()*ch-size/2)+"px";
    d.style.backgroundColor=Math.random()<0.5?("rgba("+~~((0.15+Math.random()*0.3)*256)+","+~~((0.65+Math.random()*0.15)*256)+","+~~((0.9+Math.random()*0.1)*256)+",1)"):("rgba("+~~((0.9+Math.random()*0.1)*256)+","+~~((0.15+Math.random()*0.3)*256)+","+~~((0.15+Math.random()*0.3)*256)+",0.8)");
    container.appendChild(d);
  }
}
HTML
<div id="nebula" class="nebula" style="height:35em;"></div>
<script type="text/javascript">
  function initNebula(){generateNebula(document.getElementById("nebula"),25);}
  window.addEventListener("resize",initNebula);
  initNebula();
</script>
Download Example
You can download the nebula example here.

Browser support

As of June 2016, CSS blend modes are not a standard yet. They are fully supported by Firefox (and other gecko-based browsers), fully supported by Chrome (and other webkit-based browsers), slightly broken in Safari, and unsupported by Microsoft Edge/IE.
See updated list of supported browsers.
Some of these effects can be done with SVG as well, so if it's relevant to your site, you might want to use it as a fallback.
To detect browser support, you can use this code:

if('backgroundBlendMode' in document.body.style && 'mixBlendMode' in document.body.style){
  //supported
}else{
  //unsupported
}
If you're a lazy shit, modernizr has a test for it, except it's 27kb minified instead of a one-liner (as of June 2016).

Share this article

Comments