Would you suggest icon fonts or inline SVGs for a complex single page application? And are there specific accessibility concerns for either? Accessibility is especially important for us because schools use our products. I ask because we are currently in the process of unifying and setting up an icon system.
I don’t think I would make the choice based on what “kind” of website I was building, so let’s ignore that part of it.
I also think SVG icon systems are just better than icon fonts, so let’s assume that.
The accessibility question is the interesting bit, so let’s cover that.
There are two ways an icon might be used:
Standalone: icon needs to convey meaning all by itself
Decorative: icon is just visual sugar – the words around it convey the meaning.
<!-- role="img" so that the SVG is not traversed by browsers that map the SVG to the "group" role --> <!-- aria-labelledby pointing to ID's of title and desc because some browsers incorrectly don't use them unless we do --> <!-- if you are using a <use>-based icon system, this would be a <symbol id="unique-id"> below, but otherwise the same --> <svg role="img" viewBox="0 0 100 100" aria-labelledby="unique-title-id unique-desc-id"> <!-- title becomes the tooltip as well as what is read to assistive technology --> <!-- must be the first child! --> <title id="unique-title-id">Short Title (e.g. Add to Cart)</title> <!-- longer description if needed --> <desc id="unique-desc-id">A friendly looking cartoon cart icon with blinking eyes.</desc> <!-- all the SVG drawing stuff --> <path d="..." /> </svg>
Pattern for Decorative Icons
Remember the idea with a decorative icon is that if it wasn’t there at all, it wouldn’t matter. So, we hide it from AT:
<button> <svg aria-hidden="true" viewBox="0 0 100 100"> <!-- or <use>, if using a <symbol>-based icon system --> <path d="..." /> </svg> Add to Cart </button>
But… icons might be used either way.
Right. So you probably should prepare your icons such that they are ready to be used as standalone, meaningful icons. Then, if they are used in a decorative context, slap aria-hidden="true" on the <svg>.
So your icon system might manifest like…
<Icon icon="icon-cart.svg" standalone="true" />
<?php $ standalone = false; include("icon-cart.php"); // SVG with PHP logic sprinkled in ?>
Now the icon itself is hidden (because it uses a weird meaningless font), but there is real text there that can be read as expected by AT. You can hide the text visually as well. Assuming you have some feature testing in place here’s the CSS that hides/shows as needed: