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.
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);
}