The axe accessibility rule All page content must be contained by landmarks states that all top html elements should be landmark elements, eg
<html lang="en">
<head>
<title>Hello</title>
</head>
<body>
<header>This is the header</header>
<nav>This is the nav</nav>
<main>This is the main</main>
<footer>This is the footer</footer>
</body>
</html>
But a React project requires a root element below body (required to avoid collisions with other scripts
<html lang="en">
<head>
<title>Hello</title>
</head>
<body>
<div id="root">
<header>This is the header</header>
<nav>This is the nav</nav>
<main>This is the main</main>
<footer>This is the footer</footer>
</div>
</body>
</html>
I tried to set aria-hidden="true"
to my div for screen-readers to ignore it
<div id="root" aria-hidden="true">
But this raises another issue: aria-hidden elements do not contain focusable elements
I couldn't find other people discussing this issue, which makes me wonder if it's relevant at all. Is there a clean way to have a react app with landmark top elements? Or should I just ignore this specific axe rule?
You can safely ignore this. In terms of the accessibility tree this div will be ignored.
Do not add aria-hidden
to the root div, this will attempt to hide the whole web application from a screen reader.
As long as the contents of your root div is correctly structured it will still be completely usable.
The only thing I would say is make sure you have a warning that "this application requires JavaScript" fallback sat outside of your root div.
Here is the spec on <main>
as an example. It states:-
Contexts in which this element can be used:
Where flow content is expected, but with no <article>
, <aside>
, <footer>
, <header>
or <nav>
element ancestors.
As the <body>
and <div>
elements can both accept flow content you are fine.