In search of the ideal icon system

Why use an icon system ?

💅Looks
🏃Performance
👨‍💻Maintanability

Different options

  • Individual images (no system)
  • CSS sprites
  • Icon fonts
  • Inline SVG
  • SVG <use>

Spoiler alert

Individual images (no system)

.home {
  background-image: url('../images/icon-home.png');
}
<img src='images/icon-home.png' alt='home'> 
Advantages Disadvantages
Simple to setup / use Has to be adjusted manually
Can be adjusted manually Performance (individual HTTP request for each icon)
Responsiveness / handling of retina screens
Variation = new icon

CSS sprites

.home {
    background-image: url('../images/sprites.png');
    background-position: -5px -143px;
}
Advantages Disadvantages
Performance (single HTTP request) Performance doesn't scale
Responsiveness and retina screens still an issue
Variation = new icon

Icons fonts

[data-icon]:before { 
    font-family: icons;
    content: attr(data-icon);
}
<span data-icon="⇝"></span>
Advantages Disadvantages
Easy control over the size + color Sub-pixel rendering and other visual artifacts
Looks good in any resolution Positioning can require some manual adjustment (line-height, etc)
Lighter / more perfomant than CSS sprites Semantics not ideal

Inline SVG

<svg class="icon icon-home" viewBox="0 0 100 100" aria-labelledby="title">
    <title id="title">Home</title>
    <path d=" ... " />
</svg>
Advantages Disadvantages
Best visual output Browser support (Android 2.3+, IE9+)
Simple to setup Need control over the generated markup (can be a problem with some CMS / WYSWYG editor)
Complete control over icon properties with CSS (inc. over parts of the icon) No central respository of icons = more difficult to maintain / reuse
No extra HTTP request
No flash of unstyled content
Accessibility

Or : SVG component

// Icon
var IconHome = React.createClass({
 render() {
   return (
     <svg className="home" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
	<title>HomeIcon</title>
        <path .../>
      </svg>
   )
 }
});

// which makes this reusable component for other views
<IconHome />

SVG <use>

<svg>
  <defs>

    <symbol id="shape-icon-1">
    </symbol>

    <symbol id="shape-icon-2">
    </symbol>

    <!-- etc -->

  </defs>
</svg>
<svg viewBox="0 0 100 100" class="icon shape-icon-1" aria-labelledby="title">
    <title id="title">Home</title>
  <use xlink:href="#shape-icon-1"></use>
</svg>
Advantages Disadvantages
Best visual output Need control over the generated markup (can be a problem with some CMS / WYSWYG editor)
Performance (single HTTP request, lighter than fonts) Browser support (Edge 13+), requires a polyfill (< 1KB)
Large control over icon properties with CSS (NOT over parts of the icon) Still need to load the whole SVG sprite
Accessibility Shadow DOM weirdness

Some examples from around the web

Thank you

Unicorn by Daniel Hammer from the Noun Project

Made with Slides.com