Level AAA

At Level AAA, link text must identify the destination on its own -- surrounding sentences, list items, and table cells cannot be used to disambiguate

2.4.9 Link Purpose (Link Only)

In Plain Language

2.4.9 Link Purpose (Link Only)[1] is the Level AAA tightening of 2.4.4 Link Purpose (In Context)[2]. The Level A version lets the surrounding sentence, paragraph, list item, or table cell carry meaning; the Level AAA version does not. Each link's purpose must be determinable from the link text alone -- specifically, from the link's accessible name computed in isolation.

The mechanism to picture: a screen-reader user opens the links list (VoiceOver rotor, NVDA Insert+F7, JAWS links list). The page's prose is gone; each link appears as just its accessible name. A link labelled "annual report" passes 2.4.4 when the sentence around it names the organization and year, and fails 2.4.9 because the links list shows only "annual report" with no way to tell which report it is.

Why It Matters

  • Screen-reader users navigate by links list. The list strips paragraph context, so ambiguous link text that reads fine in flow becomes a series of identical "read more" or "download" entries with no way to distinguish destinations.
  • Voice-control users (Dragon, Voice Control) activate links by speaking the visible text. Duplicate link text forces a disambiguation dialog ("1, 2, 3..."); unique text activates in one command.
  • Sighted users scanning the page also skip between links rather than reading every sentence. Self-contained link text carries meaning to that scan pattern too.
  • 2.4.9 removes the "in context" escape hatch from 2.4.4[2]. At Level A, a devloper can point at the enclosing sentence and say "it's clear from context." At Level AAA, that argument is not available -- the link text, or its programmatically determined accessible name, has to stand on its own.

Examples

Do: Fully self-describing link text

Oakwood Foundation 2024 annual report

Adult literacy programs at Oakwood

✔ Each link is fully understandable on its own

<a href="/report">Oakwood Foundation 2024 annual report</a>
<a href="/programs">Adult literacy programs at Oakwood</a>
Don't: Link text that needs surrounding context

Read our annual report for the latest numbers.

We offer several programs for adults.

✘ "annual report" and "programs" do not identify the destination on their own

<!-- FAILS 2.4.9: link text depends on context -->
<p>Read our <a href="/report">annual report</a>
  for the latest numbers.</p>
<p>We offer several
  <a href="/programs">programs</a> for adults.</p>
Do: Unique, descriptive link text in a list
Don't: Repeated generic link text

Color contrast -- Learn more

Keyboard navigation -- Learn more

Screen readers -- Learn more

✘ Three identical "Learn more" links -- impossible to distinguish

How to Fix It

  1. Rewrite the visible text to name the destination. "Read more" becomes "Read more about the 2024 annual report"; "Download" becomes "Download the user manual (PDF, 2.1 MB)". The replacement lands in both the page flow and the links list, so the fix serves 2.4.9 and the scanning reader at the same time.
  2. When visual design needs the short label, override the accessible name. Keep "Read more" on screen and attach aria-label="Read more about the 2024 annual report". The accessible-name computation gives aria-label precedence over the link's text content, so the links list shows the full description while the visual design stays compact. Note that this breaks voice-control users who speak the visible text -- prefer visible descriptive text when possible.
  3. Differentiate repeated actions in tables and list views. "Edit" / "Edit" / "Edit" in a row of records fails 2.4.9 even if the surrounding row names the record. Put the record identifier in the link: "Edit shipping address", "Edit billing address". If the visible column layout cannot accommodate it, use aria-label per row with the row's key value.
  4. Do not rely on title attributes. The links list is computed from the accessible name, and title only contributes when nothing else is present. It is also invisible to touch and inconsistent across screen readers.
  5. Check against the actual links list, not the page. Open NVDA's elements list (Insert+F7), VoiceOver's rotor (VO+U), or JAWS's links list (Insert+F7). Every entry should identify its destination without reference to the page it came from. This is the test the criterion codifies[1].

References

  1. [1] W3C (2023). Understanding Success Criterion 2.4.9: Link Purpose (Link Only). W3C, Accessed 2026-04-07. https://www.w3.org/WAI/WCAG22/Understanding/link-purpose-link-only.html
  2. [2] W3C (2023). Understanding Success Criterion 2.4.4: Link Purpose (In Context). W3C, Accessed 2026-04-07. https://www.w3.org/WAI/WCAG22/Understanding/link-purpose-in-context.html