Using custom elements for better SVG Icon Sprites

Yes. There are many awesome things you can do with SVG. But this article is about SVG Icons and what makes them awesome.

I'm going to present a new method for consuming SVG icons that will finally make using them a pleasant experience. By the end, I hope to convince you to use SVG icons for your next major project.

Its going to look like this when we're finally done:

<svg-icon type="like"></svg-icon>

But first, lets quickly review the different ways we can get icons on our page:

PNG Icons

These are boring. They're literally images. You need a different icon for every screen resolution if you don't want it to look like what your grandmother saw that time she tried to drive without her glasses. Want it to be blue instead of black? Load another asset. Red? Another asset. Sprite the icons so you can get them all in a single network request? What a pain. Want some type of hover or active animation? Fahgeddabout it.

This just will not do — lets move on.

Icon Fonts

Now we're talking! These are vectors and we can change their colors on the fly with CSS! Okay, lets make the outside of my icon light-gray, the inside red, and . . . wait. We can't do that? Okay, thats fine; I didn't really want all those colors anyway. Lets just make the that one part move a little when you hover over it . . . what? Oh, we can't do that either. Its also a pain-in-the-ass to modify these font files.

Well dang, I was almost sold on that one.

SVG Icons

SVGs are amazing. They enable you to create just about anything you can imagine a vector graphic doing:

  • Scalable & Resolution-Independent
  • Solid Browser Support
  • Accessible by Default (its just markup after all)
  • Smaller File Sizes than JPEG and/or PNG
  • Built-in Graphics Effects
  • Interactive & Styleable
  • CSS Animatable
  • Easily Modified
  • & More

It's the image format that you love to hate and hate to love. It's complexity is both confounding and empowering. By the time you've finished optimizing, animating and fine-tuning your image, your computer has nearly taken a trip out the window. Twice. But by the end, you come out the other side with a beautiful asset that you can hardly believe you brought into this world with your own two hands.

Now you just have to get it embedded on your page.

Why SVG Icons Suck

There are umpteen different articles out there about SVG and SVG spriting techniques. Oh look, I found one: SVG Sprite Creation.

Since I provided you that link to Sara Soueidan's wonderful post, which in turn links off to a bunch of other SVG related resources – I'm going to move forward assuming you have some knowledge of SVG Basics, what an SVG sprite is, how to style and embed SVGs, and how <g>, <defs>, <symbol>, and <use> elements work.

Now that you're ready, lets go down the rabbit hole! You have your SVG icons. You've even stuck them all together into an SVG sprite. Good to go, right?! Not so fast speedy – you need to choose how to include them now. There are many fun ways to add SVG to your page, but not all are suited for icons.

If you're anything like me, you like flexability. So what possible use cases can we think of concerning an icon library? Heres what I want:

  • Hey icon! Be this color! (Custom Styling)
  • Okay! Now jump up and down every 1.5s! (CSS Animations)
  • Good boy! Now when I hover over you, do a fun little animation thing! (CSS Interactions)

Now, what you need to know about those methods for including SVG on your page (from those links above that you definitely read), is that every one offers slightly different support for each of these three criteria. They are either Fully Supported, Supported Internally in the external SVG file itself (the parent page has no control), or Not Supported by the method at all:

Method Custom Styling CSS Animations CSS Interactions
<img src="icon.svg"/> No Internal No
.el {background: url(icon.svg);} No Internal No
<object data="icon.svg"></object> No Internal Internal
<embed src="icon.svg" /> No Internal Internal
<iframe src="icon.svg"></iframe> No Internal Internal
<use xlink:href="#icon"/>* No (ish) Internal (ish) Yes (ish)
<svg><path d="..."/></svg> Yes Yes Yes

* <use> tags are plagued with terrible browser support making more advanced features almost unusable

Hey look! Something there fits Exactly What I Want! Inline SVG is the only option that gives us the level of control that makes SVG icons worth using. Thats great! Except for two little things:

  1. Any chance of caching icons is out the window because every icon is hard coded into our HTML.
  2. We need to find a way, either server side or client side, to get those SVGs into the DOM, which means extra magic to manage in our templates.

Oh what is a poor web dev to do? There must be way to make this work! What if I told you that there is?

Hold on tight — We're trying something new.