Getting to grips with SVG markup

Here is a side-by-side comparison of an icon. The image on the left is an SVG, the one on the right is a raster PNG. They are both roughly the same file size (~1Kb), and at 64px x 64px they look pretty similar. But see how those same files look at double-scale:

If you're reading this post through some kind of syndication feed (RSS, etc.) you may need to visit the original post to view this image-demo correctly.

An .SVG and .PNG icon, side-by-side

The same files, increased to double-size

...and to 10x the original size

We can use the same SVG file for all sizes, and produce consistently clear and crisp results. To get the same effect with rasterized images, we’d need to create separate files for each size. Each increase in visible size would result in an increase of file size, too. We’d not only be pushing up the number of HTTP requests but also the total page-weight as well.

The basics of the SVG markup language

SVG as a format needn’t be scary or intimidating. SVG stands for Scalable Vector Graphic, and the language of SVGs is an XML-derived language like RSS feeds and XHTML1. Once you know what tags to look out for, the whole thing gets a lot simpler. Take this simplified SVG markup, for example:

<svg viewBox="0 0 100 100">
    <path d="M10 10H90V90H10Z"/>
    <circle cx="50" cy="50" r="40"/>

Even without being able to read the more technical aspects, there are clues to pick up on. It’s clear that the SVG above contains a path (a.k.a. a line) and a circle. Dive a little deeper and you’ll see that it’s a circle inside a square. The circle has a diameter of 80 (“r” == “radius”), and sits inside a 90 x 90 square (the line joins up with itself to form a shape). Both of these lie in the centre of a 100 x 100 artboard (a.k.a “view box”).

Real-world SVGs are more complex, of course. There are plenty of attributes and DOCTYPE declarations to worry about. But the general principle is the same. There is an opening tag (<svg>) and closing tag (</svg>) just like <html>. And we build shapes within the SVG using tags like <path/> and <circle/> and <rect/> (rectangle)2.

Styling SVGs with CSS

SVGs are complex, for sure, but that very complexity gives them their power. And we don’t need to know the intricacies of the co-ordinate system to harness that power. All we need to do is recognize the different elements. This is a language much like HTML, after all, so once we can find the different shapes in an icon we can add classes to them.

<svg viewBox="0 0 100 100">
    <path class="outer_square" d="M10 10H90V90H10Z"/>
    <circle class="inner_circle" cx="50" cy="50" r="40"/>

…which we can then style with CSS:

    background: yellow;
    stroke: red;
    stroke-width: 1px;
    fill: blue;

This gives us a more fine-grained level of control than a single character in an icon font would. We can manipulate the styles of each discrete part of an icon with CSS. Transitions and animations provide an extra level of detail. Our positioning can be much more precise. We have a defined and predictable co-ordinate system to work with. No more fiddling about with baseline alignment of invisible-hitboxed font characters!

There are some fantastically clever and artistic examples of SVG in the wild. The only limits appear to be the creativity and imagination of the developers who build them. A browse through CodePen reveals stunning work, but I’ll end with a more simple demonstration of my work.

I’ve always had a soft-spot for loading graphics, and love to build them myself. I built this one with a two-path SVG and a dash of CSS animation:

See the Pen Hourglass Loader by Tom Hazledine (@tomhazledine) on CodePen.

  1. This is not the place for a debate about the nuances of XHTML vs HTML vs SGML. If that kind of language-geekery is for you, you can learn more about the *ML “family” from Computerphile
  2. You can read more about the inner-workings of SVGs – including a detailed look at how to construct paths using co-ordinates – on the MDN SVG tutorial pages