Skip to content

JavaScript Tutorial Accessibility with JavaScript

Focus Management

Lesson 217 of 258 2 min read By Deepak Paswan Updated Oct 4, 2026

Focus is where the keyboard is. When your JavaScript changes the page, focus can be lost or left in a confusing place. Managing it is a core part of accessible code.

focus()

index.html
HTML
<button id="open">Show form</button>
<form id="form" hidden>
  <label>Name <input id="name"></label>
</form>
<script>
  document.querySelector("#open").addEventListener("click", () => {
    const form = document.querySelector("#form");
    form.hidden = false;
    document.querySelector("#name").focus();       // move the cursor to the first field
  });
</script>

Focus the thing the user should interact with next.

When to move focus

SituationWhere focus should go
A dialog or menu opensinto it (first control, or the dialog itself)
A dialog closesback to the button that opened it
A form fails validationthe first invalid field
Content is deletedthe next item, or the list
A “page” changes in a single-page appthe new main heading or content
A skip link is usedthe main content

Returning focus

Remember what had focus before and restore it.

index.html
HTML
<button id="open">Open panel</button>
<div id="panel" hidden tabindex="-1">
  <p>Panel content</p>
  <button id="close">Close</button>
</div>
<script>
  const open = document.querySelector("#open");
  const panel = document.querySelector("#panel");

  open.addEventListener("click", () => {
    panel.hidden = false;
    panel.focus();                      // tabindex="-1" lets us focus a non-interactive element
  });

  document.querySelector("#close").addEventListener("click", () => {
    panel.hidden = true;
    open.focus();                       // back where the user came from
  });
</script>

tabindex="-1" makes any element focusable from script without adding it to the Tab order.

Focus after removing something

script.js
JS
function deleteItem(item) {
  const next = item.nextElementSibling ?? item.previousElementSibling ?? list;
  item.remove();
  next.setAttribute("tabindex", "-1");
  next.focus();
}

Otherwise focus falls back to the top of the page, and a keyboard user must tab all the way back.

A hidden-until-focused link at the top of the page lets keyboard users jump past the navigation.

index.html
HTML
<a class="skip-link" href="#main">Skip to main content</a>
...
<main id="main" tabindex="-1">...</main>

Focus traps (for modal dialogs)

While a modal dialog is open, Tab should stay inside it. The modern way is the native <dialog> with showModal(), which handles it for you: Dialog and Modal Basics. If you build one by hand, you must loop focus between the first and last control and make the rest of the page inert.

Visible focus

Users must see where focus is. Keep or restyle the outline: :focus-visible { outline: 3px solid ...; }.

Detecting focus

script.js
JS
element.addEventListener("focus", () => { ... });
element.addEventListener("blur", () => { ... });
console.log(document.activeElement);   // the focused element

preventScroll

element.focus({ preventScroll: true }) avoids jumping the page when you focus something off-screen. Use it carefully: the user normally needs to see the focused element.

lightbulb
A quick test
After every interaction that changes the page, ask: “Where is focus now? Is that where a keyboard user would expect it?”