The wonders of inline SVG

A while back I switched to using SVG for as many graphical assets as possible. Sometimes of course it doesn't make sense to use SVG – you probably don't want to convert photos to SVG for example. But for the majority of your UI's workhorse graphical assets – things like icons and logos – they are a great fit.

The reason I initially switched was to get rid of the headache of producing multiple assets for different devices, depending on their pixel density. As a vector an SVG will look perfect at any resolution. This makes life a lot easier.

But the real power of SVG comes when you start inlining them, because then you can do all kinds of CSS magic. This first struck me as a bit unnatural – I was used to images being added to the page using <img> elements, and inlining them just wasn't something you did! But when you think about it an SVG is just markup, so it's pretty natural you just inline them instead of adding them via <img> tags.

You can easily hack up some code to inline them in your templates, because it would be crazy to actually copy and paste SVGs into templates all over the place: that is not DRY at all. In my last project I was using middleman and it's actually a piece of piss setting up a helper:

  def inline_svg(filename)
    sprockets[filename].to_s
  end

If you are using Rails the inline_svg gem should do the trick.

So now we can happily inline our SVGs into our templates, and do all kinds of CSS magic. This means you can say goodbye to hover images if you build your SVG in the right way, like in the following example:

The CSS for this is dead simple:

   #example-1:hover circle {
      fill: #fda63b;
   }

If you had multiple circles and wanted just to target a particular one, that's no problem, you can just add an ID or a class and target it like so:

   #example-1:hover #circle {
      fill: #fda63b;
   }

And if we want the B symbol to change colour on hover, no problem:

   #example-2:hover path {
      fill: #fda63b;
   }

Now to be fancy let's animate the transition:

#example-3 * {
     transition: fill 300ms ease;
}

Why would you ever want to go back to PNG?