Guide · Oct 21, 2026

Why Inline SVG Icons Show the Wrong Gradient (or None at All)

Each SVG looks right when you open it on its own. Put two or three of them inline on the same page and something breaks: an icon shows another icon's gradient, a chart's clip path cuts the wrong shape, a mask hides everything, or an icon goes flat. Remove one SVG and the others come back. The cause is almost always the same. Two files define the same id, and on a single page they are no longer separate.

One page, one ID namespace

Gradients, clip paths, masks, filters, markers and patterns are defined once, given an ID, and referenced from elsewhere: fill="url(#a)", clip-path="url(#clip0)", <use href="#shape">. Inside a standalone .svg file, those IDs only have to be unique within that file. Once you paste the markup into HTML (by hand, through a CMS, or with a framework component that inlines SVGs), every inlined SVG becomes part of one document, and the whole page shares one set of IDs.

Duplicate IDs are invalid, so there is no well-defined winner. Browsers resolve url(#a) to one of the definitions for every element that asks for it. Reports differ by browser: QuickChart users saw the first definition in the document win, and Figma users saw Safari use the last. Either way, at least one icon is drawn with a definition from a different file.

That's also why the problem disappears when the same files are used through <img src="icon.svg">, a CSS background-image or <object>. Each of those loads the SVG as its own document with its own IDs. Inline SVG vs <img> vs CSS background covers when inlining is worth that trade-off.

What it looks like

Where the duplicate IDs come from

Nobody types id="a" in two files on purpose. Tools generate it, and they generate the same names in every file:

How to fix it

The fix is to give each file's IDs a unique prefix and update every reference to match. Pick whichever of these fits how your SVGs reach the page:

For the hidden-definition case, the fix is different. A sprite or icon set that other icons reference shouldn't be hidden with display: none. Keep it rendered but invisible, for example as an <svg> with width="0" height="0" and position: absolute, so its gradients and masks stay usable.

How to confirm it's an ID problem

In DevTools, select the broken icon's shape and look at its fill, clip-path or mask. Then search the page's Elements panel for that ID (id="a", say). More than one match means a collision. A quicker test is to rename the ID in one file by hand and reload. If the icon fixes itself, you've found it. For a whole icon set, checking files pairwise doesn't scale, because the collision only exists between files. Drop them all into the checker at once and it builds the list of shared IDs for you. If you optimize your SVGs too, run the optimizer first and prefix afterwards. Prefixing changes only IDs and references, so the order doesn't undo either step.