James Doc avatar

James Doc

Inlining SVG in CSS as a background image

In a recent project, in an effort to reduce HTTP requests, I have been inlining various icons into my CSS via base64 encoding. It is really handy if you have a couple of icons that you need everywhere, e.g. a search or menu icon.

.menu { background-image: url(‘data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAANCAYAAACgu+4kAAAAMElEQVQoz2MQZGDgJxczMDCwM4jxc/4nF4vwcdQziPJzfqAAlzMMPBgNxNFABAYiABBtcJ/dF5gEAAAAAElFTkSuQmCC’);
}

This is great, however using SVG is so much better than PNG, with the various screen sizes and pixel densities using PNGs basically means that you are going to end up with blurry icons. The technique that I had been using was similar however linked out to the SVG file:

.menu { background-image: url(‘menu icon.svg’);
}

This works, however for each icon a new HTTP request, something to avoid.

The recent discovery is that you can put in SVGs directly into the url attribute of the CSS background-image property:

.menu { background-image: url(‘data:image/svg+xml;utf8,<svg xmlns=“http://www.w3.org/2000/svg” height=“13px” width=“16px” version=“1.1” xmlns:xlink=“http://www.w3.org/1999/xlink” viewBox=“0 0 16 13”><g stroke=“#160F09” stroke-linecap=“square” stroke-width=“2”><path d=“m0.5 1h13.5”/><path d=“m0.5 11h13.5”/><path d=“m0.5 6h13.5”/></g></svg>’);
}

The thing that got me stumped for far too long was that this was working perfectly in WebKit browsers (Chrome, Safari, Opera, etc) but in Firefox you got no icons. Turns out that you need to URL encode certain things for this to work. Specifically with hex colours turning the # to %23 made this a whole lot better.

I’ve yet to work out how to solve this issue in Internet Explorer though

Thanks to Rab Nawaz answer to the Inline SVG in CSS question on StackOverflow for helping me solve my FireFox quandary.

Recent entries...