Implementing an SVG Icon System

In the last few months, SVG has started to once again gain traction in the world of front end development1, thanks in part to the amazing work of some very smart people. For some time now, I’ve wanted a way to replace icon fonts with more a semantic, accessible and performant solution while maintaining the resolution independence and ease of use that comes with using them. I’ve been exploring the world of SVG and trying to find a solution that is easy to implement & maintain, light, and cross-browser compatible.

I’m writing with regards to using SVGs to create an icon system; more specifically, displaying multiple icons that serve as both decoration and as content images to be used in all areas of a website (global elements or otherwise).

Here are all the ways I explored implementing SVGs and a pros/cons list for each. This is by no means exhaustive; rather, it’s a high-level summary of the positives and negatives I personally encountered:

  • CSS sprite #
  • Background image
    • path #
    • data uri, embed svg #
    • data uri #
  • <use> #
  • <img> #
  • Icon Packs #

TL;DR

  • There is no one size fits all solution
  • I’d almost always stay away from base64 encoded SVGs in your CSS
  • If you care most about:
    • ease of implementation & maintainability: choose background image (path) or <img>
    • performance: choose sprite or background-image (embed)
    • interaction: choose <use> or background-image (embed)

CSS sprite

Pros

  • Single HTTP request
  • Can be sized using background-size
  • Easy to add to markup
    (<i class="icon icon--feed"></i>)

Cons

  • No control over interaction states (unless you duplicate the icon, change the attributes & add more selectors)
  • Only feasible way to add/edit icons is with a build tool to generate background-position values
  • If resizing with background-size, background-position needs updated too

See the Pen Implementing SVG - CSS Sprite by Damon Bauer (@damonbauer) on CodePen.

Background Image (Path)

Pros

  • Can be sized using background-size
  • Easy to add to markup
    (<i class="icon icon--feed"></i>)

Cons

  • Multiple HTTP requests
  • No control over interaction states

See the Pen Implementing SVG - Background Image by Damon Bauer (@damonbauer) on CodePen.

Background Image - Data Uri (Embed SVG)

Pros

  • Reduced HTTP requests
  • Easy to add to markup
    (<i class="icon icon--feed"></i>)

Cons

  • Leads to larger CSS files because you can only change SVG attributes by duplicating selector & svg
  • IE doesn’t have the best support (> IE9?)

See the Pen Implementing SVG - Embed SVG by Damon Bauer (@damonbauer) on CodePen.

Background Image - Data Uri (Base 64)

Pros

  • Reduced HTTP requests
  • Simple to add to existing selectors or to markup (<i class="icon icon--feed"></i>)

Cons

  • Bad for Performance
  • Leads to larger CSS files because you can only change SVG attributes by duplicating selector & svg
  • Creates illegible & unmaintainable CSS

See the Pen Implementing SVG - Base 64 SVG by Damon Bauer (@damonbauer) on CodePen.

SVG <use>

Pros

  • All svg shapes in one central location
  • Easy to style; you can access the different parts of the svg (e.g. path) and modify attributes (e.g. fill, stroke)

Cons

  • Requires more markup to display:
    <svg><use xlink:href="#icon--feed" /></svg>
  • Duplicated svg block on every page load, not the best in regards to performance2

See the Pen Implementing SVG - SVG Use by Damon Bauer (@damonbauer) on CodePen.

<img>

Pros

  • Easy to include
  • Can be resized easily

Cons

  • Each <img> adds an HTTP request
  • Can’t modify styles

See the Pen Implementing SVG - Image Tag by Damon Bauer (@damonbauer) on CodePen.

Icon Packs (e.g. Iconic, Evil Icons)

“Off the shelf” icon packs are starting to become more popular, and for good reason. These authors have put lots of time and effort creating some wonderful products that are easy to use and are well supported in most browsers.

If you do decide to use an icon pack, be sure to take a critical look at your site’s performance. Most of the icon packs I researched required JavaScript to create an Ajax request for every icon on a page. In my opinion, the benefit of easier development is not worth the extra HTTP requests and a momentary flash of the icons loading. I personally do not like having to use JavaScript just to load icons.

The Truth of the Matter

Perhaps the most important thing I learned while investigating these various options is that there are trade offs and sacrifices that you will have to make. No single solution is perfect, nor is one solution the best in every scenario. You have to determine what’s most important to you (e.g., performance, maintainability, browser support, level of interactivity), and decide which implementation you should pursue.

In my quest to replace icon fonts, I went followed down the CSS sprite path the furthest. The system I came up with was brittle, hard to work with and ultimately too complex to maintain long term. I ended up sticking with icon fonts for the time being.


  1. Google Trends showing fall and rise of SVG searches
  2. Unless you Ajax the block of SVG onto the page. However, doing so suffers from cross browser inconsistencies and requires JS for loading icons. Requires CORS to be set up properly if serving from a CDN.