Landmarks of the same kind need different names
- Rule:
axe/landmark-unique - Checks: Landmarks should have a unique role or role/label/title (i.e. accessible name) combination
- WCAG: none; a best practice, not a WCAG success criterion
- Fix class:
content: A fix needs authored text.
Who it affects
Section titled “Who it affects”- People who use a screen reader or a braille display, most of them blind.
How to fix it
Section titled “How to fix it”The page has several <nav> elements without names
Section titled “The page has several <nav> elements without names”Name each navigation for what it holds, with aria-labelledby pointing at its visible heading, or with aria-label when it has none. Leave the word “navigation” out: screen readers already announce the role.
<nav aria-label="Primary"> <a href="/plans">Plans</a></nav><nav aria-labelledby="help-links"> <h2 id="help-links">Help</h2> <a href="/support">Contact support</a></nav>One navigation appears twice with the same links, such as a pager above and below a list
Section titled “One navigation appears twice with the same links, such as a pager above and below a list”Give both copies the same name, one that says what they are, such as “Pages”. axe still reports them; the report can be dismissed once you confirm the links match. Name them apart when their links differ.
Repeated sections or asides share one name, such as cards each named “Product”
Section titled “Repeated sections or asides share one name, such as cards each named “Product””Name each for its own content, preferably with aria-labelledby pointing at its heading. Sections that are not major parts of the page can lose their names instead, since a <section> without one is not a landmark. An <aside> at the top level or in <main> stays a landmark without a name, so name it or make it a <div>.
Fixes that fail
Section titled “Fixes that fail”Numbering the names, such as “Navigation 1” and “Navigation 2”
Section titled “Numbering the names, such as “Navigation 1” and “Navigation 2””axe accepts them, but they tell screen reader users nothing about which landmark holds what.
Giving a section an aria-label that differs from its visible heading
Section titled “Giving a section an aria-label that differs from its visible heading”People who move by landmark hear one name and people who move by heading hear another, so the one section seems to be two.
In React
Section titled “In React”The part of the fix that differs in React, in its syntax. The rest of the guidance holds.
A reusable component labels its landmark with a hard-coded id or aria-label
Section titled “A reusable component labels its landmark with a hard-coded id or aria-label”Create the id with useId, so that each copy points at its own heading, or take the label as a prop. Two copies that share a hard-coded id both take their name from the first heading.
function Panel({ title, children }) { const headingId = useId(); return ( <section aria-labelledby={headingId}> <h2 id={headingId}>{title}</h2> {children} </section> );}Fixes that fail in React
Section titled “Fixes that fail in React”Building the id with Math.random() or a module-level counter
Section titled “Building the id with Math.random() or a module-level counter”The server and the client then render different values, so hydration does not match, and a random id made during render changes on every render. useId gives each copy one id that stays the same.
More on the rule
Section titled “More on the rule”axe-core’s documentation of the rule
CORA’s fix guidance adapts content from accessibility-agents, under the MIT License: see its notice.