Skip to main content

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