If I asked you to blur an image or make color adjustments to it, you’d probably reach for your favorite image or graphic editing program and rightly so. Effects like these have been created in image editors for years. However, some can now be created without the editor and through code alone.
By code I’m referring to filters in CSS and SVG. At the moment CSS lags a little behind SVG in terms of which browsers support the different filters. As you might have already guessed, I want to start a new series today about SVG filters.
My plan is to talk about the basics of SVG filters over the next few weeks and then spend time looking in more detail at some of the different things you can do with SVG filters. At the end of the series I’ll talk a little about CSS filters as well.
Be prepared. This is going to be a long series. The basics won’t take too long to cover, but the details of the specific filter primitives will. The series will easily take up most of the rest of this year and continue into 2017. Because it will take awhile to get to the end, I’ll probably break the series somewhere in the middle, and talk about something else for a bit before coming back and finishing this one.
How SVG Filters Work
I’m sure you’ve added a filter to an image before. I don’t mean things like Instagram filters, which are really specific combinations of more general filters. I mean the basic underlying filters like adding a Gaussian blur to an image or embossing another. You’ve probably placed one image on top of another and used your graphics program to blend them using a multiply or darken blend mode.
The basic idea behind SVG filter effects is you start with a source image or SVG graphic and then modify the source with one or more filters before outputting the modified image to the screen. Filters are nice because they can be added in nondestructive ways. Remove the filters and the original source is displayed again.
SVG filters are defined in one place and then referenced in another. The basic form usually looks like this.
1 2 3 4 5
<filter id="my-filter"> <filter primitive /> </filter> <circle filter="url(#my-filter)">
I’ve left out the details in the code above to focus on the general idea that you define your filters using one or more filter primitives inside a <filter> element. The filter element gets an an id, which is then referenced by the source graphic.
Note the syntax on the circle element. There’s a filter property, which takes as its value a url() that references the specific filter you want to add.
If you’ve followed some of my previous SVG posts or are generally familiar with SVG, you’ll notice this set up is similar to many other elements which are defined in one place and referenced in another.
Each filter primitive performs a single graphic operation. One might blur the image. Another might change it’s color. A third might offset its location. While each filter primitive performs a single operation, you can have multiple filter primitives inside a single filter element so your filter could both blur and offset an image or blend one image with another and then add a lighting effect.
Filters can be applied to an original source graphic or they can be applied to the result of another filter. In other words you can add a one filter effect to an image and then use the result of that effect as the source for another filter effect.
You can also apply a filter to container elements like <g> and have the filter apply to the entire group as opposed to a single element inside the group. You can even add a filter to an empty container and through a <use> element call the filter which produces the entire graphic for output to the screen.
Again, I’m leaving out the details in this introduction, though I promise to fill them in through the rest of the series. For the remainder of this post I’d like to show you a simple example and talk through it to drive home the basic concepts.
A Simple Example Applying a Gaussian Blur Filter
To illustrate how filters work let’s start with a couple of unfiltered shapes. Here are two identical squares placed inside the SVG canvas.
1 2 3 4
<svg width="100%" height="220" style="outline: 1px solid red"> <rect x="10" y="10" width="100" height="100" fill="#00f" /> <rect x="115" y="10" width="100" height="100" fill="#00" /> </svg>
Hopefully this isn’t anything new. I created two shapes using the <rect> element and set both to have equal width and height. I placed them next to each other with a few pixels in between.
I’m going to work with a Gaussian blur filter as its effects are easily seen and because it’s a simple filter to understand and demonstrate. The filter primitive to add a Gaussian blur is <feGaussianBlur>, which I’ll cover in more detail later in the series. Let’s add the filter to the example.
1 2 3 4 5 6 7 8 9 10
<svg width="100%" height="220" style="outline: 1px solid red"> <defs> <filter id="blur"> <feGaussianBlur stdDeviation="3" /> </filter> </defs> <rect x="10" y="10" width="100" height="100" fill="#00f" /> <rect x="115" y="10" width="100" height="100" fill="#00f" filter="url(#blur)" /> </svg>
You’ll notice I placed the filter element inside a <defs> element since we’re defining a filter in one location and referencing it in another. It’s not necessary, but it’s standard practice. The filter has an id of “blur” and inside the filter element is a single <feGaussianBlur> filter primitive.
Don’t worry too much about the stdDevdiation property on the filter primitive for now. All you need to know is the greater the value of the stdDeviation, the more blur there will be on the resulting graphic.
The last thing to notice is I added a filter property to the second rectangle and refer to the blur filter using the filter property and a value of url(#blur).
Here’s the result.
As you can see the second rectangle is blurry. It has fuzzy edges and even the center isn’t as solid blue as the original. It’s blurry throughout. Best of all I used exactly zero bitmapped images so we can get the original rectangle back any time we want by removing the filter.
You probably don’t want to blur most elements that appear on a webpage, but you might want to blur the shadow behind something and later in the series I’ll show you how to create a drop shadow with SVG by combining this filter primitive with another one.
There is a lot more to SVG filters than what I’ve showed here and I’ll dig into the details in the coming weeks. Hopefully you can see it’s relatively easy to add a filter to an SVG graphic, which is the main thing I wanted to show you today.
If you’ve followed along with some of my previous SVG series, the basics of filters should look familiar. You define your filters in one location and refer to them on the graphic or container to which you want to apply the filter.
There are also many more filter primitives besides feGaussianBlur. SVG offers primitives to add lighting effects, blend two images, adjust colors, and all sorts of other things.
I’ll get to all the filter primitives in a few weeks, but first I want to go into more detail about how filters work. I’ll pick things up next time by talking more about the filter element and the different attributes that help you define the filter.
Download a free sample from my book, Design Fundamentals.