· 4 min read
How to Combine SVG Icons Into One Sprite
Heshan Fernando
Co-founder & COO
You’ve got twenty icons from a designer, each in its own SVG file, each with a hard-coded fill colour and its own idea of what the viewBox should be. Drop them in as <img> tags and you get twenty requests and no way to change their colour with CSS.
An SVG sprite solves both problems at once, but only if the merge is done properly — and the two things that go wrong are always the same two things.
What an SVG sprite actually is
A sprite is one SVG document containing several <symbol> elements, each with an id. Anywhere on the page you reference one with <svg><use href="#icon-search"/></svg>, and the browser draws that symbol.
Two details make it work.
Each symbol keeps its own viewBox. That’s what lets the icon scale to whatever size the <use> element is given. A symbol without a viewBox renders at a fixed size and ignores your CSS entirely — the single most common sprite bug.
Fills are replaced with currentColor. Instead of fill="#333", the path inherits the text colour of wherever it’s placed, so a button’s hover state changes its icon for free. This is the thing separate <img> tags can never do.
Why people get stuck here
- Mixed grid sizes. Icons drawn on 24px and 16px grids merged into one sprite look inconsistent at every size.
- ID collisions. SVGs often contain internal IDs for gradients and clip paths. Merge two files that both use
#aand one of them breaks. - Hard-coded fills. Every icon locked to the colour it was exported with.
- External sprite CORS. Referencing an external sprite file from a different origin silently fails in most browsers.
What a good sprite looks like
Every symbol has a viewBox
Non-negotiable. Without it the icon can’t scale, and the failure looks like a CSS problem rather than a markup one.
IDs are prefixed and predictable
icon-search, icon-close, icon-menu. A prefix prevents collisions with other IDs on the page, and predictable naming means you can reference an icon without opening the sprite to check.
Colour comes from CSS
Convert fills to currentColor unless an icon is genuinely multi-colour — a flag, a logo, a brand mark. Those keep their original fills and simply don’t participate in theming.
| Approach | Requests | Can CSS Colour It? | Best For |
|---|---|---|---|
Separate <img> files | One per icon | No | One-off images |
| Inline SVG per use | Zero extra | Yes | A handful of icons |
| Symbol sprite | One total | Yes | A full icon set |
Common mistakes to avoid
- Stripping the viewBox during optimisation — some SVG optimisers do this by default, and it breaks scaling.
- Leaving
widthandheightattributes on the symbols, which fight the CSS sizing you apply at the use site. - Referencing an external sprite from a CDN on another origin, then wondering why nothing renders.
- Including a 200-icon sprite inline on every page when the page uses six of them.
- Forgetting
aria-hidden="true"on decorative icons, so screen readers announce meaningless graphics.
How to do it with SVG Sprite Generator
The SVG Sprite Generator merges the files and handles the parts that break sprites, all in your browser.
- Add the icons that belong in one set — same grid size gives the cleanest result.
- Set an ID prefix so sprite IDs can’t collide with anything else on the page.
- Choose
currentColorif the icons should inherit text colour. - Copy the sprite into your layout, and use the generated
<use>snippet to reference each icon. - Add
aria-hidden="true"to decorative icons and a<title>inside meaningful ones.
The MDN reference on <use> covers the referencing rules, including the same-origin requirement. Other design and asset tools are in the tools directory.
Frequently asked questions
Inline sprite or external file?
Inline avoids an extra request and works everywhere, including cross-origin situations that break external references. An external file caches across pages, which matters on a large multi-page site — but it must be served from the same origin.
Why must each symbol keep its viewBox?
Because the viewBox defines the coordinate system the icon is drawn in, and that’s what allows it to scale to any size. Without it the browser has no mapping between the path data and the box you gave it.
Can I still use multi-colour icons?
Yes — leave their original fills in place. They won’t respond to currentColor, which is correct for a flag or a logo. Mixing both kinds in one sprite is fine.
Final thought
If a sprite icon renders at the wrong size, check the viewBox before you touch the CSS. It’s the cause nine times out of ten, and no amount of styling will fix it.