Skip to main content
HTML Validation

There must not be two elements with the same "nearest ancestor autofocus scoping root element" that both have the “autofocus” attribute specified.

About This HTML Issue

A page can have only one element with the autofocus attribute, and so can each <dialog> and each popover on it.

The HTML standard groups autofocus elements by their "nearest ancestor autofocus scoping root element". For an element inside a <dialog>, or inside an element with the popover attribute, that root is the closest such ancestor. A <dialog> or popover that has autofocus itself is its own root. Everything else on the page shares one root, the <html> element. When two elements with autofocus end up with the same root, the validator reports this error.

The rule follows from how browsers use the attribute. On page load, the browser focuses one autofocus element, normally the first in source order, and ignores the rest. A <dialog> or popover can have its own autofocus element because the browser moves focus into it each time it opens.

A common cause is a site header whose search field has autofocus, on a page whose main form uses it too. Keep autofocus on the one field people most likely want to type in first, and remove it from the others. A modal built from a plain <div> doesn't get its own root, even with role="dialog". If the second field belongs in a modal, build the modal with <dialog> or the popover attribute, and its autofocus no longer clashes with the page's.

Invalid example

<header>
  <form action="/search" role="search">
    <input type="search" name="q" aria-label="Search" autofocus>
  </form>
</header>
<main>
  <form action="/login" method="post">
    <label for="username">Username</label>
    <input type="text" id="username" name="username" autofocus>
    <label for="password">Password</label>
    <input type="password" id="password" name="password">
    <button type="submit">Sign in</button>
  </form>
</main>

Valid example

Only the login form's first field keeps autofocus:

<header>
  <form action="/search" role="search">
    <input type="search" name="q" aria-label="Search">
  </form>
</header>
<main>
  <form action="/login" method="post">
    <label for="username">Username</label>
    <input type="text" id="username" name="username" autofocus>
    <label for="password">Password</label>
    <input type="password" id="password" name="password">
    <button type="submit">Sign in</button>
  </form>
</main>

When the search field lives in a <dialog>, both fields can keep autofocus, because each has a different root:

<main>
  <form action="/login" method="post">
    <label for="username">Username</label>
    <input type="text" id="username" name="username" autofocus>
    <label for="password">Password</label>
    <input type="password" id="password" name="password">
    <button type="submit">Sign in</button>
  </form>
</main>
<dialog id="search-dialog">
  <form action="/search" role="search">
    <input type="search" name="q" aria-label="Search" autofocus>
    <button type="submit">Search</button>
  </form>
</dialog>

Find issues like this automatically

Rocket Validator scans thousands of pages in seconds, detecting HTML issues across your entire site.

Help us improve our guides

Was this guide helpful?
🌍 Trusted by teams worldwide

Validate at scale.
Ship accessible websites, faster.

Automated HTML & accessibility validation for large sites. Check thousands of pages against WCAG guidelines and W3C standards in minutes, not days.

Scheduled Reports
API Access
Open Source Standards
€5 / week

1K Weekly

1,000 monthly checks. Cancel anytime.

Get 1K Weekly →

Join teams across 40+ countries