This article originally appeared on .Net magazine, March 2016 Issue

by Shehzad Azram

Things have come a long way from using plain images as icons. Yet many users still face accessibility problems – 280 million according to WHO. It’s imperative to take users’ needs into consideration when designing your site.

Let’s take you through a brief history of icons to understand how things have moved along. Before the advent of CSS, people used images to create icons which gave rise to issues around accessibility and semantics. Each icon may have required a number of images for hover states, colours and sizes. The number of icons used increased HTTP requests therefore increasing the time it took to load the page. This also had an affect whilst re-designing the site as you would need new images built which was an overhead in terms of cost and time.

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 leading to faster page loads. This also improved accessibility because readers were able to ignore the icons, if they were for decoration purposes only, as there was no markup on the page. The main problem with this approach was that changing icons was a cumbersome process especially if you needed a different colour or resolution; in this case you needed a separate image for each one which would increase the size of the sprite and take up design time and then perhaps changing the style might have been painful too as you would have had to change background-position.

Then came icon fonts which were vector based and therefore resolution independent, and could be manipulated through CSS i.e. their colour or position. To make these accessible you must include some extra code that browsers would ignore but readers would not. But this doesn’t solve the problem if users use their own CSS with a different font, which would show a different icon, making it hard for users to interact with the site. Also if the font rendering failed, you would not get the icon but instead something like a square box which would mean nothing to the screen readers and indeed anyone browsing the site. Using unicode characters also provided challenges if you used unicode that was used by someone else thereby potentially displaying a different icon. The icon designs were itself minimalist and didn’t look good on retina displays or scale well despite being vector graphics.

SVG Icons font not rendered

How font icons look when font isn’t rendered properly

SVG Icons

How previous image should have looked

 And now we are in the era of Scalable Vector Graphics (SVG). This is an XML markup language for describing two-dimensional vector graphics. So you can create graphics using code. Don’t worry though, you don’t have to write code; instead you can use software such as Adobe illustrator to create graphics which can be saved as SVGs which you can then embed in your pages. The end result is the same, you get icons or images.

The uptake of SVG based icons is improving as is the browser support. SVGs like font icons are vector based but unlike font icons, you don’t have to do any workaround to make them more accessible as they already contain semantic elements e.g. title & description attributes. So why should we use them over font icons? They scale to any size without losing detail, they also look great on retina displays. You get more control over your icons, including animation, more CSS properties, the ability to produce multi-coloured icons and they also scale better. They still suffer from the same problem as font icons in that older browsers do not support them so we need to use few tricks to get around this issue. On the plus side, they have more CSS properties which allow designers/developers to have more control over them. some examples include targeting stroke width & colour, targeting different section of the SVG icons individually so having multi-coloured icons which was not possible to do with pure CSS and font-icons.

glyph fallback

 

Multicoloured images Apple logo

 

How to implement them:

Having looked at the background to the issues surrounding accessibility with icons, the question arises as to how SVG icons can best be implemented. There are a few caveats to be aware of when using SVGs. When you create icons in Illustrator, you should use simple keystrokes as opposed to paths as this will lead to less code being produced and when saving you should make sure that you save only the icon(s) and not the whole drawing board/canvas.

Once you have saved all the icons, you may want to combine them all into a sprite. While these are similar to the sprite sheets used with the PNG sprite sheets of old you can now reference each icon by an ID, rather than having to keep track of the position of each icon on the sheet.

While doing all this manually can be a tedious process, you can use automation tools such as gulp or grunt to automate the whole process of converting SVGs into sprites, creating PNG fallbacks for browsers which do not support them, such as IE8, or older Android devices and also creating supporting CSS files. Additionally to be able to style the SVGs, changing colour in CSS, the SVG code needs to be included in the HTML body of the page, so it is worth setting up an include to bring this in automatically.

So a workflow would look something like this:

Create SVG icons in illustrator. Remember to use simple strokes to save space.

  • Save them (as SVGs) so that only icons are saved (and not the whole drawing board/canvas)
  • Go to Objects -> Artboards -> Fit to Artwork Bounds. Remember to manually adjust this if there are strokes outside of the icon i.e. if the icon is not contained within perfect square/rectangle etc.
  • Make all fills pure black and strokes transparent. Otherwise we won’t be able to use fill CSS property as the icon will have an inline fill attribute which we won’t be able to override via CSS.
  • Clean them up to remove Adobe Illustrator excess text that is not needed with the use of gulp/grunt tasks
  • You can use something like svgo (link in reference) but be careful it might also remove some information needed for CSS.
  • Create PNG fallback (optional and only if you want to support old browsers)
  • Use javascript to check whether the browser supports SVG if not, replace these with the fallback PNGs. (There is a link to sample Javascript function in reference section)
  • Include SVG icons in your pages at the top of the page (using a server side language like PHP, Python etc)
  • You might have to change/add title/desc attributes if they weren’t put in automatically to make sure SVG icons are accessible.
  • Style the icons using CSS. You have bit more flexibility as mentioned previously.
  • Remember to style the SVG using the id of the <g> tag i.e if your symbol is
    <g id=“#arrow-drop-down”…>

You should use #arrow-drop-down { } to target the icon using CSS.

It looks like there is a lot of work to do each time, but thankfully almost all of this can be reduced to just saving SVGs in particular folder and have automated tools take care of the rest including the creation of fallback PNGs with sprites, CSS to use & minifying images. Here are some of the plugins for each automated tool (grunt and gulp) that are useful but there are lots more available on the internet.

Grunt Gulp
grunt-iconizr gulp-svg2png
grunt-svg-sprite gulp-svg-symbols.
gulp-svg-sprite
grunt-svgmin gulp-svgmin

grunt-iconizr is a powerful plugin that can create a CSS icon kit from SVG and serve them as SVG or PNG sprite with CSS/SASS/LESS. grunt-svg-sprite as the name suggests creates sprites for SVG. grunt-svgmin is useful to strip any excess info from SVGs to reduce their file size.

SVG sprite

SVG sprite

gulp-svg2png as name suggest convert svgs to pngs, and gulp-svg-symbols converts svgs files into a single svgs file as a symbol.

To use these tools you need to install NodeJS, either grunt or gulp and then create a bit of code in Javascript that uses aforementioned plugins. This means you should be comfortable working in javascript and command line. Having said that you can follow guidelines provided in the resource section as well as copy & paste most of the code to create gulp or grunt files. You will of course have to change directory paths to suit your own needs. You may also want to define another task called watch using plugins gulp-watch or grunt-contrib-watch. This will watch for any changes you make into directories and automatically create new sprites, fallback PNGs and CSS should you add more SVGs in the future.

So hopefully, you now have got a basic idea on why we should be using SVGs and how to use them and any caveats that need to be followed. Please check the Reference section for some more resources that will help you automate your work flow and give some more detailed information on hows and whys of the SVG. It is important to remember that it may take a bit of time to get used to a new work flow especially if you are working in a big team and everyone is accustomed to using font icons. It is also important to remember that due to time constraints and having to support old browsers, you may choose not to use SVG icons but you could certainly experiment with them in a smaller or personal project before introducing them to your company and/or team.

Making your current font-icons accessible

As mentioned font-icons on their own are not really accessible in both old and some new browsers especially mobile browsers such as Opera Mini, Blackberry etc do not support @font-face and with these browsers serving at least 370 million users worldwide, it is imperative that we address the issues if we are to use font icons.

If your site is already in production or you support older browsers then it may not be wise to use SVG icons yet due to timings or the time it takes to get accustomed to a change in your workflow. So you can do the following techniques to make sure your icons are accessible and render properly in previously mentioned problematic browsers.

Most popular libraries use :before or :after CSS to include icons. The screen readers will read them even though its in unicode! To solve this, we have to add these icons using spans, and then add the aria-hidden=true so that they are not readable.

In the event of no @font-face support, we can fall back to text, png or to another glyph. You can include whichever option you want to go for into your code hiding these by default and only showing them when relevant. This technique uses modernizr to detect font-face fupport and afontgarde.

Glyph Fallback

Glyph Fallback

 

 Image Fallback

Image Fallback

Be sure to look at further reading list for a link to further explanation.

 


 

References:

Here are some resources you can go to for help with creating SVG Icons. If you are brand new to using automation like Grunt or Gulp head to https://nodejs.org/en/ to install Node and then to http://gulpjs.com/ or http://gruntjs.com/ to install either Grunt or Gulp.

If you need SVG images visit https://www.svgimages.com/ or https://icomoon.io/ where you can download SVGs icons but be prepared to pay for these, although you can sometimes find free versions.

Here is an article to help you with modifying font icons to improve accessibility and other issues:https://www.filamentgroup.com/lab/bulletproof_icon_fonts.html

Here are a few links to repositories that will help you automate your own task flow should you wish to use SVGs: http://lukewhitehouse.co.uk/blog/svg-icon-workflow/ and http://wearejh.com/design/svg-icon-sprites-optimized-workflow/ https://github.com/lukewhitehouse/svg-icon-workflow . The first link also has a javascript code towards the end of the page that should help you turn your SVGs into PNGs for browsers who do not support SVGs. Here is a really detailed guide https://svgontheweb.com/ that will be useful. 

Finally here is a way to bullet proof your font icons reliably. https://github.com/filamentgroup/a-font-garde. This gives a detail guide on how to provide fall back in case of no @font-face support.