The answer to “What is the most accessible HTML for an SVG icon?” isn’t one-size-fits all, because what an icon needs to do on a website varies. I’m partial to Heather Migliorisi’s research on all this, but I can summarize. Extremely quickly: hide it if it’s decorative, title it if it’s stand-alone, let the link do the work if it’s a link. Here are those three possibilities:
The icon is decorative
As in, the icon is just sitting there looking pretty but it doesn’t matter if it entirely went away. If that’s the case:
<svg aria-hidden="true" ... ></svg>
There’s no need to announce the icon because the label next to it already does the job. So, instead of reading it, we hide it from screen readers. That way, the label does what it’s supposed to do without the SVG stepping on its toes.
The icon is stand-alone
What we mean here is that the icon is unaccompanied by a visible text label, and is a meaningful action trigger on its own. This is a tricky one. It’s gotten better over time, where all you need for modern browsers is:
<svg role="img"><title>Good Label</title> ... </svg>.
This works for an SVG inside a
<button>, say, or if the SVG itself is playing the “button” role.
The icon is wrapped by a link
…and the link is the meaningful action. What’s important is that the link has good text. If the link has visible text, then the icon is decorative. If the SVG is the link where it’s wrapped in an
<a> (rather than am internal-SVG link), then, give it an accessible label, like:
<a href="/" aria-label="Good Label"><svg aria-hidden="true" ... ></svg></a>
…or, have a
<span class="screen-reader-only"> text within the link and the hidden SVG.
I believe this syncs up correctly with advice not only from Heather, but with Sara, Kitty, and Florens as well.
Not sure if someone has tested more recently but using a
<title>element inside an inline SVG messes with Facebook’s crawler for its link previews. This means that when you share a link, the crawler looks for all the
<title>elements on the page and appends it together for the title of its link preview cards, So you could end up with a preview card title of “Acme Website Search our site Facebook Twitter YouTube …” whereby “Acme Website” is the actual title of the webpage in the
<head>but “Search our site Facebook Twitter YouTube …” is from
<title>elements in any SVGs.
From the (admittedly little) I’ve read about accessibility in HTML, I thought the
aria-labeledbyattributes were only really supposed to be used when there wasn’t existing labely text associated with the element in question. I thought that patterns such as
<a href="…" title="Meaningful title"><svg … /></a>and
<button title="Meaningful title"><svg … /></button>were sufficient for those icon-only clickables…?
Using the SVG
<title>isn’t recommended. In addition to the issue Justin mentioned above (which I personally didn’t know about), in my article I also link to an article by my friend Scott O’hara in which he details screen reader support for different labelling techniques. It’s not recommended using the
<title>on the SVG inside a button, but rather use one of the other techniques I’ve outlined in my post. I also have another post related to this topic in the works.
(P.S. Thanks for linking to my post! Heads up: the link on my name links to Heather’s article not mine.)
Is there any difference between:
And why not use
<title>in this case?
In theory they are the same, see https://html5accessibility.com/stuff/2020/11/07/not-so-short-note-on-aria-label-usage-big-table-edition/, but …
… the second form is more verbose in VoiceOver, because SVG with aria-label is announced as a group, so rather go with aria-label on the link.
How to use svg icons inside a input box without using css