Short Answer
Visually hidden text is still the most robust way to ensure link text is read out.
There are other ways of doing this that are neater such as using the alt
attribute on an external image or aria-labelledby
on an inline SVG so I have included those in the answer below.
Long Answer
Most modern screen readers will not have a problem with this (NVDA and JAWS both read the title text in my quick test) but some older ones (including old versions of NVDA, JAWs etc.) will not work.
I believe that the comment that "desc" is the equivalent of "alt" is not correct as I explained in this answer on title vs description on SVG (the first three lines are relevant).
To further expand on this here is what the W3C says about SVGs in the proposed spec update:-
The ‘title’ child element represents a short text alternative for the
element.
On a link, this could be the title or a description of the target
resource; on an image or drawing object, it could be a short
description of the graphic; on interactive content, it could be a
label for, or instructions for, use of the element; and so forth.
source: https://www.w3.org/TR/SVG2/struct.html#TitleElement
The ‘desc’ element represents more detailed textual information for
the element such as a description. This is typically exposed to
assistive technologies to provide more detailed information, such as a
description of the visual appearance of a graphic or help to explain
the functionality of a complex widget. It is not typically available
to other users, so should not be used for essential instructions.
source: https://www.w3.org/TR/SVG2/struct.html#DescElement
External SVGs
For external SVG files the recommended way to ensure text is read is to use alt
tags. This may mean slight duplication but alt attributes work back to ie4!
Keep your title
attribute as if someone accesses the image directly they will still get some description of what the image contains.
Inline SVGs
For this you should give your title
an ID. Then add aria-labelledby
to the surrounding link. As stated in the question I linked you can also give the <description>
an ID and link both of them if you wish.
The downside is that aria-labelledby
is not as well supported as you might think, but it is perfectly valid and passes WCAG recommendations.
<a href="/fern">
<svg role="img" viewBox="0 0 100 100" aria-labelledby="linkText">
<title id="linkText">Bracken</title>
<use xlink:href="/ferns_sprite.svg#bracken"></use>
</svg>
</a>
The most robust way - visually hidden text.
The above two ways of doing this are correct, but if you support Internet Explorer (which you should if you care about accessibility as usage of IE is higher in the screen reader community) then the most robust way is still visually hidden text.
Visually hidden text is not visible on the screen but will still be read by a screen reader.
Please use the CSS class below to hide text as it has better compatibility than bootstrap sr-only class as explained in this answer I gave.
Notice how I completely hide the SVG in both circumstances using aria-hidden="true"
and also add focusable="false"
on the inline SVG due to Internet Explorer and older Opera browsers making SVGs interactive. The empty alt=""
is still required as a fallback for screen readers that don't fully support aria
.
The below should work all the way back to IE6 and with the CSS class provided should hopefully work for several years to come!
.visually-hidden {
border: 0;
padding: 0;
margin: 0;
position: absolute !important;
height: 1px;
width: 1px;
overflow: hidden;
clip: rect(1px 1px 1px 1px); /* IE6, IE7 - a 0 height clip, off to the bottom right of the visible 1px box */
clip: rect(1px, 1px, 1px, 1px); /*maybe deprecated but we need to support legacy browsers */
clip-path: inset(50%); /*modern browsers, clip-path works inwards from each corner*/
white-space: nowrap; /* added line to stop words getting smushed together (as they go onto seperate lines and some screen readers do not understand line feeds as a space */
}
<a href="/fern">
<span class="visually-hidden">Bracken</span>
<svg role="img" viewBox="0 0 100 100" aria-hidden="true" focusable="false">
<title>Bracken</title>
<use xlink:href="/ferns_sprite.svg#bracken"></use>
</svg>
</a>
<a href="/fern">
<span class="visually-hidden">Bracken</span>
<img src="/bracken" alt="" aria-hidden="true" />
</a>