Switching to an SVG workflow

The benefits of a vector-based icon sprite system

SVG (Scalable Vector Graphics) in the browser have been around for a while now, we have regularly used them for inline images such as logos or feature illustrations.

A fallback for legacy browsers is straight forward. A javascript function along with a Modernizr test simply replaces the path for a png equivalent:

if (!Modernizr.svg) {
$(’.js-svg-replace[src$=”.svg”]’).each(function (index, e) {
e.src = e.src.replace(’.svg’, ‘.png’);

For browsers without JS support a <noscript> tag will display the fallback png – a straightforward process for content images.

Icon sprite sheets

For a long time we have been using a tried and tested bitmap sprite sheet method for icons and other UI signposting. A relatively simple process which requires minimal browser testing and no need for fallbacks or browser polyfills to function.

Our sprite sheet consisted of a single, organised PSD file containing vector shapes. This would be manually resized and versions saved out for regular and high DPI (retina) devices. Sprites would be added to the markup as pseudo elements in the CSS through a simple SASS mixin.

@mixin icon() {
content: ‘’;
display: inline-block;
background: url(’../img/icon-sprite.png’) 0 0 no-repeat;
@media (-o-min-device-pixel-ratio: 5/4), (-webkit-min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) {
background-image: url(’../img/retina/icon-sprite.png’);
background-size: 1000px 150px;

Adding a new sprite would involve placing it in the PSD, saving out at the 2 sizes, running the files through a compressor, measuring the X + Y coordinates and adding them to the stylesheet as a new class. A reasonably laborious task but quite straight forward.

It did however have some quite significant drawbacks…

File versioning

Git merge conflicts became more common, especially in our larger projects which often have many concurrent development branches. Sprites would be added in the same location on different branches and fixing the conflicts would be a slow, manual process.

Sprite resizing

Although a bitmap image is able to give pixel-level control on what is presented in the browser you are limited to the single display size defined in the image. Zoom into a page and all the icons become pixelated. If an icon needs to be displayed at a new size elsewhere on the page this new size needs to be added as a separate sprite image. Rollover states suffer the same outcome, new sprites have to be made, and CSS hover fades are very tricky to implement.

When creating a new version of our front-end framework we decided it was time to ditch our old methods and use a more modern SVG based icon workflow.

Icon Fonts?

We use a custom font icon system in some of our custom admin interfaces but I’ve never been comfortable using icon fonts in public facing sites. Aside from accessibility issues its difficult to get them to display crisp at specific pixel sizes and updating the font itself is more of a hassle than our bitmap sprite sheets.

Deciding on an SVG Icon System

I was initially hoping that our sprite sheet could just be replaced with a similar generated SVG file and the same CSS offsetting would be used to display on the page. After much trial and error this turned out to be an unrealistic goal, custom SVG viewbox modifications are ignored by many versions of Safari and you lose the ability to resize, colour and add hover effects.

The technique that is increasingly becoming the ‘standard’ is to group all the icons into a single svg containing a set of id designated symbols. We do this using the svg-store gulp package which results in an SVG like this:

<symbol id=“icon-padlock” viewBox=“0 0 44 44”>
<path d=”...”“/>

You can then reference each symbol in your markup with a href:

<svg class=“svg-icon” aria-label=“Locked Icon”>
<use xmlns:xlink=“http://www.w3.org/1999/xlink” xlink:href=”#icon-padlock”></use>

There are a few methods for adding this source SVG to your page. Inlining the SVG into the page seemed like the most performant solution for us, you lose the benefits of a cached external file but it removes an additional HTTP request on the page.

Legacy Browsers

Unfortunately browser support below ie10 isn’t great and we’re yet to find a fallback that is easy to implement and maintain. We’re firm believers in ‘progressive enhancement’ – so for the majority of our sites as long as the site still functions well and is accessible to all we can live a slightly reduced experience for a small percentage of users.

Beautiful icons at all screen sizes

The initial set up took some time and we’ve had to work out a few issues with display ratios and positioning but now our site icons are really easy to maintain and look great at all sizes on all devices.

Let's work together

From website design to online software development, our Bristol-based agency delivers digital solutions that can transform your business.

Contact us today to find out more.