How to svg native filters vs. css filter property: a practical comparison
- Step 1Decide where the asset will be displayed — If the SVG will only ever be inline in a page that loads your CSS, a CSS filter is fine. If it might be an
<img src>, a CSSbackground-image, or shipped to a context without your stylesheet, embed the effect with the SVG injector instead. - Step 2Match the effect to a system — Blur, glow, and drop shadow exist in both worlds. Frosted glass that blurs the page behind the element exists only in CSS (
backdrop-filter). Custom convolution and displacement exist only in SVG primitives — the injector does not author those, but hand-written SVG can. - Step 3For a portable effect, inject SVG primitives — Run the svg-filter-injector: pick a preset and intensity. It writes the
<filter>into<defs>and attaches it to your content, so the effect is part of the file. - Step 4For a quick page-only effect, write CSS — Add
filter: drop-shadow(...)orfilter: blur(...)in your stylesheet against the host element. No file edit, but the effect lives and dies with the CSS. - Step 5Reference an SVG filter from CSS if you need both — Define a
<filter>in inline SVG and apply it to any HTML element viafilter: url(#id). This routes CSS through SVG primitives — useful when you outgrow the standard CSS filter functions. - Step 6Verify the asset out of context — Drop the finished SVG into an
<img>tag with no surrounding CSS. If the effect is still there, it is embedded; if it is gone, it was a CSS filter and needs the injector to make it portable.
Capability and portability comparison
How embedded SVG filters compare with the CSS filter / backdrop-filter properties. The injector covers the blur/glow/shadow row via real SVG primitives.
| Dimension | Embedded SVG filter (injector) | CSS filter property | CSS backdrop-filter |
|---|---|---|---|
| Lives in | the SVG file (<defs>) | your stylesheet | your stylesheet |
Renders inside <img src> | Yes | No (CSS does not reach the image's internals) | No |
| Blur / glow / drop shadow | Yes — feGaussianBlur, feMerge, feDropShadow | Yes — blur(), drop-shadow() | Yes (blur of the backdrop) |
| Blur the content behind the element | No (operates on the SVG's own pixels) | No | Yes — this is its whole purpose |
| Custom convolution / displacement | Possible in hand-written SVG (not via this tool) | No | No |
| Ease of authoring a basic effect | Preset + slider in the injector | One CSS line | One CSS line |
Decision matrix
Pick the system by where the effect must live and what it must do.
| You want… | Best choice | Why |
|---|---|---|
A drop shadow that ships with an icon used as <img> | Embedded SVG (injector) | CSS filters do not apply to an image's internals |
A quick hover blur on a <div> | CSS filter | No file edit; trivial to write and toggle |
| Frosted glass that blurs the page behind a panel | CSS backdrop-filter | SVG filters cannot sample the backdrop |
| A reusable glow across an SVG sprite | Embedded SVG (injector) on the sprite source | Effect travels with the asset; pair with svg-sprite-builder |
| A coloured shadow on an icon | Recolour then inject, or write CSS drop-shadow(color) | The injector's shadow colour is fixed; CSS drop-shadow() takes a colour |
Cookbook
Same effect, two ways — so you can see where each one breaks.
CSS drop shadow vanishes inside <img>
A CSS filter on an inline SVG works on the page, but the moment the same SVG is referenced as an image the CSS no longer reaches it. The injector's embedded feDropShadow does not have this problem.
Works (inline, page CSS loaded):
.icon { filter: drop-shadow(2px 4px 3px rgba(0,0,0,.4)); }
<svg class="icon">...</svg>
Broken (same SVG as an image):
<img src="icon.svg" class="icon"> <!-- shadow is GONE: CSS can't enter the image -->
Fixed (inject the shadow into the file):
<img src="icon-dropshadow.svg"> <!-- shadow embedded in <defs>, renders everywhere -->CSS line vs. injected SVG markup
The same drop shadow expressed both ways. The injector's Drop Shadow at intensity 6 emits dx=3, dy=6, stdDeviation=3, flood-opacity 0.4 (black).
CSS:
.icon { filter: drop-shadow(3px 6px 3px rgba(0,0,0,.4)); }
Injected SVG (preset dropshadow, intensity 6):
<filter id="jad-filter-dropshadow" x="-10%" y="-10%" width="130%" height="130%">
<feDropShadow dx="3" dy="6" stdDeviation="3" flood-opacity="0.4"/>
</filter>Frosted glass is a CSS-only job
Glassmorphism that blurs the page behind a panel needs backdrop-filter — the injector's Glassmorphism preset only blurs and saturates the icon's own pixels, not the backdrop.
True frosted glass (CSS only):
.panel { backdrop-filter: blur(12px) saturate(1.5); background: rgba(255,255,255,.2); }
Injector Glassmorphism (icon's own pixels only):
<filter id="jad-filter-glassmorphism">
<feGaussianBlur in="SourceGraphic" stdDeviation="6" result="blur"/>
<feColorMatrix in="blur" type="saturate" values="1.5"/>
</filter>
# Use this for a self-blurred icon, NOT to see the background through it.Route CSS through an SVG filter
When CSS filter functions are not enough, define the filter in inline SVG and reference it by url(). This applies SVG primitives to any HTML element.
<svg width="0" height="0"><defs>
<filter id="halo"><feGaussianBlur stdDeviation="3" result="b"/>
<feMerge><feMergeNode in="b"/><feMergeNode in="SourceGraphic"/></feMerge></filter>
</defs></svg>
.title { filter: url(#halo); } /* SVG glow on an HTML heading */Make a CSS-only effect portable
If a teammate built the look with CSS and you now need the icon in emails or docs, stop maintaining the CSS and bake the effect into the file with the injector.
Before: glow lives in styles.css (lost outside the app)
After: run svg-filter-injector -> glow @4 -> logo-glow.svg
the <feGaussianBlur>+<feMerge> are in the file; CSS rule can be deletedEdge cases and what actually happens
CSS filter on an icon reused as an image
Effect lostA CSS filter never enters the contents of an <img> or CSS background-image. The icon renders flat. Bake the effect into the SVG with the svg-filter-injector so it survives the move.
Expecting the SVG glassmorphism to show the backdrop
Not supportedSVG filters cannot read pixels outside the element's own region, so the Glassmorphism preset blurs only the icon. For glass that blurs the page behind it, use CSS backdrop-filter on a container.
Wanting a custom convolution or displacement effect
Out of scopeThe injector only emits its five presets (blur, glow, shadow, glassmorphism, neomorphism). feConvolveMatrix, feDisplacementMap, and feTurbulence are valid SVG but must be hand-written; the tool does not author them, and CSS cannot do them at all.
Coloured shadow needed
Differs by systemCSS drop-shadow() takes a colour argument; the injector's shadow colour is fixed (black, or white+black for neomorphism). For a coloured shadow with embedded SVG, hand-edit the emitted flood-color, or recolour artwork with svg-hex-swapper first.
Stacking many filters in CSS vs SVG
Both supported, differentlyCSS chains functions in one declaration (filter: blur(2px) brightness(1.1)). SVG chains primitives inside one <filter> via result/in. The injector writes one preset at a time, so multi-primitive SVG stacks beyond a preset are a hand-edit.
Inline SVG vs external SVG support for `url(#id)`
Inline onlyfilter: url(#id) resolves against a filter in the same document. Referencing a filter id inside an external SVG file from page CSS is inconsistently supported. Keep the <filter> in the same document or embed it in the asset itself.
Performance of a large blur
Comparable, GPU-boundBoth CSS and SVG blur are GPU-accelerated for simple cases. A very large stdDeviation or many filtered elements forces extra texture passes either way; throttle intensity and apply filters to a few hero elements, not every list item.
Email and Markdown rendering
Embedded SVG winsMost email clients and Markdown renderers strip or ignore your CSS but still render an <img> of an SVG. An embedded SVG filter shows; a CSS filter does not. Inject when the destination is outside your app.
Frequently asked questions
What is the core difference?
A CSS filter lives in your stylesheet and applies to any element while the CSS is loaded; an embedded SVG filter lives inside the SVG file and travels with it, rendering even as an <img>. The injector produces the embedded kind.
Which one should I use for an icon I distribute?
Embedded SVG. CSS filters do not reach an image's internals, so a distributed icon used as <img> would lose a CSS effect. Inject the effect so it is part of the file.
Can SVG filters create frosted glass over the background?
No. SVG filters only operate on the element's own pixels. The injector's Glassmorphism preset blurs and saturates the icon itself. True backdrop frosting needs CSS backdrop-filter.
What can SVG filters do that CSS cannot?
Hand-written SVG offers feConvolveMatrix, feDisplacementMap, feTurbulence, feMorphology, and fine feComposite/feBlend control. The injector itself does not author those, but they are possible in raw SVG; CSS has no equivalent.
What can CSS filters do that SVG cannot?
backdrop-filter blurs and tints whatever is behind the element. SVG filters cannot see outside the element's region, so this glassmorphism-over-content effect is CSS-only.
Is one faster than the other?
For simple blur and shadow, they are comparable and both GPU-accelerated. Long primitive chains or huge blur radii add texture passes in either system, so keep intensity and the number of filtered elements modest.
Can I apply an SVG filter from CSS?
Yes — filter: url(#my-filter) references a <filter> defined in inline SVG and applies it to any HTML element, combining CSS targeting with SVG primitives. Keep the filter in the same document.
Which approach does the JAD tool take?
Embedded SVG. The svg-filter-injector writes native <filter> primitives into the SVG's <defs>, so the effect is portable and does not depend on any external CSS.
Do both work in all browsers?
The blur, glow, and drop-shadow paths (feGaussianBlur, feDropShadow, feMerge, CSS blur()/drop-shadow()) are universally supported. backdrop-filter has good but slightly newer support; check it for older targets.
How do I move an existing CSS effect into the file?
Run the injector with the matching preset and intensity, then delete the CSS rule. The effect is now embedded <defs> markup that renders anywhere the SVG does.
Can I get a coloured shadow either way?
With CSS, drop-shadow(x y blur color) takes a colour. With the injector the shadow colour is fixed, so recolour the source first or hand-edit the emitted flood-color.
Should I ever use both together?
Yes — embed the portable part (blur/shadow) in the SVG, and use CSS backdrop-filter on the surrounding container for the glass-over-background part that SVG cannot do.
Privacy first
Every JAD SVG tool runs entirely in your browser using the DOM API and Canvas. Your SVG files never leave your device — verified by zero outbound network requests during processing.