SVG (Scalable Vector Graphics) in the browser have been around for a while now. At Ember we regularly use them for inline images such as logos or feature illustrations.
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.
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…
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.
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.
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 it’s 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:
You can then reference each symbol in your markup with a href:
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.
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 everything still functions well and is accessible to all then a slightly reduced experience for a small percentage of users is acceptable.
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.