Visual Effects in CSS: BLend Modes

Blend modes make it possible to combine background colors and images using effects commonly found in graphics software such as Photoshop. Defined modes include multiply , screen , overlay , and coLor-dodge .

“Blend modes” is the colloquial name for the background-blend-mode and mix-blend-mode properties. These properties are outlined in the Compositing and Blending specification. Although the CSS Working Group manages most CSS specifications, the World Wide Web Consortium’s CSS-SVG Effects Task Force manages this one. Blend modes apply to HTML and SVG elements. Here we’ll focus on using them with HTML.

Blend modes describe how to visually combine layers. Both mix-blend-mode and background- blend-mode accept the same values, but work slightly differently:

  • mix-blend-mode blends foreground layers with layers that they overlap.
  • background-blend-mode mixes background images and colors. It accepts a single mode or a list of modes, and this list gets applied in the same order as background-image .

Let’s look at some examples.

mix-blend-mode

As mentioned above, mix-bLend-mode merges foreground layers with layers that are stacked below it. A layer may be a background color or image for a parent element, for the root element, or elements that sit beneath the targeted element in the stack. Consider the following HTML and CSS:

<!DOCTYPE html>

<html lang=”en”>

<head>

<meta charset=”UTF-8″>

<title>mix-blend-mode</title>

<link rel=”stylesheet” href=”mix-blend-mode.css”>

</head>

<body>

<div>

<p>This is a paragraph that’s positioned below the image in the stack. </p>

<img src=”dahlia.]pg”>

</div>

</body>

</html>

Our mix-bLend-mode.css file looks like this:

div {

background-image: linear-gradient(to left, #f30, #fc0);

width: 60vw;

margin: 3rem auto;

position: relative;

}

p {

position: absolute;

color: black;

margin: 4rem;

font-size: 6.4rem;

}

img {

display: block;

height: auto;

width: 100%;

}

The image below shows the output of the code we have so far.

Since the <p> element is absolutely positioned, the text overlays the photo. Notice too that the photo fills the entire width and height of its parent container so we can’t see its background gradient. Now let’s add mix-bLend-mode to the img rule set. We’ll use the difference mode:

img {

display: block;

height: auto;

width: 100%;

mix-blend-mode: difference;

}

Now the photograph has moved to the top of the layer stack (as pictured below), but its pixels have been blended with the paragraph’s text and the background image of its parent <div> .

Adding mix-bLend-mode: difference causes the photograph, text, and background of its parent to blend in a specific way. Using a value other than normal for mix-bLend-mode creates a new stacking context for the element. The new stack or group then gets blended and composited with the stacking context that contains the element.

Although this looks like chaos on screen, it’s predictable once you understand how each blend mode works. Blend modes use an RGB color system, where the red, green, and blue component of each color is expressed as a value between 0 and 1. We can convert from colors expressed using the CSS rgb / rgba functions by dividing each channel’s value by 255. For example, rgb(255, 0, 255) becomes rgb(1, 0, 1) , and rgb(52, 62, 28) becomes RGB(0.203, 0.243, 0.109) .

With the exception of normal , each blend mode uses a mathematical formula to determine what color to paint each pixel within the overlapping region ( normal indicates that no blending should occur). The specification outlines how to calculate the output for each blend mode. For difference , that formula is:

pixel color = bottom layer color – top layer color

In other words, pixel color is the absolute value of the difference between the red, blue, and green channels of the bottom and top layers.

Let’s return to the photo of dahlias in the example above. The color of the pixel at (0,0) of the photograph is rgb(185, 40, 58) . If we express each channel as a value between 0 and 1, this becomes RGB(0.725, 0.157, 0.227) .

The color of the pixel at (0,0) in the background gradient of div is rgb(255, 204, 0) , or RGB(1, 0.8, 0) . Let’s calculate the difference between each channel:

RED: 1.0 – 0.725 = 0.275
GREEN: 0.8 – 0.157 = 0.643
BLUE: 0.0 – 0.227 = -0.227

The color at (0,0) of our blended layers is RGB(0.275, 0.643, 0.227) or rgb(70, 164, 58) . When used with difference , black doesn’t produce a change in pixel color; its red, blue, and green channels are all zero ( rgb(0,0,0) ). White, on the other hand, inverts the color of a pixel.

Safari versions 14.0.2 and under behave a little differently from other browsers. When the value of background-image or background-color isn’t explicitly set, those versions of Safari use white or rgb(255,255,255) as the initial value. Firefox, Chrome, and Edge, on the other hand, use rgba(0,0,0,0) . This can lead to unexpected results for some blend modes. Let’s look at an example using exclusion .

The exclusion blend mode is similar to the difference blend mode, with a slightly lower level of contrast. Here’s the formula for calculating an exclusion blend mode:

pixel color = bottom layer + top layer – 2 x bottom layer x top layer

Say we have a pixel with color rgb(128, 177, 230) . If we express each channel as a proportion of 255, this becomes RGB(0.502, 0.694, 0.902) . First, we’ll blend it with black, or RGB(0, 0, 0) :

RED: 0 + 0.502 – 2 x 0 x 0.502 = 0.502

GREEN: 0 + 0.694 – 2 x 0 x 0.694 = 0.694

BLUE: 0 + 0.902 – 2 x 0 x 0.902 = 0.902

Our pixel color remains unchanged at RGB(0.502, 0.694, 0.902) or rgb(128, 177, 230) . But if we blend it with white, or RGB(1, 1, 1) , something else happens:

RED: 1 + 0.502 – 2 x 1 x 0.502 = 0.498

GREEN: 1 + 0.694 – 2 x 1 x 0.694 = 0.306

BLUE: 1 + 0.902 – 2 x 1 x 0.902 = 0.098

Our blended pixel color is RGB(0.498, 0.306, 0.098) or rgb(127, 78, 25) .

In the image below, the picture on the left reflects what happens when you use mix-blend­mode: exclusion and the initial value of background-color in Firefox, Chrome, and Edge. The picture on the right reflects Safari’s behavior. Adding background-color: white to the element’s parent ensures consistent behavior across browsers.

Photo by Aaron Burden from Unsplash

background-blend-mode

As mentioned at the beginning of this section, the background-bLend-mode property combines background colors and images. It accepts a mode or a list of modes. Arguments follow the ordering of background-image , meaning that background-bLend-mode can accept a single blend mode or a list of blend modes.

The first image listed in a background-image list is the topmost layer, drawn closest to the user. Other images in the list stack towards the bottom in the order in which they’re listed. In the following example, our background-image list contains two values. However, because the top gradient uses opaque colors, it’s the only background image that’s visible:

body{

linear-gradient( 90deg, rgb(255,0,0), rgb(0,0,255)), linear-gradient(270deg, rgb(127,255,0), rgb(255,255,0));

}

The following image illustrates that just the topmost layer is visible, which is the first image listed.

Each item in a background-bLend-mode list gets applied in the same order. If there’s only one item in the list, it’s repeated for every item in the background-image list. Let’s add a blend mode to the CSS above:

body {

background-image: linear-gradient( 90deg, rgb(255,0,0), rgb(0,0,255)),

linear-gradient(270deg, rgb(127,255,0), rgb(255,255,0));

background-blend-mode: multiply;

}

Since background-bLend-mode has one item in its list, the browser will use multiply for both background images.

The multiply blend mode sets the color of a pixel to the product of the top and bottom layers. In this case, the pixel at (0,0) is the product of red ( RGB(1,0,0) ) and yellow ( RGB(1,1,0 ), which works out to RGB(1,0,0) , as illustrated below. Multiplying our gradient layers creates a gradient that transitions from red to black.

Let’s look at another example using multiple backgrounds and multiple blend modes:

div {

height: 733px; width: 1152px;

background-size: 100% auto;

background-repeat: no-repeat;

background-position: 0 0, -70px -140px, center right;

/* List of multiple backgrounds */

background-image: linear-gradient(to bottom, #f90d, #f30d, #f0fd 105%), url(‘strawberry-trio.jpg’), url(‘strawberry-and-milk.jpg’);

background-blend-mode: saturation, darken, screen;

}

In this example, we’ve combined a gradient and two photographs of strawberries. The following image shows the separate layers.

Strawberry image (center) by al Gatewood from Unsplash. Strawberry on spoon image by wallner from Pixabay.

Each layer has a different blend mode. The saturation mode applies to the gradient layer, while saturation and darken apply to the strawberry-trio.jpg and strawberry-and- mitk.jpg layers respectively. You can see the result below.

You may have noticed here that we haven’t defined a background color. Let’s change that:

div {

height: 733px; width: 1152px;

background-size: 100% auto;

background-repeat: no-repeat;

background-position: 0 0, -70px -140px, center right;

background-image: linear-gradient(to bottom, #f90d, #f30d, #f0fd 105%), url(‘strawberry-trio.jpg’), url(‘strawberry-and-milk.jpg’);

background-blend-mode: saturation, darken, screen;

background-color: green; /* Now we have a background color */

}

Now our element has a greenish tint, as you can see below. If the element has a background color, that layer becomes part of the blend.

Blend modes are limited to a local stacking context. Adding a background color to an ancestor of div would not affect the blending result of div .

1. Blend Mode Values

There are sixteen values that you can use with the mix-blend-mode and background-blend­mode properties. The following image is a partly transparent PNG image of a lemon set against a background gradient of its container that transitions from magenta to purple to blue, with no blend mode applied.

Sliced lemon photo by Louis Hansel from Unsplash.10

The following table illustrates the result of each mix-blend-mode value when added to the img element.

Refer to the pecification for the formulas used to calculate the pixel color for each blend mode.

Source: Brown Tiffany B (2021), CSS , SitePoint; 3rd edition.

Leave a Reply

Your email address will not be published. Required fields are marked *