Apply a Filter to a Background Image

You can apply a filter to an entire element quite easily with the filter property. But what if you want to apply a filter just to the background of an element? It’s weirdly tricky.

There are CSS properties that specific to backgrounds, like background-blend-mode — but blending and filters are not the same thing. It sorta seems to be the reason we have backdrop-filter, but not quite. That does filtering as the background interacts with what is behind the element.

There is no background-filter, unfortunately. What are we to do?

Use a pseudo-element instead of a background

If you put the contents of the element in an inside wrapper, you can set that on top of a pseudo-element that is simply pretending to be a background.

.module { position: relative;
}
.module::before { content: ""; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-image: url(graphic-to-be-filtered.jpg); filter: grayscale(100%);
}
.module-inside { /* This will make it stack on top of the ::before */ position: relative;
}

See the Pen Apply Filter to Psuedo Element by Chris Coyier (@chriscoyier) on CodePen.

See how the “background” gets filtered with grayscale there? We called the grayscale filter there and applied it only to the pseudo-element, leaving the rest of the content inside unfiltered.

It depends on what kind of filtering you want… you might be able to fake it with blend modes

I ran into this issue as I was specifically trying to grayscale the background image of an element. Since, as we’ve covered, there is no specific property just for that, I thought about background-blend-mode, particularly how there are blending options for things like saturation and color. If I could set pure black over the top of the graphic, then I could blend them — like I can with multiple backgrounds — and essentially fake a grayscale effect.

Note that you can’t use a solid color by itself when working with multiple backgrounds (that would be a background-color not background-image), so we have to fake that as well with a no-transition linear-gradient.

.module { background-image: linear-gradient(black, black), url(image-to-be-fake-filters.jpg); background-size: cover; background-blend-mode: saturation;
}

See the Pen Apply Fake Filter with Blend Mode by Chris Coyier (@chriscoyier) on CodePen.

Dan Wilson’s explorations

Dan got way into this and made an exploratory Pen in which there are three layers:

  1. Top layer: a vignette from a radial-gradient
  2. Middle layer: solid color
  3. Bottom layer: image graphic

You can adjust the colors used on the top two layers and apply different blend modes to each one. That was another thing I learned! Just like you can comma-separate to make multiple backgrounds (and likewise with background-size, background-position and such to apply those values to specific backgrounds) you can also comma-separate background-blend-mode to apply different blending effects to each layer.

See the Pen Multiple Backgrounds, Multiple Blend Modes by Dan Wilson (@danwilson) on CodePen.

The post Apply a Filter to a Background Image appeared first on CSS-Tricks.

The backdrop-filter CSS property

I had never heard of the backdrop-filter property until yesterday, but after a couple of hours messing around with it I’m positive that it’s nothing more than magic. This is because it adds filters (like changing the hue, contrast or blur) of the background of an element without changing the text or other elements inside.

Take this example where I’ve replicated the iOS notification style: see how the background of each of these boxes are blurred but the text isn’t?

That’s only a single line of CSS to create that faded background effect, just like this:

.notification { backdrop-filter: blur(3px);
}

Now it’s worth noting that browser support for this CSS property isn’t particularly well supported just yet (see below). But we’ve been trying to do this sort of filtering stuff for a really long time and so it’s great to see that progress is being made here. Chris wrote about the “frosted-glass” technique in 2014 and way back then you had to use a bunch of weird hacks and extra images to replicate the effect. Now we can write a lot less code to get the same effect!

We also get to pick from a lot more filters than just that frosted glass style. The following demo showcases all of the backdrop-filter values and how they change the background:

Each of these boxes are just separate divs where I’ve applied a different backdrop-filter to each. And that’s it! I sort of can’t believe how simple this is, actually.

Of course you can chain them together like so:

.element { backdrop-filter: blur(5px) contrast(.8);
} 

And this could make all sorts of elaborate and complex designs, especially if you start combining them together with animations.

But wait, why do we even need this property? Well, after reading up a little it seems that the go-to default example is a modal of some description. That’s what Guillermo Esteves was experimenting with back in 2015:

See the Pen PwRPZa by Guillermo Esteves (@gesteves) on CodePen.

I reckon we can do something much weirder and more beautiful if we put our minds to it.

A note about browser support

The backdrop-filter property is not well supported at the time of this writing. And even in Safari where it is supported, you’ll still need to prefix it. There’s no support for Firefox at all. But, really, do websites need to look exactly the same in every browser?

This browser support data is from Caniuse, which has more detail. A number indicates that browser supports the feature at that version and up.

Desktop

Chrome Opera Firefox IE Edge Safari
No No No No 17 9*

Mobile / Tablet

iOS Safari Opera Mobile Opera Mini Android Android Chrome Android Firefox
9.0-9.2* No No No No No

Further reading

  • backdrop-filter on MDN
  • Building iOS-like transparency effects in CSS with backdrop-filter

The post The backdrop-filter CSS property appeared first on CSS-Tricks.