The main landmark needs to sit outside other landmarks
- Rule:
axe/landmark-main-is-top-level - Checks: Main landmark should not be contained in another landmark
- WCAG: none; a best practice, not a WCAG success criterion
- Fix class:
mechanical: A fix needs no authored text or visual decision.
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”A wrapper around <main> is a landmark, such as a named <section> or an element with role="region"
Section titled “A wrapper around <main> is a landmark, such as a named <section> or an element with role="region"”Make the wrapper a plain <div> with no landmark role and no name, or move <main> out of it. HTML lets <main> sit only in <body>, a <div>, an unnamed <form> or a custom element, so an unnamed <section> is still the wrong wrapper.
<div class="layout"> <main> <h1>Account settings</h1> <p>Change your email address and password.</p> </main></div>The <main> element sits inside the site header, a navigation or a sidebar
Section titled “The <main> element sits inside the site header, a navigation or a sidebar”Move <main> out so that it is a sibling of the header, the navigation and the footer, not a child of one of them.
<header> <a href="/">Acme home</a></header><main> <h1>Orders</h1> <p>You have no open orders.</p></main><footer> <p>Acme Inc.</p></footer>Fixes that fail
Section titled “Fixes that fail”Changing the page’s only <main> to a <div> to clear the rule
Section titled “Changing the page’s only <main> to a <div> to clear the rule”The page then has no main landmark, so screen reader users cannot jump to its content, and axe reports landmark-one-main instead.
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 layout component renders <main> around the routes, and a page component renders its own <main> inside it
Section titled “A layout component renders <main> around the routes, and a page component renders its own <main> inside it”Keep <main> in the layout only, and have page components return their content in a fragment, a <div> or an <article>.
function Layout({ children }) { return ( <> <header> <a href="/">Acme home</a> </header> <main>{children}</main> </> );}
function OrdersPage() { return ( <> <h1>Orders</h1> <p>You have no open orders.</p> </> );}The app mounts into a <main> in index.html and also renders its own
Section titled “The app mounts into a <main> in index.html and also renders its own”Mount the app into a plain <div>, such as <div id="root">, and render <main> from the app.
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.