Entry

Best practice techniques for SVG Icons

Here’s how I’d handle various common SVG icon scenarios with accessibility in mind.

Just an icon #

So this is an icon that’s not within a link or button and has no adjacent text. This might be, for example, an upward-pointing arrow icon in a <td> in a “league table” where the arrow is intended to indicate a trend such as “The figure has increased” or “Moving up the table”.

The point here is that in this scenario the SVG is content rather than decoration.

<svg 
role="img"
focusable="false"
aria-labelledby="arrow-title"
>

<title id="arrow-title">Balance has increased</title>
<path >…</path
</svg>

Note: Fizz Studio’s article Reliable valid SVG accessibility suggests that the addition of aria-labelledby pointing to an id for the <title> (as Léonie originally recommended) is no longer necessary. That’s encouraging, but as it does no harm to keep it I think I’ll continue to include it for the moment.

The same article also offers that maybe we should not use the SVG <title> element (and use aria-label to provide an accessible name instead) due to the fact that it leads to a potentially undesirable tooltip, much like the HTML title attribute does. To be honest I’m OK with this and don’t see it as a problem, and as I mention later have heard probably even more problematic things about aria-label so will stick with <title>.

Button (or link) with icon plus text #

This is easy. Hide the icon from Assistive Technology using aria-hidden to avoid unnecessary repetition and rely on the text as the accessible name for the button or link.

<button>
<svg aria-hidden="true" focusable="false" ><!--...--></svg>
Search
</button>

<a href="/search">
<svg aria-hidden="true" focusable="false"><!--...--></svg>
Search
</a>

Button (or link) with icon alone #

In this case the design spec is for a button with no accompanying text, therefore we must add the accessible name for Assistive Technologies ourselves.

<button>
<svg focusable="false" aria-hidden="true"><!--...--></svg>
<span class="visually-hidden">Search</span>
</button>

<a href="/search">
<svg focusable="false" aria-hidden="true"><!--...--></svg>
<span class="visually-hidden">Search</span>
</a>

The reason I use text that’s visually-hidden using CSS for the accessible name rather than adding aria-label on the button or link is because I’ve heard that the former option is more reliable. In greater detail: aria-label is announced inconsistently and not always translated.

References #

External Link Bookmark Note Entry Search