2.4.9 Level AAA Guideline 2.4 Navigable Added in WCAG 2.0 Partly detectable automatically

Link Purpose (Link Only)

A mechanism is available to identify the purpose of each link from the link text alone, except where the purpose is ambiguous to all users.

Who this affects

Screen reader users navigating by link list, without needing to inspect surrounding context to work out where each link goes.

The failure and the fix

Each example below is a self-contained page, loaded in a frame so its markup cannot affect this page. Open either one on its own to test it with a keyboard or screen reader.

Fails 2.4.9

Open the failing example in a new tab

fail.html — the problem

<h1>Support</h1>

<!-- This page PASSES 2.4.4 Link Purpose (In Context) at Level A: each "Read
     more" sits inside its own list item with a heading, so its purpose can be
     worked out from the programmatically determined context.

     It FAILS 2.4.9 at AAA, which drops the "in context" allowance. The link
     text ALONE must identify the purpose - because that is how a screen reader
     user navigating by link list actually encounters it: stripped of all
     surrounding content. -->
<ul>
  <li>
    <h2>Delivery and collection</h2>
    <p>How long orders take and where to collect them.</p>
    <a href="#a">Read more</a>
  </li>
  <li>
    <h2>Returns</h2>
    <p>Our 30-day returns policy.</p>
    <a href="#b">Read more</a>
  </li>
  <li>
    <h2>Accessibility</h2>
    <p>Step-free access and hearing loops at our shops.</p>
    <a href="#c">Read more</a>
  </li>
</ul>

<p id="a">Delivery.</p><p id="b">Returns.</p><p id="c">Accessibility.</p>

Meets 2.4.9

Open the passing example in a new tab

pass.html — the fix

<h1>Support</h1>

<!-- FIX 1: the heading is the link. The link text alone says where it goes,
     and the target is larger for everyone (2.5.8). -->
<ul>
  <li>
    <h2><a href="#a">Delivery and collection</a></h2>
    <p>How long orders take and where to collect them.</p>
  </li>
  <li>
    <h2><a href="#b">Returns policy</a></h2>
    <p>Our 30-day returns policy.</p>
  </li>
  <li>
    <h2><a href="#c">Accessibility at our shops</a></h2>
    <p>Step-free access and hearing loops.</p>
  </li>
</ul>

<!-- FIX 2: where a design insists on a repeated call to action, extend the
     accessible name with visually hidden text. The visible words must remain
     inside the name so speech-input users can still say them (2.5.3). -->
<p><a href="#a">Read more<span class="visually-hidden"> about delivery and collection</span></a></p>

<!-- Test it the way a screen reader user experiences it: open the rotor or
     press Insert+F7 in NVDA to list every link on the page, and read the list
     with the page hidden. Every entry should make sense on its own.

     The exception: links whose purpose is ambiguous TO ALL USERS are allowed -
     a "random article" link is genuinely unpredictable for everyone, so it
     does not fail. -->

<p id="a">Delivery.</p><p id="b">Returns.</p><p id="c">Accessibility.</p>

How to test it

Read every link's accessible name in isolation. Each must be self-explanatory. "Read more about our refund policy" passes where "Read more" fails.

  • Automated

    Generic link text can be pattern-matched, but the judgement of self-sufficiency is human.

    This demo's failure is not machine-detectable. Every link on the failing page has text, so axe's link-name rule is satisfied. Deciding that "Read more" fails to identify its destination requires reading the page and understanding what each link points at - which is judgement, not pattern matching.

    Relevant axe rules:

    • link-name
  • Keyboard

    Unplug the mouse. Move through the page with Tab, Shift+Tab, Enter, Space and the arrow keys. See the keyboard testing script.

  • Screen reader

    Listen to both examples with NVDA, JAWS, VoiceOver or TalkBack and compare what is announced. See the screen reader cheat sheets.

  • Visual

    Zoom to 200% and 400%, narrow the viewport to 320 px, and apply the text-spacing overrides. See the visual testing procedures.

In the specification