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.

Solved With CSS! Colorizing SVG Backgrounds

CSS is getting increasingly powerful, and with features like CSS grid and custom properties (also known as CSS variables), we’re seeing some really creative solutions emerging. The possibilities are still being explored on what CSS can do to make writing UI’s simpler, and that’s exciting!

One of those is now one of my favorite CSS features: filters. Let’s look at how we can use filters to solve a problem you may have encountered when working with SVG as a background image on an element.

CSS Filters

First, let’s start by with an overview of filters. They include the following functions:

  • blur()
  • brightness()
  • contrast()
  • drop-shadow()
  • grayscale()
  • hue-rotate()
  • invert()
  • opacity()
  • saturate()
  • sepia()

These effects can also be achieved with SVG filters or WebGL shaders, but CSS filters are the easiest way to implement basic transformations in the most browser-efficient manner. Because they are shortcuts of SVG filter effects, you can also use filter: url() and specify a filter effect ID onto any element. If you want to play around with custom filters, I recommend checking out cssfilters.co.

The Problem: Editing SVG Backgrounds

I love using the SVG (scalable vector graphics) format for web design. SVG is a great image format for the web, and since it’s based on code, it allows for high-quality responsive and interactive content. When you inject SVG onto the page, you have access to each of its internal elements and their properties, allowing you to animate them, update values (such as color), and dynamically inject additional information. SVG is also a great icon format, especially instead of icon fonts, and in smaller UI elements due to its high quality (think: retina screens) and small image size (think: performance).

I find that often, when SVG is used for these smaller elements, or as a large area of illustration, it’s included as a background image for simplicity. The drawback to this is that the SVG is no longer under your control as a developer. You can’t adjust individual properties, like fill color, of an SVG background because it is treated just like any image. This color conundrum can be solved with CSS! Filters to the rescue!

Adjusting Brightness

The first time I discovered the SVG background challenge was when I was working on a website that had white SVG icons for social share icons that lived on a background determined to match that application. When these icons were moved onto a white background, they were no longer visible. Instead of creating a new icon, or changing the markup to inject inline SVG, you can use filter: brightness().

With the brightness filter, any value greater than 1 makes the element brighter, and any value less than 1 makes it darker. So, we can make those light SVG’s dark, and vice versa!

What I did above was create a dark class with filter: brightness(0.1). You can also do the opposite for darker icons. You can lighten icons by creating a light class with something like filter: brightness(100) or whatever is suitable to your needs.

Icons with a fill color of #000, or rgb(0,0,0) will not brighten. You need to have a value greater than 0 in any of the rgb channels. fill: rgb(1,1,1) works great with a high brightness value such as brightness(1000), but even brightness(1000) will not work on pure black. This is not an issue with light colors and white.

Adjusting Color

We’ve now seen how to adjust light and dark values with a brightness() filter, but that doesn’t always get us the desired effect. What if we want to inject some color into those icons? With CSS filters, we can do that. One little hack is to use the sepia filter along with hue-rotate, brightness, and saturation to create any color we want.

From white, you can use the following mixtures to get the navy, blue, and pink colors above:

.colorize-pink { filter: brightness(0.5) sepia(1) hue-rotate(-70deg) saturate(5);
} .colorize-navy { filter: brightness(0.2) sepia(1) hue-rotate(180deg) saturate(5);
} .colorize-blue { filter: brightness(0.5) sepia(1) hue-rotate(140deg) saturate(6);
}

The world is your oyster here. SVG is just one use case for multiple filters. You can apply this to any media type—images, gifs, video, iframes, etc., and support is pretty good, too:

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
18* 15* 35 No 17 6*

Mobile / Tablet

iOS Safari Opera Mobile Opera Mini Android Android Chrome Android Firefox
6.0-6.1* 37* No 4.4* 64 57

One final note here is to remember your user! Filters will not work in Internet Explorer, so please send a visible image to all of your users (i.e. don’t use a white SVG with an applied filter on a white background, because your IE users will not see anything). Also, remember to use alternative text for icon accessibility, and you’ll be golden to use this technique in your own applications!

The post Solved With CSS! Colorizing SVG Backgrounds appeared first on CSS-Tricks.

Using SVG to Create a Duotone Effect on Images

Anything is possible with SVG, right?!

After a year of collaborating with some great designers and experimenting to achieve some pretty cool visual effects, it is beginning to feel like it is. A quick search of “SVG” on CodePen will attest to this. From lettering, shapes, sprites, animations, and image manipulation, everything is better with the aid of SVG. So when a new visual trend hit the web last year, it was no surprise that SVG came to the rescue to allow us to implement it.

The spark of a trend

Creatives everywhere welcomed the 2016 new year with the spark of a colorizing technique popularized by Spotify’s 2015 Year in Music website (here is last year’s) which introduced bold, duotone images to their brand identity.

The Spotify 2015 Year in Music site demonstrates the duotone image technique.

This technique is a halftone reproduction of an image by superimposing one color (traditionally black) with another. In other words, the darker tone will be mapped to the shadows of the image, and the lighter tone, mapped to the highlights.

We can achieve the duotone technique in Photoshop by applying a gradient map (Layer > New Adjustment Layer > Gradient Map) of two colors over an image.

Choose the desired color combination for the gradient map
A comparison of the original image (left) and when the gradient map is applied (right)

Right click (or alt + click) the adjustment layer and create a clipping mask to apply the gradient map to just the image layer directly below it instead of the applying to all layers.

It used to take finessing the <canvas> element to calculate the color mapping and paint the result to the DOM or utilize CSS blend-modes to come close to the desired color effect. Well, thanks to the potentially life-saving powers of SVG, we can create these Photoshop-like “adjustment layers” with SVG filters.

Let’s get SaVinG!

Breaking down the SVG

We are already familiar with the vectorful greatness of SVG. In addition to producing sharp, flexible, and small graphics, SVGs also support over 20 filter effects that allow us to blur, morph, and do so much more to our SVG files. For this duotone effect, we will use two filters to construct our gradient map.

feColorMatrix (optional)

The feColorMatrix effect allows us to manipulate the colors of an image based on a matrix of rbga channels. Una Kravets details color manipulation with feColorMatrix in this deep dive and it’s a highly recommended read.

Depending on your image, it may be worth balancing the colors in the image by setting it to grayscale with the color matrix. You can adjust the rbga channels as you’d like for the desired grayscale effect.

<feColorMatrix type="matrix" result="grayscale" values="1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 1 0" >
</feColorMatrix>

feComponentTransfer

Next is to map the two colors over the highlights and shadows of our grayscale image with the feComponentTransfer filter effect. There are specific element attributes to keep in mind for this filter.

Attribute What it Does Value to Use
color-interpolation-filters (required) Specifies the color space for gradient interpolations, color animations, and alpha compositing. sRGB
result (optional) Assigns a name to this filter effect and can be used/referenced by another filter primitive with the in attribute. duotone

While the result attribute is optional, I like to include it to give additional context to each filter (and as a handy note for future reference).

The feComponent filter handles the color mapping based on transfer functions of each rbga component specified as child elements of the parent feComponentTransfer: feFuncR feFuncG feFuncB feFuncA. We use these rbga functions to calculate the values of the two colors in the gradient map.

Here’s an example:

The Peachy Pink gradient map in the screenshots above uses a magenta color (#bd0b91) , with values of R(189) G(11) B(145).

Divide each RGB value by 255 to get the values of the first color in the matrix. The RGB values of the second column result in #fcbb0d (gold). Similar to in our Photoshop gradient map, the first color (left to right) gets mapped to the shadows, and the second to the highlights.

<feComponentTransfer color-interpolation-filters="sRGB" result="duotone"> <feFuncR type="table" tableValues="(189/255) 0.9882352941"></feFuncR> <feFuncG type="table" tableValues="(11/255) 0.7333333333"></feFuncG> <feFuncB type="table" tableValues="(145/255) 0.05098039216"></feFuncB> <feFuncA type="table" tableValues="0 1"></feFuncA>
</feComponentTransfer>

Step 3: Apply the Effect with a CSS Filter

With the SVG filter complete, we can now apply it to an image by using the CSS filter property and setting the url() filter function to the ID of the SVG filter.

It’s worth noting that the SVG containing the filter can just be a hidden element sitting right in your HTML. That way it loads and is availble for use, but does not render on the screen.

background-image: url('path/to/img');
filter: url(/path/to/svg/duotone-filters.svg#duotone_peachypink);
filter: url(#duotone_peachypink);

Browser Support

You’re probably interested in how well supported this technique is, right? Well, SVG filters have good browser support.

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
8 9 3 10 12 6

Mobile / Tablet

iOS Safari Opera Mobile Opera Mini Android Android Chrome Android Firefox
6.0-6.1 10 all 4.4 62 57

That said, CSS filters are not as widely supported. That means some graceful degradation considerations will be needed.

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
18* 15* 35 No 17 6*

Mobile / Tablet

iOS Safari Opera Mobile Opera Mini Android Android Chrome Android Firefox
6.0-6.1* 37* No 4.4* 62 57

For example, Internet Explorer (IE) does not support the CSS Filter url() function, nor does it support CSS background-blend-modes, the next best route to achieving the duotone effect. As a result, a fallback for IE can be an absolutely positioned CSS gradient overlay on the image to mimic the filter.

In addition, I did have issues in Firefox when accessing the filter itself based on the path for the SVG filter when I initially implemented this approach on a project. Firefox seemed to work only if the filter was referenced with the full path to the SVG file instead of the filter ID alone. This does not seem to be the case anymore but is worth keeping in mind.

Bringing it All Together

Here’s a full example of the filter in use:

<svg xmlns="http://www.w3.org/2000/svg"> <filter id="duotone_peachypink"> <feColorMatrix type="matrix" result="grayscale" values="1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 1 0" > </feColorMatrix> <feComponentTransfer color-interpolation-filters="sRGB" result="duotone"> <feFuncR type="table" tableValues="0.7411764706 0.9882352941"></feFuncR> <feFuncG type="table" tableValues="0.0431372549 0.7333333333"></feFuncG> <feFuncB type="table" tableValues="0.568627451 0.05098039216"></feFuncB> <feFuncA type="table" tableValues="0 1"></feFuncA> </feComponentTransfer> </filter> </svg>

Here’s the impact that has when applied to an image:

A comparison of the original image (left) with the filtered effect (right) using SVG!

See the Pen Duotone Demo by Lentie Ward (@lentilz) on CodePen.

For more examples, you can play around with more duotone filters in this pen.

Resources

The following resources are great points of reference for the techniques used in this post.

  • SVG Filter primitive elements – MDN documentation
  • Finessing feColorMatrix – Una Kravets’ detailed post on A List Apart

Using SVG to Create a Duotone Effect on Images is a post from CSS-Tricks