Who it affects
Someone who is blind, tabbing through an online florist's footer hears link, link, link for the Instagram, Facebook and Pinterest icons and cannot tell them apart.
Someone using voice control (Dragon, or Voice Control on a Mac) has no word to say to open an icon link, so has to fall back to a numbered grid over every clickable thing on the page.
Someone who reads the page through a screen reader's links list sees a list full of empty entries and 'Read more' and has no sense of where any of them lead.
Broken versus fixed
Both examples are live and rendered in a sandboxed frame. The broken one is deliberately broken.
A screen reader announces: link, link, link. Nothing says which one is Instagram and which is Facebook.
Announced: link, Bloom and Stem on Instagram. Then: link, Bloom and Stem on Facebook.
Show the markup behind both examples
<style>body{font-family:system-ui;margin:0;padding:16px;background:#f6f3ee}.social{display:flex;gap:12px;align-items:center}.ico{display:inline-block;width:36px;height:36px;border-radius:50%;background:#8a5a7a}.ico.fb{background:#4a6fa5}.ico.pin{background:#b23a3a}</style>
<p style="margin:0 0 8px"><strong>Bloom and Stem</strong>, florist, Norwich</p>
<div class="social">
<a href="#instagram" class="ico"></a>
<a href="#facebook" class="ico fb"></a>
<a href="#pinterest" class="ico pin"></a>
</div>
<style>body{font-family:system-ui;margin:0;padding:16px;background:#f6f3ee}.social{display:flex;gap:12px;align-items:center}.ico{display:inline-block;width:36px;height:36px;border-radius:50%;background:#8a5a7a}.ico.fb{background:#4a6fa5}.ico.pin{background:#b23a3a}</style>
<p style="margin:0 0 8px"><strong>Bloom and Stem</strong>, florist, Norwich</p>
<div class="social">
<a href="#instagram" class="ico" aria-label="Bloom and Stem on Instagram"></a>
<a href="#facebook" class="ico fb" aria-label="Bloom and Stem on Facebook"></a>
<a href="#pinterest" class="ico pin" aria-label="Bloom and Stem on Pinterest"></a>
</div>
Test it by hand in two minutes
- Press Tab repeatedly through the page. Each time a link gets focus, ask: if I could only hear this link, would I know where it goes?
- Turn on VoiceOver (Cmd+F5 on a Mac), open the rotor with Ctrl+Option+U and choose Links. On Windows, start NVDA and press Insert+F7. Any entry that is blank, or says only 'link', fails.
- Right click an icon link, choose Inspect, and look for text between the a tags, an aria-label, or an img with an alt attribute.
- Read each link's text on its own, away from its sentence. 'Click here' and 'Read more' pass this rule but still fail the person; say where the link goes.
The fix
<a href="https://instagram.com/bloomandstem" class="icon-instagram"></a>
<a href="https://instagram.com/bloomandstem" class="icon-instagram" aria-label="Bloom and Stem on Instagram"></a>
Say where the link goes, in the words a person would use. If it opens a new tab or a PDF, say that too.
Image link
<a href="/bouquets/peony"><img src="peony.jpg" alt=""></a>
<a href="/bouquets/peony"><img src="peony.jpg" alt="Peony bouquet"></a>
When the image is all the link holds, its alt text is the link text. An empty alt leaves the link with no name.
Visually hidden text instead of aria-label
<a href="/basket" class="basket-icon"></a>
<a href="/basket" class="basket-icon"><span class="visually-hidden">Basket, 2 items</span></a>
Hidden text gets translated by browser translation tools and shows up if the CSS fails. Use a clip-based visually-hidden class, never display:none, which hides it from everyone.
Inline SVG inside a link
<a href="/search"><svg viewBox="0 0 24 24"><circle cx="11" cy="11" r="7"/></svg></a>
<a href="/search"><svg viewBox="0 0 24 24" aria-hidden="true" focusable="false"><circle cx="11" cy="11" r="7"/></svg><span class="visually-hidden">Search</span></a>
Hide the drawing and add the words. An SVG title element also works, but hidden text is read more consistently.
Common mistakes
- Relying on the title attribute, which most screen readers skip and touch screen users never see.
- Putting the name in a CSS ::before content string; some screen readers read it, many do not.
- Hiding the text with display:none, which removes it from screen readers as well as the screen.
- Writing the same name, like 'Read more', on ten links that go to ten different places.
- Giving a logo link the alt text 'logo' instead of the company name and where it goes, which is usually home.
WCAG criteria this rule maps to
axe-core tags this rule as WCAG 2.2 level A. It is one of the checks for:
- 2.4.4 Link Purpose (In Context) (level A). Official W3C text.
- 4.1.2 Name, Role, Value (level A). Official W3C text.
The scanner can see that a link has no accessible name from its text, image alt, aria-label or aria-labelledby. It cannot tell whether the name is useful, so a link called 'Click here' passes the rule and still fails the person. Automated tools find only part of the accessibility problems on a page; a pass on this rule is not a pass on the criterion.
Related rules
button-name
A button needs a name that assistive technology can announce.
A
ARIA buttons, links and menu items need a name
aria-command-name
When you give an element role="button", role="link" or role="menuitem", you are promising assistive technology that it is a control.
A
Images must have alternative text
image-alt
Every img element needs an alt attribute.
A
The words on a control must be part of its accessible name
label-content-name-mismatch
People who use voice control activate a control by saying the words they can see on it.