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 to 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.
You can support CSS-Tricks by being an MVP Supporter.