Things have come a long way from the days when we used plain vector art (opens in new tab) images as icons. Yet there are still a number of accessibility issues when it comes to icons. Thankfully, SVGs could go a long way towards addressing this problem.
In this article, I'll take you through the different icon options we have used in the past, then explore the benefits (and drawbacks) of SVG icons. Finally, I'll explain how to implement SVG icons, using automation tools to reduce the workload.
First, let's go through a brief history of icons so you can understand how things have moved on. Before the advent of CSS, people used images to create icons, which gave rise to issues around accessibility and semantics. Each icon would have multiple images to support different states – for example, to show hover states, different colours or sizes.
The number of icons being used increased HTTP requests, and thus also the page load time. If you had to redesign the site, you would need to build a whole new set of images for each icon.
When CSS was introduced, things got better. People became accustomed to using sprites (many images glued together in one big image), resulting in one request. As well as faster page loads, this also improved accessibility.
Readers were able to ignore the icons if they were for decoration purposes only, as there was no markup on the page. However, altering icons remained a cumbersome process – changing the colour or resolution still necessitated the creation of a separate image, which would increase the size of the sprite.
Next came icon fonts. These are vector-based and therefore resolution-independent, and things like colour and position can be manipulated through CSS. They also boast wide-ranging support across all major browsers and versions. However, to make icon fonts accessible you have to include some extra code that browsers ignore but screen readers do not.
There are further problems with this approach. If designers use their own CSS with a different font, a different icon will show. If the font rendering fails, the icon will not display; instead users get something like a square box, which doesn't mean much to anyone.
Relying on CSS font positioning properties like line height and font size can be unintuitive when working with graphical glyphs, particularly when the icons need to align with images and text.
Fundamentally, using fonts to render vector images is a hack to get widespread browser support. However, if for whatever reason SVG icons are not a possibility, see the boxout opposite for a guide to using icon fonts properly.
Finally, along came SVG. These are based on an XML markup language for describing two-dimensional vector graphics, which means you can create graphics using code. Alternatively, if you don't want to write code, you can create graphics using software such as Illustrator, save them as SVGs, and the code will be generated for you.
While SVG has been around since the last century, it took over a decade for Internet Explorer to catch up with v9. With the rapid decline of legacy IE usage, SVG is now a viable solution across the vast majority of browsers and devices.
There are still some older browsers that do not support SVG icons, but there are tricks to get around this. So why should we use them over font icons? SVGs, like font icons, are vector-based.
Unlike font icons, you don't have to use workarounds to make them accessible: they already contain semantic title and description attributes. They scale to any size without losing detail, so look great on HDPI displays.
Having looked at the background to the issues surrounding accessibility with icons, the question arises as to how SVG icons can best be implemented. Let's look at an example workflow. Along the way I'll explain the caveats you should be aware of when using SVGs.
Design icons in illustrator
Start by creating your SVG icons in Illustrator. You should use simple keystrokes as opposed to paths, as this will lead to less code being produced. When saving, make sure you save only the icon, and not the whole drawing board or canvas.
Go to Objects > Artboards > Fit to Artwork Bounds . You'll need to manually adjust this if there are strokes outside the icon (i.e. if the icon is not contained within a perfect square or rectangle). Make all the fills pure black and the strokes transparent. If we don't do this, the icon will have an inline fill attribute that we won't be able to override with the fill CSS property later.
Clean up your icons to remove any excess text from Illustrator that is not required for your gulp or Grunt tasks. For this you can use something like SVGO, but be careful as this might also remove some information needed for CSS.
Once you have saved all the icons, you may want to combine them all into a sprite. While these are similar to the PNG-based sprite sheets of old, you will now be able to reference each icon with an ID, rather than having to keep track of its position on the sheet.
Add PNG fallbacks
At this point you need to consider if you want to cater for those browsers that don't support SVG icons, such as IE8 or older Android devices. If you do, you'll need to create a PNG fallback.
Although it is not possible to change the colour or other properties of PNG icons, this approach should be sufficient for a fallback.
Add the style icons with CSS
Include SVG icons at the top of the page using a server-side language like PHP or Python. You might have to add title and describe attributes if these haven't been put in automatically (or edit them if they are incorrect). This is important to ensure the icons are accessible.
Next style the icons using CSS. As mentioned previously, with SVGs you have bit more flexibility. Remember to style the SVG using the ID of the <g> tag (so if your symbol is <g id="#arrow-drop-down"...> , you should use the ID #arrow-drop-down to target your CSS.
While doing all this manually can be tedious, tools such as gulp and Grunt can help. Through these tools and with the help of plugins, we can automate the process of converting SVGs into sprites, setting up PNG fallbacks and creating supporting CSS files. Here are few plugin options for each step:
- grunt-iconizr: A powerful plugin that can create a CSS icon kit from SVG, and serve it as a SVG or PNG sprite with CSS, Sass or Less
- grunt-svg-sprite / gulp-svg-sprite: As the names suggest, these create sprites for SVG
- grunt-svgmin / gulp-svgmin: This is useful for stripping any excess information from SVGs in order to reduce file size
- gulp-svg2png: Converts SVGs to PNGs
- gulp-svg-symbols: Converts SVGs files into a single SVG file as a symbol
To be able to style the SVGs by changing their colour in CSS, the SVG code needs to be included in the HTML body of the page. It is worth setting up an include to bring this in automatically.
You may also want to define a task called watch using the plugins gulp-watch or grunt-contrib- watch. This will watch for any changes you make in directories and automatically create new sprites, fallback PNGs and CSS, should you want to add more SVGs in the future.
You should now have a basic idea why SVG icons are a good idea, how to implement them, and any particular caveats. Check the reference boxout for further resources that will help you automate your workflow and give some more detailed information on the hows and whys of the SVG.
Remember, it may take some time to get used to a new workflow, especially if you are working in a large team that is accustomed to using font icons. Due to time constraints and having to support old browsers, it may not even be possible for you to use SVG icons.
However, you could certainly experiment with them in a personal project before introducing them to your company and to the team.