SVG Filters Introduction

Get an overview of the SVG <filter> element and how filter primitives chain together to create effects like blur, shadows, and color shifts.

What Is an SVG Filter?

An SVG filter is declared as a <filter> element, usually inside <defs> so it isn't rendered directly, and given a unique id. Any shape or group can then use that filter by referencing it with the filter attribute, for example filter="url(#myFilter)". A filter behaves like a small image-processing pipeline: it contains one or more filter primitive elements, and each primitive reads an input image, processes it in some way, and produces an output that later primitives — or the final rendered result — can use.

A Minimal Blur Filter

<!DOCTYPE html>
<html>
<body>

<svg width="160" height="120" viewBox="0 0 160 120" xmlns="http://www.w3.org/2000/svg">
  <defs>
    <filter id="softBlur">
      <feGaussianBlur stdDeviation="4" />
    </filter>
  </defs>
  <rect x="30" y="30" width="100" height="60" fill="steelblue" filter="url(#softBlur)" />
</svg>

</body>
</html>

The filter Element and Its Region

The <filter> element itself accepts x, y, width, and height attributes that define the filter region — the rectangular area, relative to the element's bounding box, in which the filter is allowed to draw. By default this region extends from -10% to 120% in both dimensions, giving effects like blur or drop shadows a little extra room to spread beyond the original shape. If an effect looks clipped at the edges, the filter region is usually the reason, and widening x/y/width/height fixes it.

  • feGaussianBlur — softens edges by blurring the input image
  • feOffset — shifts the image horizontally and/or vertically, the basis of drop shadows
  • feColorMatrix — remaps color channels to produce grayscale, hue rotation, or saturation changes
  • feMerge — stacks multiple filter results on top of each other in order
  • feFlood plus feComposite — fills a solid color and blends it with another input
  • feDropShadow — a shorthand primitive that combines blur, offset, and color in a single step

Building a Drop Shadow from Primitives

<!DOCTYPE html>
<html>
<body>

<svg width="180" height="140" viewBox="0 0 180 140" xmlns="http://www.w3.org/2000/svg">
  <defs>
    <filter id="dropShadow" x="-30%" y="-30%" width="160%" height="160%">
      <feOffset in="SourceAlpha" dx="6" dy="6" result="offsetBlur" />
      <feGaussianBlur in="offsetBlur" stdDeviation="4" result="blurredShadow" />
      <feMerge>
        <feMergeNode in="blurredShadow" />
        <feMergeNode in="SourceGraphic" />
      </feMerge>
    </filter>
  </defs>
  <rect x="30" y="20" width="100" height="70" fill="orange" filter="url(#dropShadow)" />
</svg>

</body>
</html>

Chaining Primitives with in and result

Each filter primitive supports an in attribute naming the input it should read, and a result attribute naming the output it produces so later primitives can refer back to it. Two special keywords are always available: SourceGraphic, the original rendered element, and SourceAlpha, just the alpha (transparency) channel of that element, which is handy for building shadows in the shape's silhouette without its color showing through.

Reusing One Filter on Multiple Shapes

<!DOCTYPE html>
<html>
<body>

<svg width="220" height="120" viewBox="0 0 220 120" xmlns="http://www.w3.org/2000/svg">
  <defs>
    <filter id="shared" x="-20%" y="-20%" width="140%" height="140%">
      <feGaussianBlur stdDeviation="2.5" />
    </filter>
  </defs>
  <circle cx="60" cy="60" r="40" fill="mediumpurple" filter="url(#shared)" />
  <rect x="130" y="25" width="70" height="70" fill="seagreen" filter="url(#shared)" />
</svg>

</body>
</html>
Note: Modern browsers also support feDropShadow, a shorthand primitive equivalent to the offset-blur-merge chain shown above: <feDropShadow dx="6" dy="6" stdDeviation="4" flood-color="black" />. Use the longhand version when you need finer control, such as coloring the shadow independently.
Note: Filters are recalculated whenever the filtered element repaints, which can be expensive on large images or many animated elements. Keep filter regions as tight as reasonably possible and avoid animating filter attributes on dozens of elements at once.
Element / AttributePurpose
<filter>Container for a chain of filter primitives, referenced via filter="url(#id)"
feGaussianBlurBlurs the input using a Gaussian function controlled by stdDeviation
feOffsetShifts the input by dx/dy, the basis of drop-shadow effects
feMergeComposites multiple inputs in stacking order using feMergeNode children
feColorMatrixTransforms colors via a matrix, enabling grayscale, saturation, and hue effects
feDropShadowA shorthand primitive producing a blurred, offset, colored shadow in one step

Exercise: SVG Filters

How do you apply a filter defined as <filter id='f1'> to a shape?