If a picture is worth a thousand words, then blending two pictures together must be worth many times that. Likewise, the design possibilities that open up with the availability of blend modes in CSS are likely greater than you realize.
When you hear CSS Blend Modes being talked about, the commotion is really about three new CSS properties that have gained fairly good support in modern browsers.
These properties include:
background-blend-mode
, for blending an element’s background images, gradients, and background colorsmix-blend-mode
, for blending elements over other elements, and lastlyisolation
, a lesser used property used with mix-blend-mode for keeping elements from mixing together.However, this article will focus on background-blend-mode
, the property with the most widespread support, and how you can use it today to create eye-catching backgrounds and photo effects for your website that once were only possible in Photoshop.
Advanced effects with CSS background blend modes
CSS blend modes are taking the power of Photoshop and putting it into CSS. Learn more here. Source code: https://codepen.io/collection/njazaM Introduction — 00:00 3D plaid background — 01:53 Circle pattern — 03:21 Night vision — 04:46 Blacklight freak out — 05:48 Mix-blend-mode example — 07:27 Try LogRocket for free: https://logrocket.com/?yt20 LogRocket is a frontend application monitoring solution that lets you replay problems as if they happened in your own browser.
The background
property is where we can use CSS gradients. Functions like linear-gradient()
, radial-gradient()
, and the repeating-linear-gradient()
and repeating-radial-gradient()
varieties of the two have widespread support and more critically, a standardized syntax across browsers.
But the background
property can also accept more than one gradient rendered on top of each other, with each function separated by a comma. Lea Verou showcased impressive patterns that can be created with this technique, from checkerboards, to bricks, to stars.
But now that we have the background-blend-mode
property, we can create even more new gradients and patterns.
Let’s overlay three gradients to make a background with nearly the full spectrum of colors that can be displayed on a monitor.
.spectrum-background { background: linear-gradient(red, transparent), linear-gradient(to top left, lime, transparent), linear-gradient(to top right, blue, transparent); background-blend-mode: screen; }
The effect above used to only be possible with an image, weighing in at many tens of kilobytes. But we’ve just reproduced the effect with CSS in less than 200 bytes, not to mention saving an HTTP request as well.
We can also create some interesting plaid patterns with gradients and background-blend-mode
.
.plaid-background { background: repeating-linear-gradient( -45deg, transparent 0, transparent 25%, dodgerblue 0, dodgerblue 50% ), repeating-linear-gradient( 45deg, transparent 0, transparent 25%, tomato 0, tomato 50% ), repeating-linear-gradient( transparent 0, transparent 25%, gold 0, gold 50% ), white; background-blend-mode: multiply; background-size: 100px 100px; }
How about one more, this time with a radial gradient:
.circles-background { background: radial-gradient( khaki 40px, transparent 0, transparent 100% ), radial-gradient( skyblue 40px, transparent 0, transparent 100% ), radial-gradient( pink 40px, transparent 0, transparent 100% ), snow; background-blend-mode: multiply; background-size: 100px 100px; background-position: 0 0, 33px 33px, -33px -33px; }
With the help of Yoksel and Una Kravets, I’ve prepared a collection of 24 more blend mode gradients to make your website fast and attractive looking.
While background-image
allows us to set multiple gradients on an element, one trick is that we can also set multiple image backgrounds with the url()
syntax in much the same way. When we combine that with background-blend-mode
and properties like filter
, that’s where things can get really interesting.
We can use CSS to make a photograph on the left look like it was sketched with pencil and paper. No Photoshop, no HTML5 canvas, no WebGL, no Javascript libraries. Five CSS properties is all we need.
Although we can use other block-level elements like <body>
, <section>
, <figure>
, here’s the HTML we’ll use to get started.
<div class=”pencil-effect”></div>
Let’s start styling. Replace chapel.jpg
with the url of the image you are using. We will set the background image twice and its background-size to cover .
.pencil-effect { background: url(chapel.jpg), url(chapel.jpg); background-size: cover; }
Below in the first square is the result of our first step:
Now let’s add in a blend mode:
background-blend-mode: difference;
Oh no, where did everything go? We are left with a completely black square. The difference blend mode takes the two backgrounds and subtracts pixel by pixel the darker color of one background from the lighter color of the other background.
If it’s confusing what is going on here, let’s see what happens when we offset the two backgrounds ever so slightly with background-position
and calc()
.
background-position: calc(50% — 1px) calc(50% — 1px), calc(50% + 1px) calc(50% + 1px);
Using a comma, we set two background positions, each corresponding to one copy of the background image. The first image, we move from the center on the x-axis to the left by one pixel, and from the center on the y-axis, upwards by a pixel. For the second copy of the background image, we do the opposite, moving down and to the right.
What we are left with is two background images that are slightly offset but the whole picture is still centered in our element. Now that the difference blend mode finds the differences between the two images, it reveals the edges in the photo. Pretty cool?
Lastly, we will use the filter
property to invert the photo and make it grayscale.
filter: brightness(3) invert(1) grayscale(1);
For this specific photo, we will also boost the brightness, which has the secondary effect of increasing the contrast of the lines.
Here’s our final snippet of CSS for this effect:
.pencil-effect { background: url(photo.jpg), url(photo.jpg); background-size: cover; background-blend-mode: difference; background-position: calc(50% — 1px) calc(50% — 1px), calc(50% + 1px) calc(50% + 1px); filter: brightness(3) invert(1) grayscale(1); }
We can recreate a chalkboard effect by following the steps for the pencil sketch effect, while omitting the invert(1)
function on the final step.
Let’s try to recreate one more effect with CSS blend modes and make a photo appear like we are viewing it through the lens of night vision goggles.
There are three parts to our background that we will blend together with the overlay
blend mode. This blend mode both lightens and darkens a background and works as a combination of two other blend modes, multiply
and screen
.
First we will setup our background image, just once this time.
background: url(moose.jpg); background-size: cover; background-position: center;
Now let’s add in a gradient and background-blend-mode. The we are using a slightly transparent lime to black radial gradient here.
background: url(moose.jpg), radial-gradient( rgba(0,255,0,.8), black ); background-blend-mode: overlay;
Not too bad, maybe we want to stop there. I have one more idea that might make the effect look more authentic, and that is to add some faux scan lines to the background with a repeating background gradient.
background: url(moose.jpg), radial-gradient( rgba(0,255,0,.8), black ), repeating-linear-gradient( transparent 0, rgba(0,0,0,.2) 3px, transparent 6px );
And to wrap it up, the full CSS used for this effect:
.night-vision-effect { background: url(moose.jpg), radial-gradient( rgba(0,255,0,.8), black ), repeating-linear-gradient( transparent 0, rgba(0,0,0,.2) 3px, transparent 6px ); background-blend-mode: overlay; background-size: cover; }
I’ve made a gallery of 20 CSS image effects you can use on your website.
The good news is that the background-blend-mode
property has full support in Firefox, Chrome, and Opera.
The somewhat good news is that it has enough support in Safari to support all the effects we’ve overviewed here, while Safari currently lacks support for the saturation
, hue
, color
, and luminosity
blend modes.
The bad news is that Internet Explorer and IE Edge have no support for any CSS blend mode properties.
This means we need to plan ahead for browsers that do not yet support background-blend-mode
. The nifty CSS @supports
rule makes that pretty easy. Here’s two examples.
For the first example, we will take our spectrum background gradient and provide a fallback if the background-blend-mode
property isn’t supported. We are using background: gray;
for this example as a fallback, but any CSS can be used in its place.
.spectrum-background { background: gray; @supports (background-blend-mode: screen) { background: linear-gradient(red, transparent), linear-gradient(to top left, lime, transparent), linear-gradient(to top right, blue, transparent); background-blend-mode: screen; } }
And here’s the pencil sketch effect with a fallback. We are testing for two crucial properties we need support for for the effect: filter
and background-blend-mode
. If a user’s browser doesn’t support those (or if the browser doesn’t support CSS @supports
for that matter), we will fallback to the plain original photograph.
.pencil-effect { background-image: url(photo.jpg); background-size: cover; @supports (background-blend-mode: difference) and (filter: invert(1)) { background-image: url(photo.jpg), url(photo.jpg); background-blend-mode: difference; background-position: calc(50% — 1px) calc(50% — 1px), calc(50% + 1px) calc(50% + 1px); filter: brightness(3) invert(1) grayscale(1); } }
Blending Modes Demystified by Justin McDowell
Basics of CSS Blend Modes by Chris Coyier
CSS3 Patterns Gallery by Lea Verou
Una Kravets’ 6-part CSS Image Effects Series
Can I use… Support for background-blend-mode
Image Effects with CSS by Bennett Feely
New CSS Gradient possibilities with the background-blend-mode property by Bennett Feely
Experimental Polyfill for background-blend-mode by Rik Cabanier
Compositing and Blending Level 1 Specification by the W3C
As web frontends get increasingly complex, resource-greedy features demand more and more from the browser. If you’re interested in monitoring and tracking client-side CPU usage, memory usage, and more for all of your users in production, try LogRocket.
LogRocket is like a DVR for web and mobile apps, recording everything that happens in your web app, mobile app, or website. Instead of guessing why problems happen, you can aggregate and report on key frontend performance metrics, replay user sessions along with application state, log network requests, and automatically surface all errors.
Modernize how you debug web and mobile apps — start monitoring for free.
Would you be interested in joining LogRocket's developer community?
Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.
Sign up nowLearn how to manage memory leaks in Rust, avoid unsafe behavior, and use tools like weak references to ensure efficient programs.
Bypass anti-bot measures in Node.js with curl-impersonate. Learn how it mimics browsers to overcome bot detection for web scraping.
Handle frontend data discrepancies with eventual consistency using WebSockets, Docker Compose, and practical code examples.
Efficient initializing is crucial to smooth-running websites. One way to optimize that process is through lazy initialization in Rust 1.80.