Blending Modes in CSS: Color Theory and Practical Application
Learn CSS: The Complete Guide
We've built a complete guide to help you learn CSS, whether you're just getting started with the basics or you want to explore more advanced CSS.
Blending Modes
You might be familiar with “blending modes” if you’re a Photoshop user; they allow you to combine layers in different ways and they’re great fun to play with. Blending modes in CSS, however, aren’t supported universally, but they are certainly on their way.
In this tutorial, we will learn how blending modes work and the different ways you can implement blending modes using CSS.
The Basics of Blending
If you’ve never encountered blending modes, the way they work may seem a bit elusive. Let’s break it down.
What does “blending mode” actually mean?
Blending modes have been available in design software for years, but the concept of blending modes has actually been in use for much longer, even before computers were invented.
The “blending” part of blending modes refers to taking two colors and combining them in some way to make one color. More accurately, we take two pixel maps and blend them together.
How that blending takes place is the “mode” part of blending modes. How do those colors interact? Because we are working with the digital space, we can take any mathematical formula and apply it to the two inputs to derive an output.









You do the Math
If you’re feeling really ambitious, take a look through the W3C FX Task Force’s official compositing document which explains the mathematical implementations of each of the different blending modes. It demonstrates a formula used to calculate the blending more.
Cm = B(Cb, Cs)
- Here,
Cmis the resultant color after blending. -
Brefers to the blending function. - The
Cbvariable is the background color. - And the
Csvariable is the source color.
All colors are based on a 0-1 scale, which maps directly to an rgb 0-255 value.
There are two categories of blending modes. The first are considered “non-separable”, and the second (unsurprisingly) are considered “separable”. Whether a blending mode is considered separable or not is determined by the underlying algorithm. If the algorithm treats each of the separate color channels (red, green, and blue) equally, it is considered non-separable. If it uses each of the color channels individually, it is considered separable.
All blend modes may only return colors that are within the range of 0 to 255. Anything beyond this range in either direction will be clipped to the range. When you see large areas of white or black on a blended area, it is likely because those areas are being clipped.
Types of Blending Modes Available in CSS
CSS blending modes, where supported, work in two different ways. The first type of blend mode is called background-blend-mode. This property allows you to blend all of the backgrounds within one element with each other.
If you have defined, for example, multiple background images (supported in all browsers beyond IE8), the first background image will be treated as the source layer, and any image added afterwards will be treated as the background layer, lying underneath.
Adding a background color (which must be last in the list) places another layer at the bottom. The color will be treated as the background layer, and the images as the source layers. Take the following style rule, for example:
1 |
div { |
2 |
background: |
3 |
url(img/pattern.png), |
4 |
url(img/jellyfish.jpg), |
5 |
#f07e32 ; |
6 |
}
|
That gives us:



And we can then add blend modes into the mix:
1 |
div { |
2 |
background: |
3 |
url(img/pattern.png), |
4 |
url(img/jellyfish.jpg), |
5 |
#f07e32 ; |
6 |
background-blend-mode: screen; |
7 |
}
|
Here are two divs using these styles, one without the blending mode, the second with:
A secondary blending mode type, mix-blend-mode, allows for independent elements to be blended together. The spec is more specific about the implementation, but the blending occurs in “stacking contexts”.
This is what happens when we use mix-blend-mode, attempting to get the background image and color within the same element to blend (very little):
1 |
.my-overlay-element { |
2 |
background-color: #f07e32; |
3 |
background-image: url(img/jellyfish.jpg); // Note: This image will not be blended with the background color. |
4 |
mix-blend-mode: color-dodge; |
5 |
}
|
Below, you can find an interactive demo for exploring the effects of a given blend mode.
Separable Blend Modes
Let’s take a look at the available blending modes, by examining the formula used, and applying each one to the red circle placed above our jellyfish.



Screen:
1 |
B(Cb, Cs) = 1 - [(1 - Cb) x (1 - Cs)] |
Screen is named after the concept of projecting multiple photo exposures at the same time on one screen. The resulting color is always at least as light as either of the blended layers.



Darken:
1 |
B(Cb, Cs) = min(Cb, Cs) |
Selects the darker of the two colors.



Lighten:
1 |
B(Cb, Cs) = max(Cb, Cs) |
Selects the lighter of the two colors.



Color dodge:
1 |
if(Cb == 0) |
2 |
B(Cb, Cs) = 0 |
3 |
else if(Cs == 1) |
4 |
B(Cb, Cs) = 1 |
5 |
else
|
6 |
B(Cb, Cs) = min(1, Cb / (1 - Cs)) |
Color dodge lightens the background color to reflect the source color.



Color burn:
1 |
if(Cb == 1) |
2 |
B(Cb, Cs) = 1 |
3 |
else if(Cs == 0) |
4 |
B(Cb, Cs) = 0 |
5 |
else
|
6 |
B(Cb, Cs) = 1 - min(1, (1 - Cb) / Cs) |
Color burn darkens the background color, increasing the contrast between the source and the background.



Hard light:
1 |
if(Cs <= 0.5) |
2 |
B(Cb, Cs) = Multiply(Cb, 2 x Cs) |
3 |
else
|
4 |
B(Cb, Cs) = Screen(Cb, 2 x Cs -1) |
Applies “multiply” on lighter colors and “screen” on darker colors. Essentially, “hard light” is the opposite of “overlay”, which we’ll look at next.



Overlay:
1 |
B(Cb, Cs) = HardLight(Cs, Cb) |
Applies “screen” on lighter colors and “multiply” on darker colors; written as the same as “hard light”, except with the arguments to the function reversed.



Soft light:
1 |
if(Cs <= 0.5) |
2 |
B(Cb, Cs) = Cb - (1 - 2 x Cs) x Cb x (1 - Cb) |
3 |
else
|
4 |
B(Cb, Cs) = Cb + (2 x Cs - 1) x (D(Cb) - Cb) |
5 |
with |
6 |
if(Cb <= 0.25) |
7 |
D(Cb) = ((16 * Cb - 12) x Cb + 4) x Cb |
8 |
else
|
9 |
D(Cb) = sqrt(Cb) |
This blend mode applies a variant of “multiply” on dark values and a variant of “screen” on lighter values (similar to screen).
In this algorithm, we see a secondary function D that is set in the with clause based on the blue value present in the color. The end result is typically a much softer effect than “overlay”.



Difference:
1 |
B(Cb, Cs) = | Cb - Cs | |
Difference takes the absolute difference value between the two colors, which has the effect of a photo negative.



Exclusion:
1 |
B(Cb, Cs) = Cb + Cs - 2 x Cb x Cs |
The exclusion mode has the same basic effect as the “difference” mode, except that similar colors result in a lower contrast middle value (rather than a darker value).



Non-separable Blending Modes
The “non-separable” blending modes utilize a few extra functions, including a ClipColor function, SetLum function, and Sat function.
Important note: No version of Safari supports “hue”, “saturation”, “color”, or “luminosity” blend modes with mix-blend-mode or background-blend-mode.
1 |
ClipColor(C) |
2 |
l = Lum(C) |
3 |
n = min(Cred, Cgreen, Cblue) |
4 |
x = max(Cred, Cgreen, Cblue) |
5 |
|
6 |
if n < 0.0
|
7 |
Cred = l + (((Cred - l) * l) / (l - n)) |
8 |
Cgreen = l + (((Cgreen - l) * l) / (l - n)) |
9 |
Cblue = l + (((Cblue - l) * l) / (l - n)) |
10 |
|
11 |
if x > 1.0 |
12 |
|
13 |
Cred = l + (((Cred - l) * (1 - l)) / (x - l)) |
14 |
Cgreen = l + (((Cgreen - l) * (1 - l)) / (x - l)) |
15 |
Cblue = l + (((Cblue - l) * (1 - l)) / (x - l)) |
16 |
|
17 |
return C
|
18 |
|
19 |
SetLum(C, l) |
20 |
d = l - Lum(C) |
21 |
Cred = Cred + d
|
22 |
Cgreen = Cgreen + d
|
23 |
Cblue = Cblue + d
|
24 |
|
25 |
return ClipColor(C) |
26 |
|
27 |
Sat(C) = max(Cred, Cgreen, Cblue) - min(Cred, Cgreen, Cblue) |
Note the min, mid, and max utility functions refer to the minimum, middle, and maximum values. (Mid is not the average of the three values.) The values Cred, Cgreen, and Cblue refer to red, green, and blue values present in color C.
With these definitions, we can now look at the non-separable blending modes.
Hue:
1 |
B(Cb, Cs) = SetLum(SetSat(Cs, Sat(Cb)), Lum(Cb)) |
This mode applies the hue of the source layer to the luminance and saturation of the background color.



Saturation:
1 |
B(Cb, Cs) = SetLum(SetSat(Cb, Sat(Cs)), Lum(Cb)) |
This mode does the same thing as the “hue” mode, but instead applies the saturation of the foreground to the hue and the luminance of the background.



Color:
1 |
B(Cb, Cs) = SetLum(Cs, Lum(Cb)) |
Applies the hue and saturation of the foreground to the luminance of the background.



Luminosity:
1 |
B(Cb, Cs) = SetLum(Cb, Lum(Cs)) |
This mode applies the luminosity of the source layer with the hue and saturation of the background layer.



Conclusion
Blend modes in CSS provide new and exciting flexibility for design and unique aesthetic experiences. Understanding the math and the color theory that applies to each of the available blending modes provides you with a more holistic toolset.
What will you do as browsers continue to add support for blend modes?
Related Links
- Check out what authors are doing with Photoshop actions and blend modes over on Envato Market
- Read more about <blend-mode> on Mozilla Developer Network
-
Compositing And Blending In CSS by Sara Soueidan



