SVG Filters
SVG filters allow you to apply complex visual effects to your elements, such as blurs, shadows, and color manipulations. They are defined once and can be applied to any shape or group.
The filter Element
Like gradients and patterns, filters are defined inside the defs element and referenced by a unique id. The actual container for these effects is the filter element, which serves as a wrapper for one or more filter primitives. These primitives are specialized elements prefixed with fe (short for Filter Element). By linking these primitives together inside a single filter tag, you can transform simple shapes into complex visual assets directly in the browser.
Filter primitives are the atomic building blocks of the SVG coordinate system. Each primitive performs a specific graphical operation, such as blurring, shifting, or color manipulation. They work by taking an input (either the source graphic itself or the output of a previous primitive), processing it, and passing the result to the next stage in the chain. This modularity allows for nearly infinite creative possibilities, from subtle drop shadows to organic, procedural textures like marble or clouds.
While many developers are familiar with CSS filters like blur() or grayscale(), the filter element offers far more granular control. Because its primitives operate at the pixel level and allow for complex blending and lighting calculations, they bridge the gap between standard web code and professional image-editing software like Photoshop or After Effects.
Simple Example: Blur and Drop Shadow
Here's an example of defining and applying basic blur and drop shadow filters:
Available Filter Primitives
Here are the filter primitives we can use in our filters:
| Primitive | Description |
|---|---|
feGaussianBlur |
Blurs the input image by a specified amount. Useful for soft shadows and glowing effects. |
feOffset |
Moves an image relative to its original position. Standard for creating the "offset" in a drop shadow. |
feColorMatrix |
Modifies colors using a 5x4 matrix. Used for grayscale, sepia, or adjusting saturation and hue. |
feBlend |
Combines two inputs using blending modes like multiply, screen, darken, or lighten. |
feMerge |
Layers multiple filter results on top of each other to build complex effects. |
feDropShadow |
A convenient single tag for creating standard drop shadows with offset and blur. |
feTurbulence |
Creates digital noise or textures, useful for generating organic patterns like clouds or grain. |
feDisplacementMap |
Uses the pixel values of one image to physically warp or shift another image. |
feMorphology |
Thickens (dilate) or thins (erode) the strokes of an image, often used for text outlines. |
feComposite |
Combines images based on pixel-level math, such as masking one shape into another. |
feComponentTransfer |
Allows for independent manipulation of color channels (R, G, B, A) for precise color grading. |
feDiffuseLighting |
Creates a matte lighting effect by treating the alpha channel as a surface map. |
feSpecularLighting |
Adds shiny, mirror-like highlights to a surface. |
feConvolveMatrix |
Applies a matrix of values to neighboring pixels for sharpening or embossing. |
feFlood |
Fills the entire filter area with a single solid color. |
feImage |
Pulls in an external graphic or another part of the SVG to use inside the filter. |
feTile |
Tiles a small input image to fill the entire filter region. |
feDistantLight |
Defines a light source at an infinite distance (like the sun) for lighting primitives. |
fePointLight |
Defines a light source at a specific coordinate (like a lightbulb). |
feSpotLight |
Defines a directional light that tapers off in a cone (like a flashlight). |
Advanced Example: Marble Texture
As you can probably guess, by combining the filter primitives above, we can create some pretty advanced effects. Here's an example of a marble texture filter:
Here we use a combination of filter primitives to create a marble texture that's a lot different to the simple blur and drop shadow examples above.
Filter Regions
By default, filters are applied within a "filter region" that is slightly larger than the element itself. If your effect (like a very large blur) gets cut off, you may need to increase the filter's x, y, width, and height attributes.
<filter id="largeBlur" x="-50%" y="-50%" width="200%" height="200%">
<feGaussianBlur stdDeviation="20" />
</filter>