I recently came about this glassmorphism trend on Codepen that uses the backdrop-filter
CSS property. It’s a cool way to blur a background. Before finding this technique, I would make text readable by using Photoshop (well, GiMP) to darken and blur a background image. By using the backdrop-filter
property, a background can be blurred with CSS.
Context
So, we all love heros with some text, right? And images for the background, right? So you found a really nice background photo that you want some text on, but when you just do that, it looks bad because the background isn’t contrasted with the text enough. Or maybe there’s a little weird interlacing thing that’s happening around the edges of the text.
Well, you could do a few things. To fix that, you could do what I did on my landing page – that is add a gradient background in-between the image and the text. You could add a blurred background there, too. Another option is to pull the photo in to photoshop and edit it, making it darker (or brighter, depending on your text color), and maybe blurring it a little bit to make the text stand out more. Or, you could use the backdrop-filter
property on the element’s children.
Using Backdrop-filter
Enter backdrop-filter
. This will take care of everything you need. This property has a bunch of potential values. To start, we’ll focus on blur()
, but we’ll go over the other 9 later on in the post. Before we get started, a point: backdrop-filter
will seem to affect everything behind the element it’s applied to, so it won’t work directly on elements with background images. So, if you’re trying this to make text more readable on a hero image, for example, you’d either need to make a container as big as the hero to hold the children and apply the backdrop-filter to, or be okay with the backdrop-filter being applied just to the box of the content. Okay, with that out of the way…blur()
does exactly what you think – it blurs the backdrop. The value passed to the function should be a specified length, such as px, em, rem, vh, or vw
. Passing a value of “0” would reset the blur (or have no effect).
.el {
backdrop-filter: blur(10px);
backdrop-filter: blur(2em);
}
In Use
We’ll start by blurring the backdrop of a child-element on a hero. I really like this effect with a thin, uppercase serif font for some reason. I’ve added a little bit of padding to the child element to make it a little nicer to look at. I put the backdrop-filter
property right at the top.
See the Pen Backdrop Filter Demo 1 by Nate Northway (@the_Northway) on CodePen.
Combining Filters
So that worked ok, but you might still be able to see that even with the blur, there are times when the contrast is not enough. Multiple values can be applied that can fix this. I think knocking the brightness down a little bit would make this look great. The syntax is pretty simple, just add the value after the initial value.
.el {
backdrop-filter: blur(10px) brightness(90%);
}
Here’s that in practice:
See the Pen Backdrop Filter Demo 2 by Nate Northway (@the_Northway) on CodePen.
The Other Method
Ok, so that’s the basics, but by changing the markup a little tiny bit, we can get that effect across the whole hero image. All we need is an intermediate element between the background and the child, or for the child to be the same size as the background. We’ll tackle all that in a few ways, all in the same pen.
See the Pen Backdrop Filter Demo 3 by Nate Northway (@the_Northway) on CodePen.
Backdrop-filter values
The other values for backdrop-filter
are all the filter functions defined by the W3C. Below is a demo of all of them. There are a few that don’t seem to do much – I have a feeling because they don’t. I left out box-shadow, for example, because that is meant for a different feature, and though it technically works here, it doesn’t do anything you could ever see.
See the Pen Backdrop Filter Demo 4 by Nate Northway (@the_Northway) on CodePen.
Browser Compatibility
Not good news here. Chrome, Edge, and Safari are the only desktop browsers (currently as of December 2020) with support. No support from FF or IE. In the mobile realm, Android Chrome, Android Browser, and Safari all support it, while Android FF does not. Check out caniuse for more detailed explanation.
An Aside
When I was building the last demo, I used SCSS variables to make it a little easier to build it out. Basically, SCSS to run a @for
loop for each of the possible value combinations of input. Each filter, and each possible value (0-100). Using the #{$i}
variable as the parameter for the function on grayscale, invert, opacity, and saturate caused the SCSS to throw an error because those are all SCSS functions, as well. The only thread I found on this was from 2013 and seems like it should have been updated by now, right? I found a quick fix in that thread, but I wonder if I was doing something wrong?