Wayfinding is a quiet skill: when it works, nobody notices it. People glance at a
menu, read a link, and move on without thinking. It only becomes visible when it
breaks — when a link reads “click here” and gives no hint of where it leads, when
nothing in the menu shows which page you’re on, when a buried page can only be reached
by one long path, or when the navigation rearranges itself from screen to screen. Each
of those failures pushes effort back onto the user, and for people who navigate by
screen reader, keyboard, or memory, it can stop the journey entirely.
This lesson works through the four defects behind the majority of real-world
navigation failures. Each one is small to fix and uses plain HTML you already have —
the wins come from writing honest link text and keeping the structure predictable, not
from adding ARIA on top.
What you’ll learn
How to write link text that describes its destination so it makes
sense out of context; how to mark the current page in a navigation menu with
aria-current="page" and a non-colour cue; how to give people more than
one way to reach content — navigation plus search plus a sitemap; and how to keep
the order and labels of your navigation consistent from one page to the next.
Standards this lesson maps to
Standard
Criterion
Level
What it requires
WCAG 2.2
2.4.4 Link Purpose (In Context)
A
The purpose of each link can be determined from its text, or from the text together with its programmatically determined context.
WCAG 2.2
2.4.9 Link Purpose (Link Only)
AAA
The purpose of each link can be determined from the link text alone, with no surrounding context needed.
WCAG 2.2
4.1.2 Name, Role, Value
A
The state of the current navigation item is exposed to assistive technology, e.g. with aria-current="page".
WCAG 2.2
2.4.5 Multiple Ways
AA
More than one way is available to locate a page within a set of pages, except where the page is a step in a process.
WCAG 2.2
3.2.3 Consistent Navigation
AA
Navigation repeated across pages appears in the same relative order each time, unless the user changes it.
WCAG 2.2
3.2.4 Consistent Identification
AA
Components with the same function are identified consistently across pages (same name, label, and icon).
EN 301 549
9.2.4.4 / 9.2.4.5 / 9.3.2.3 (incorporates WCAG)
—
European harmonised standard; references the WCAG A/AA set including the navigation criteria.
Section 508
502.3 / 504 (incorporates WCAG A & AA)
—
US federal ICT must meet WCAG 2.0 Level A and AA, including link purpose and consistent navigation.
ADA Title II
WCAG 2.1 AA (DOJ rule)
AA
US state/local government web content must conform to WCAG 2.1 AA.
The four problems we’ll fix
Each card below isolates one common navigation defect. For every issue you get a
plain-language statement of the problem, a Bad example (shown as
escaped, non-running code so it can’t affect this page), a Good
example, the copyable Code, and an ordered fix.
Non-descriptive link text
WCAG 2.2 · 2.4.4A2.4.9AAAEN 301 549
Link text like “click here”, “read more”, or a bare URL
carries no meaning on its own. Many screen reader users navigate by pulling up a
list of every link on the page, where each one is read with no surrounding
sentence — a list of five “read more” entries is five links to nowhere in
particular. A pasted URL is worse: it’s announced character by character, or as an
opaque string of slashes and query parameters. The fix is to make the visible link
text describe its destination, so the link stands on its own whether it’s read in
the flow of the page or lifted out into a links list.
Bad
The destination lives in the surrounding sentence, not in the link. Read out
of context — as a screen reader links list does — “click here” and “read more”
are meaningless, and the raw URL is just noise.
bad-link-text.html
<p>To see our refund policy, <a href="/refunds">click here</a>.</p>
<p>New pricing is now live. <a href="/pricing">Read more</a></p>
<p>Docs: <a href="/docs/getting-started">https://example.com/docs/getting-started</a></p>
Good
The visible text names the destination. Each link makes sense on its own, so
it works in a links list and satisfies 2.4.9 (link text alone), the stronger
AAA bar — not just 2.4.4 (link plus context).
good-link-text.html
<p>Read our <a href="/refunds">refund policy</a>.</p>
<p><a href="/pricing">See the new 2026 pricing</a></p>
<p><a href="/docs/getting-started">Read the getting-started guide</a></p>
Code
When a design repeats a short label like “Read more” by necessity (a card
grid), keep the visible text but extend the accessible name with
aria-label so each link is still unique out of context. Never hide
the destination behind only an icon.
link-aria-label.html
<article>
<h3 id="post-42">Designing accessible menus</h3>
<p>A short summary of the article…</p>
<a href="/blog/accessible-menus"
aria-label="Read more: Designing accessible menus">Read more</a>
</article>
How to fix
Make the visible link text describe the destination — “refund policy”,
“2026 pricing” — not “click here” or “read more”.
Read each link as if it were alone in a list. If you can’t tell where it
goes, rewrite it.
Don’t use a raw URL as link text; replace it with a human-readable label.
If a repeated short label is unavoidable, give each link a unique
accessible name with aria-label (it overrides the visible text
for assistive tech, so include the same words).
Two links that go to the same place should share the same text;
two links with different text shouldn’t go to the same place.
Current page not indicated in the navigation
WCAG 2.2 · 4.1.2AEN 301 549Section 508
A navigation menu where nothing marks the active item
leaves users guessing where they are. Sighted users often get a colour highlight,
but a screen reader user hears the same flat list of links on every page with no
sign of which one is the page they’re on — and if the only cue is colour,
low-vision and colour-blind users miss it too. The state of the current item is
part of its name, role, and value (4.1.2): set aria-current="page" on
the active link so assistive tech announces “current page”, and pair it with a
visual cue that doesn’t rely on colour alone.
Bad
An active class paints the current link a different colour, but
nothing exposes that state programmatically. Screen reader users get no
“current page” announcement, and the colour-only cue fails for many others.
bad-current.html
<nav aria-label="Primary">
<ul>
<li><a href="/">Home</a></li>
<li><a class="active" href="/learn">Learn</a></li>
<li><a href="/about">About</a></li>
</ul>
</nav>
<!-- .active only changes the text colour -->
Good
The active link carries aria-current="page", so it’s announced as
the current page. A CSS rule keyed off the attribute adds a non-colour cue (a
bold weight and a left border), satisfying both 4.1.2 and the use-of-colour
requirement.
Style the current item from the attribute, not a class, so the visual cue and
the announced state can never drift apart. Use weight plus a marker, not colour
alone.
current-cue.css
[aria-current="page"] {
font-weight: 700; /* non-colour cue */
border-inline-start: 3px solid currentColor;
padding-inline-start: 0.5rem;
}
/* For "you are here" in a breadcrumb, use a span, not a link: */
<li><span aria-current="page">Links & navigation</span></li>
How to fix
Add aria-current="page" to the navigation link for the page the
user is on — exactly one per nav.
Pair it with a visual cue that isn’t colour alone: a heavier weight, an
underline, or a border, so the “you are here” state is perceivable for
everyone.
Drive the styling from the [aria-current="page"] attribute, not
a separate .active class, so the cue and the announced state
stay in sync.
In a breadcrumb, mark the final “you are here” item with
aria-current="page" on a non-link <span>.
Use the right token for the context — page for the current
page, step in a wizard, true for a generic current
item.
Only one way to find content
WCAG 2.2 · 2.4.5AAEN 301 549ADA
When the only route to a page is a single deep,
multi-level menu, anyone who can’t — or doesn’t want to — drill through that exact
path is stuck. People form different mental models: some browse a menu, some search
by name, some scan a sitemap or an A–Z index. Multiple Ways (2.4.5) asks that a
page be reachable by at least two of these, so no one is locked out by the single
route the designer happened to pick. Search especially shortens long keyboard and
switch journeys. The one exception is a page that is a step in a process (like a
checkout), where a stray shortcut could break the flow.
Bad
The only way to reach the page is by hovering and drilling through nested menu
levels. There’s no search, no sitemap, and no in-content links — a single
route, and a demanding one for keyboard and screen reader users.
bad-one-way.html
<nav aria-label="Primary">
<ul>
<li>Products
<ul>
<li>Hardware
<ul>
<li><a href="/products/hardware/sensors">Sensors</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</nav>
<!-- No search, no sitemap, no other path to /products/hardware/sensors -->
Good
Alongside the menu there’s a site search and a link to a sitemap. The same
page can now be reached three different ways, so the single deep path is no
longer the only option (2.4.5).
A sitemap is simply a nested list of links to every page — cheap to build and
a reliable second route. An A–Z index or related-links block counts too. You
need any two independent ways, not all of them.
Provide at least two independent ways to reach any page: a navigation menu
plus a site search, a sitemap, or an A–Z index.
Add a real search form with a labelled input wrapped in
role="search"; it’s the fastest route for many users.
Publish a sitemap page — a nested list of links to everything — and link to
it from the footer of every page.
In-content links and related-links blocks count as additional ways, so
cross-link between related pages.
You may skip this only for a page that is a step in a process (such as a
checkout), where extra entry points would break the flow.
Inconsistent navigation and naming across pages
WCAG 2.2 · 3.2.3AA3.2.4AAEN 301 549Section 508
People learn a site by repetition: once they’ve found
the menu and a control, they expect it in the same place, in the same order, with
the same name on every page. When the navigation is reordered from one page to the
next, or the same control is called “Search” here and “Find” there — or shows a
magnifying-glass icon on one page and a label on another — that learned model
breaks. Consistent Navigation (3.2.3) requires repeated navigation to keep the same
relative order, and Consistent Identification (3.2.4) requires components with the
same function to be named and marked the same way throughout. This matters most for
users with cognitive disabilities, but it speeds everyone up.
Bad
Between two pages the menu order changes and the same search control is
relabelled. A returning user has to re-find everything; a screen reader user
hears a different list and a different control name (3.2.3, 3.2.4).
The navigation keeps the same relative order on every page, and the search
control keeps the same name throughout. The shared markup is best lived in one
include or component so it can’t drift.
good-consistent.html
<!-- shared on every page (same order, same labels) -->
<nav aria-label="Primary">
<a href="/">Home</a> <a href="/learn">Learn</a> <a href="/about">About</a>
</nav>
<button>Search</button>
Code
Consistent identification covers the accessible name too. If a control is an
icon-only button, give it the same accessible name everywhere — don’t label it
“Search” on one page and “Find” via aria-label on another.
consistent-name.html
<!-- Same accessible name on every page -->
<button type="button" aria-label="Search">
<svg aria-hidden="true" focusable="false">…</svg>
</button>
<!-- Reuse the markup; don't hand-copy it per page -->
<!--#include virtual="/partials/site-header.html" -->
How to fix
Keep navigation that repeats across pages in the same relative order
everywhere (3.2.3); reordering is only allowed if the user chooses it.
Give every repeated control the same name, label, and icon on every page —
one function, one identity (3.2.4).
Match the accessible name to the visible label so voice-control users can
say what they see.
Build the header and navigation as a single shared include or component, so
a change happens once and can’t drift between pages.
If you offer a user-reorderable or personalised menu, that’s fine — the
consistency requirement applies to changes you make, not ones the
user requests.
Recap
Write link text that names its destination so it stands on its own — never
“click here”, “read more”, or a bare URL (2.4.4, 2.4.9).
Mark the active navigation item with aria-current="page" and back
it up with a visual cue that isn’t colour alone (4.1.2).
Give people more than one way to reach a page — a menu plus a search and a
sitemap or A–Z index — so no content depends on a single route (2.4.5).
Keep navigation in the same order on every page and give each repeated control
the same name and icon throughout (3.2.3, 3.2.4).
The same fixes satisfy WCAG, EN 301 549, Section 508, and ADA
Title II at once — make wayfinding honest and predictable and you meet them all.