SVG Filters

Jakob Jenkov
Last update: 2015-02-01

SVG filters are used to add nice effects to your SVG images. For instance, drop shadow, blur or highlights.

Filter Example

Here is a simple SVG filter example that shows two ellipses. The left ellipse is displayed without a filter. The righ ellipse is rendered with a Gaussian Blur filter applied to it:

  <defs>
      <filter id="blurFilter" y="-5" height="40"
          <feGaussianBlur in="SourceGraphic" stdDeviation="3" y="-"/>
      </filter>
  </defs>
    
  <ellipse cx="55" cy="60" rx="25" ry="15"
           style="stroke: none; fill: #0000ff; " />

  <ellipse cx="155" cy="60" rx="25" ry="15"
           style="stroke: none; fill: #0000ff; filter: url(#blurFilter);" />    

Here is the resulting image:

Notice how the edge of the right ellipse is blurred.

Filter Input and Output

SVG filters takes some input (source) to which they apply their filter effect. The input of a filter can be either the graphic of a shape (meaning the RGB colors), the alpha channel of a shape, or the output of another filter.

SVG filters produce a graphic output (result) from the input. This output is what is normally displayed instead of the shape the filter is applied to. The output of a filter can be used as the input of another filter. Thus, filters can be chained.

Here is an illustration of SVG filter input and output:

SVG filters can take the shape graphic, alpha channel or the ouput of another filter as input.
SVG filters can take a shape graphic, alpha channel or the output of another filter as input.

The input of an SVG filter is normally specified in the in attribute of a filter element. Here is an example:

<feGaussianBlur stdDeviation="3" in="SourceGraphic" />

If the output of an SVG filter is to be used as the input of another filter, you need to add a result attribute to the filter element. Here is an example:

<feGaussianBlur stdDeviation="3"
    in="SourceGraphic" result="blur"/>

Another SVG filter can now use the output of this filter by putting the value blur into its in attribute. The value blur is specified in the result attribute of the filter in the example above.

Filter Dimensions

The dimensions of a filter are set using its x, y, width and height attributes.

The x and y attributes are interpreted relatively to the x and y of the shape used as input. Since the output of some filters are often bigger in size than the input (like blur added around a shape), you will often need to use a negative number for x and y to avoid cutting off the graphics added by the filter.

The width and height attributes are equally straightforward. Again, you may sometimes have to specify a width and height that is larger than the input shape, to avoid cutting off effects added by the filter.

Combining Filters

You can combine filters using the <feMerge> element. Here is an example:

<defs>
    <filter id="blurFilter2" y="-10" height="40" x="-10" width="150">
        <feOffset in="SourceAlpha" dx="3" dy="3" result="offset2" />
        <feGaussianBlur in="offset2" stdDeviation="3"  result="blur2"/>

        <feMerge>
            <feMergeNode in="blur2" />
            <feMergeNode in="SourceGraphic" />
        </feMerge>
    </filter>
</defs>

<ellipse cx="55" cy="60" rx="25" ry="15"
         style="stroke: none; fill: #0000ff; filter: url(#blurFilter2);" />    

This example creates an SVG filter containing two filter elements: <feOffset> and <feGaussianBlur>. The offset filter effect works on the alpha channel of the shape it is applied to. The Gaussian blur works on output from the offset filter effect.

The <feMerge> element combines the output of the blur filter with the original graphic. The inputs are combined in the order they appear inside the <feMerge> element. Thus, the later inputs are shown ontop of earlier inputs. The result is an image where the shape looks like it has a drop shadow. Here is the resulting image:

Gaussian Blur Filter

The Gaussian blur SVG filter can blur an SVG shape. The Gaussian blur filter is represented by the <feGaussianBlur> element. Here is an example:

<defs>
    <filter id="blurFilter4" x="-20" y="-20" width="200" height="200">
        <feGaussianBlur in="SourceGraphic" stdDeviation="10" />
    </filter>
</defs>
<rect x="20" y="20" width="90" height="90"
      style="stroke: none; fill: #00ff00; filter: url(#blurFilter4);" />

This example defines a <filter> with a <feGaussianblur> inside. The example then defines a green rectangle which references the filter from its CSS filter property. Here is the resulting image:

Blur Size

The stdDeviation attribrute of the <feGaussianBlur> element determines how much to blur the shape the filter is applied to. The bigger a number, the more the shape is blurred. Here are three examples with different values for the stdDeviation attribute:

<defs>
    <filter id="blurFilter5" x="-20" y="-20" width="200" height="200">
        <feGaussianBlur in="SourceGraphic" stdDeviation="2" />
    </filter>
    <filter id="blurFilter6" x="-20" y="-20" width="200" height="200">
        <feGaussianBlur in="SourceGraphic" stdDeviation="6" />
    </filter>
    <filter id="blurFilter7" x="-20" y="-20" width="200" height="200">
        <feGaussianBlur in="SourceGraphic" stdDeviation="12" />
    </filter>
</defs>

<rect x="20" y="24" width="90" height="90"
      style="stroke: none; fill: #00ff00; filter: url(#blurFilter5);" />
<rect x="150" y="24" width="90" height="90"
      style="stroke: none; fill: #00ff00; filter: url(#blurFilter6);" />
<rect x="300" y="24" width="90" height="90"
      style="stroke: none; fill: #00ff00; filter: url(#blurFilter7);" />    

Here is the resulting image:

Notice how the rectangles become more and more blurred, the higher the value in the stdDeviation attribute of the filter applied to them is.

Blurring the Alpha Channel

The example above used SourceGraphic as input, meaning the RGB colors of the shape were used as input for the filter. You can use the alpha channel of the shape as input instead, by setting the value SourceAlpha on the in attribute of the <feGaussianBlur> element. Here is an example:

<defs>
    <filter id="blurFilter8" x="-20" y="-20" width="200" height="200">
        <feGaussianBlur in="SourceAlpha" stdDeviation="10" />
    </filter>
</defs>
<rect x="20" y="20" width="90" height="90"
      style="stroke: none; fill: #00ff00; filter: url(#blurFilter8);" />    

Here is the resulting image:

Notice, that even if the rectangle is defined with green fill, the output from the filter is black and white. That happens when the Gaussian blur filter is applied to the alpha channel instead of the graphic (RGB) channel.

Offset Filter

The offset filter takes an input and moves the input in its output. That is, it can move a shape up, down, left or right. Thus it works like a translation transformation, except it is done in a filter. Here is an example:

<defs>
    <filter id="offsetFilter1" x="-20" y="-20" width="200" height="200">
        <feOffset in="SourceGraphic" dx="80" dy="20" />
    </filter>
</defs>
<rect x="20" y="20" width="90" height="90"
      style="stroke: #000000; fill: none; filter: url(#offsetFilter1);" />
<rect x="20" y="20" width="90" height="90"
      style="stroke: #000000; fill: none; " />

This example defines two rectangles in the exact same location. One of the rectangles has an offset filter applied, which moves it down and to the right.

Here is the resulting image.

It seems that the offset filter has some other effect on the shape also (a kind of blur), but I am not sure why that is. I have not been able to find any explanation of why this happens.

Color Matrix Filter

The color matrix filter can be used to apply matrix transformations to the colors of a shape. Here is an example:

<defs>
    <filter id="colorMatrixFilter1" x="-20" y="-20" width="200" height="200">
        <feColorMatrix in="SourceGraphic" type="matrix"
                values="0 0 0 1 0
                        0 0 0 1 0
                        0 0 0 1 0
                        0 0 0 1 0
                "/>
    </filter>
</defs>
<rect x="20" y="20" width="90" height="90"
      style="stroke: none; fill: #0000ff; filter: url(#colorMatrixFilter1);" />

The values for the matrix are provided inside the values attribute of the <feColorMatrix> element. There has to be 4 x 5 = 20 values in total. The values are applied to the colors of the original shape like this:

 0 0 0 red   0
 0 0 0 green 0
 0 0 0 blue  0
 0 0 0 1     0

Here is the resulting image:

Note: I am getting some rather odd results with the color matrix filters in both Chrome and Firefox. The rectangle above is specified with a fill color, yet once the color matrix filter has done its work, only the outline is left.

Blend Filter

The blend filter can blend input from multiple filters into one. Here is an example:

<svg width="500" height="100">
  <defs>
    <filter id="blurFilter3" y="-10" height="40" x="-10" width="150">
      <feOffset in="SourceAlpha" dx="3" dy="3" result="offset3" />
      <feGaussianBlur in="offset3" stdDeviation="3"  result="blur3"/>

      <feBlend  in="SourceGraphic" in2="blur3" x="-10" width="160"/>

    </filter>
  </defs>

  <ellipse cx="55" cy="60" rx="25" ry="15"
         style="stroke: none; fill: #0000ff;
                filter: url(#blurFilter3);" />

</svg>    

This example declares a filter that uses 3 filter effects. The first two is an offset and a Gaussian blur effect which are already chained. The third is the <feBlend> effect which takes two inputs (in and in2) and blends them into one.

The resulting effect is very similar to what you get by combining filters as described earlier in this text.

Jakob Jenkov

Featured Videos

Java Generics

Java ForkJoinPool

P2P Networks Introduction



















Close TOC
All Tutorial Trails
All Trails
Table of contents (TOC) for this tutorial trail
Trail TOC
Table of contents (TOC) for this tutorial
Page TOC
Previous tutorial in this tutorial trail
Previous
Next tutorial in this tutorial trail
Next