v145 · Web APIs · Focus Option Reference

Focus Option Reference

Complete reference for element.focus(options) — all accepted options, their types, defaults, and interaction with CSS pseudo-classes.

live focus option workbench

Use the buttons to focus the target with different option objects. The readout shows whether the target was newly focused, whether :focus and :focus-visible match, and whether preventScroll kept the scroll container in place.

Checking focus option behavior…
Scroll starts here. Focusing the target without preventScroll may move this panel.
Bottom spacer for scroll measurement.
Non-focusable edge target: this plain div has no tabindex, so calling focus() should not make it the active element.
active elementnone
newly focusednot tested
:focusnot tested
:focus-visiblenot tested
scrollTop before → afternot tested
last option objectnone
No focus calls yet.

focus() options

Option Type Default Description Since
preventScroll boolean false When true, the browser will not scroll the element into view after focusing it. Long-standing
focusVisible boolean | undefined undefined When true, sets :focus-visible. When false, clears it. When omitted, the browser uses its heuristic (unchanged behaviour). Chrome 145

pseudo-class behaviour

Call :focus matches :focus-visible matches
element.focus() Yes Browser heuristic (usually no for mouse, yes for keyboard)
element.focus({ focusVisible: true }) Yes Yes — always
element.focus({ focusVisible: false }) Yes No — always suppressed
User keyboard Tab Yes Yes
User mouse click Yes No (unless element has tabindex and heuristic triggers)

accessibility patterns

// Pattern 1: skip link — target shouldn't show ring
skipLink.addEventListener('click', () => {
  mainContent.focus({ preventScroll: false, focusVisible: false });
});

// Pattern 2: modal dialog opened by keyboard shortcut — ring should show
document.addEventListener('keydown', e => {
  if (e.key === '/' && !e.ctrlKey) {
    searchDialog.showModal();
    searchInput.focus({ focusVisible: true });
  }
});

// Pattern 3: carousel auto-advance — suppress ring during auto-play
function advanceSlide(el) {
  el.focus({ focusVisible: false });
}

// Pattern 4: restore focus after modal closes — respect keyboard context
function closedByKeyboard = true; // track how the close was triggered
modal.addEventListener('close', () => {
  opener.focus({ focusVisible: closedByKeyboard });
});

CSS integration

/* Recommend: style :focus-visible, not :focus */
button:focus-visible {
  outline: 2px solid var(--accent-blue);
  outline-offset: 2px;
}

/* Suppress default outline for pointer users only */
button:focus:not(:focus-visible) {
  outline: none;
}

/* You can also style differently based on context */
.card:focus-visible {
  box-shadow: 0 0 0 3px var(--accent-blue);
}

see also