Search topics
Navigation that marks the current page only by its look
The menu link for the page you are on is bold and underlined by a class, but nothing in the markup says it is the current page.
class="active" The problem
Screen reader users move through the menu without being told which page they are on.
A site's header has four links: Home, Products, Pricing and Contact. On the pricing page, the Pricing link is bold with a bar under it, so a sighted visitor sees at a glance where they are. A screen reader user moving through the same menu hears "Home, link", "Products, link", "Pricing, link", "Contact, link". Nothing tells them which one is the page they are on. On a large site with sections and sub-menus, the same gap means they can't tell which section a page belongs to either.
The bold text and the bar come from a class, active, that only the stylesheet reads. The menu shows a relationship, "this link is the page you are on", and WCAG 1.3.1 Info and Relationships requires that information shown by presentation is also available in the code, or in the text. Here it is only in the look. The class name means nothing to the browser, so assistive technology has nothing to pass on.
Screen reader users rely on the menu to orient themselves, the way sighted visitors do. People who arrive on a page from a search result or a shared link especially need to know where they have landed. Without the mark, they have to read the heading and the content and work it out.
1 of 10 groups affected
- No vision (affected)
- Low vision (not affected)
- Colour vision (not affected)
- No hearing (not affected)
- Hard of hearing (not affected)
- No speech (not affected)
- Motor (not affected)
- Reach, strength (not affected)
- Cognitive (not affected)
- Seizures (not affected)
- Without vision A screen reader reads every menu link the same way, so the person cannot tell from the menu which page they are on, or which section a page belongs to, and has to read the page itself to find out.
A scanner sees four valid links with names and passes them. It can't know that one link is styled as current, because a class called active, selected or is-here means nothing to it, and it can't check that the marker moves when the page does. AI code generators often reach for aria-selected="true" or role="tab" on the link, which belong to tabs and listboxes and are ignored or misread on a plain link. Some remove the href from the current link, which takes it out of the Tab order and still says nothing about it being current. Listening to the menu on two different pages is the only way to confirm that it says where you are.
Try it
Press Tab to move through the menu.
The panel shows what a screen reader says on each link. Can you tell which page you are on? Press Enter on another link to move there.
Broken Can you fix this?
Screen reader says:
(Tab to a link)A recreated demo. The broken version is intentionally inaccessible.
The fix
Say in the code which menu link is the current page, and draw the look from that.
- 1Mark the current page's link with
aria-current="page", or with hidden text inside the link. - 2Set the visual style and the code marker from the same condition, so they mark the same link.
- 3Mark one link per menu, and move the mark when the page changes.
<nav aria-label="Main"> <ul> <li><a href="/">Home</a></li> <li><a href="/products">Products</a></li> <li><a href="/pricing" class="active">Pricing</a></li> <li><a href="/contact">Contact</a></li> </ul></nav>Aria-current on the link
<nav aria-label="Main"> <ul> <li><a href="/">Home</a></li> <li><a href="/products">Products</a></li> <li><a href="/pricing" aria-current="page">Pricing</a></li> <li><a href="/contact">Contact</a></li> </ul></nav>Why this fix: Style from the state, not a class
The active class gives the Pricing link its look and nothing else. A screen reader reads it as "Pricing, link", the same as the other three.
aria-current="page" tells assistive technology that this link is the page being shown, and screen readers announce it as "current page". The style now selects on the attribute instead of a class, so the look and the code come from one marker and can't point at different links. The link keeps its href, so it stays in the Tab order and still works as a link.
Both pass 1.3.1. Use aria-current="page": it does the same job with one attribute and nothing to translate, screen readers announce it in the user's own language, and styling from the attribute ties the look to the code. Use hidden text only when the menu cannot take attributes, and keep the class and the text set by the same condition.
Other links and menus need their own choices once the main menu is right.
- Section links: when a visitor is on a page inside Products, such as a single product, the Products link is not the current page. Some sites mark it with
aria-current="true"and a lighter style to show the current section; others leave it unmarked. Never mark itpage. - Several menus: a page can have a header menu, a sub-menu and a footer menu that link to the same page. Mark the link in each, so the answer is the same wherever someone reads it.
- Breadcrumbs: the last item names the current page, and takes
aria-current="page"if it is a link. Breadcrumbs have their own guide. - Client-side routing: in a single-page app, the router must move the attribute when the view changes. Set it from the router's current URL, not from a click handler, so a back-button move updates it too.
Keep the visual mark visible in forced colors. A bold weight and a border survive Windows contrast themes; a background colour or a change of text colour alone does not, and colour alone also fails 1.4.1. Leave the current page as a working link: people use it to reload or copy the address, and removing the href changes the Tab order from page to page.
Fixing this with an AI coding assistant? Get this guide as Markdown
Verify the fix
5 checks, no mouse.
Test with: Screen reader, Keyboard, Forced colors
Record the OS, browser and assistive-technology versions, the build, the date, and the actual result of each step. Repeat after the menu or router changes.
Limits
This is a starting pattern, not a guarantee for every menu. Screen readers word aria-current differently, and some say it before the link name and some after. A menu that marks the right link still leaves people lost on a site with a confusing structure; a clear page title, heading and breadcrumbs carry the rest.
This is a recreated teaching example, not a finding about a named client. The code is a starting pattern: test it in your own product. No completed assistive-technology test is claimed here.
Keep this fixed as your code changes.
Turn guides like this into rules your coding agents and CI follow, then have the result retested with a keyboard and screen readers.