(as a reply to: https://css-tricks.com/svg-use-with-external-reference-take-2/)
While I love SVG (sprites) there are a lot of issues to take into account.
UPDATE: you should take a look at https://dl.dropboxusercontent.com/u/145744/accessible-svg-icon/test.html which seems a simpler and more robust approach
Another thing: since people copy-paste our code examples it would be great if we could advocate the most robust and accessible markup IMO. I am no a11y expert, but in my understanding we could/should take some extra steps to make out SVG sprite icons more accessible.
Below my current thinking, I would love an a11y expert's advice on this!
First: make a distinction between 'presentational' and 'content' icons. Just as we would with img
and their alt
attributes.
For all SVG Icon sprites (in sprite.svg
):
- Add a
title
element child to the sprite'ssymbol
- Add a
desc
element child to the sprite'ssymbol
<symbol id="left-arrow">
<title>Back</title>
<desc>An arrow pointing left</desc>
<path etc.../>
</symbol>
Now, for use
ing those symbols as purely presentational icons:
- Use
role="presentation"
on the SVG
<svg role="presentation">
<use xlink:href="sprite.svg#left-arrow"/>
</svg>
That's it. But for SVG icons as 'content' we should do more:
- Add
role="img"
- Add a
title
attribute - Add a
title
element with uniqueid
- Add
aria-labelledby="title-id"
<svg role="img" title="Back" aria-labelledby="title-back1">
<title id="title-back1">Back</title>
<use xlink:href="sprite.svg#left-arrow"/>
</svg>
This ensures the best accessibility AFAIK. Again: I am no a11y expert, so please correct me when I'm mistaken.
Thoughts?
- Github: @davidhund
- Twitter: @valuedstandards
Quick results with NVDA and Firefox:
aria-label
attribute is read twice.aria-label
is read (once, or twice if usingrole="img"
.aria-label
on parent element works well, including for a<span>
(for the record, in my tests JAWS and VoiceOver wouldn't read anything for<span aria-label="…">
), and since we hide the icon itself witharia-hidden="true"
we avoid labels that are read twice.For inline icons:
<text>
element but not the pathsaria-hidden
works well for hiding the iconaria-label
works for reading an accessible label, and it prevents NVDA from reading the text element in the icon (which seems to be what the spec asks for)So the situation with NVDA is pretty good. It will not read
<title>
elements in an external sprite, but providing accessible text witharia-label
works well. If you use botharia-label
androle="img"
it gets a bit verbose, because the label is said twice.