v145 · Web APIs · Focus

Focus's focusVisible option

Chrome 145 adds a focusVisible option to element.focus(), giving JavaScript control over whether the browser shows a visible focus indicator (the focus ring) when programmatically focusing an element.

background

The CSS :focus-visible pseudo-class lets the browser decide when to show a focus ring — typically for keyboard navigation but not mouse clicks. When JavaScript calls element.focus(), the browser heuristic sometimes shows a ring when not desired, or hides it when needed for accessibility.

Chrome 145 exposes { focusVisible: true | false } as an option on focus(), letting developers explicitly control whether the :focus-visible state is set on the focused element.

concepts

  1. focusVisible Demo

    Two buttons side by side — one focused with { focusVisible: false } (no ring), one with { focusVisible: true } (ring shown) — illustrating the difference in real time.

  2. Focus Option Reference

    Full option object reference for element.focus(), including preventScroll, focusVisible, and how they interact with :focus and :focus-visible CSS pseudo-classes.

  3. Dialog Restorer

    Dialog that remembers how it was opened (mouse vs. keyboard, sniffed via e.detail) and restores focus to the trigger with focusVisible matching the original input modality.

  4. Focus Ring Control

    Four real-world scenarios — skip link, keyboard shortcut, scroll-to-section, dialog close — each with three trigger buttons (true, false, default). Reports live whether :focus-visible matched and explains which option is correct for each use case.

the change

// Before Chrome 145: no control over focus ring from JS
element.focus();  // Browser decides whether :focus-visible matches

// Chrome 145+: explicit control
element.focus({ focusVisible: true });   // Force ring — matches :focus-visible
element.focus({ focusVisible: false });  // Suppress ring — :focus-visible won't match
element.focus();                         // Browser heuristic (default unchanged)

// Use case: programmatic skip-link activation
skipLink.addEventListener('click', () => {
  mainContent.focus({ focusVisible: false }); // Skip link itself highlights; target shouldn't
});

// Use case: keyboard shortcut activates dialog — ring should be visible
shortcutHandler(() => {
  firstDialogButton.focus({ focusVisible: true });
});

references