简体   繁体   中英

How can we fix the A11y error "All page content must be contained by landmarks" with React?

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.

Further info

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.

There is no problem with the root element being a <div> element. You probably have another <div> , <p> or some other non-landmark element on the same level of the <main> , <header> and <footer> . If you will run axe on the example you showed above you won't see this issue. You will see it on the example below.

<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>
            <div>I am a stray element</div>
            <footer>This is the footer</footer>
        </div>
    </body>
</html>

The element you are looking for can be a marketial pixel on the page or darkening layer for pop-up modals for example. In these cases or in case the element is empty (and not going to be filled with content later) or its content is not relevant for screen readers (purely decorative image for example) then you can add this specific element aria-hidden="true"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM