3.2.1 On Focus

WCAG 2.2 · 3.2.1 A Understandable

What it requires

When any component receives keyboard focus, it must not automatically trigger a change of context. Moving focus to a control — by tabbing, clicking, or scripting — is allowed to do nothing visible beyond the normal focus indicator. It must not, on its own, do things like open a new window, move focus elsewhere, submit a form, or otherwise substantially rearrange the page.

A “change of context” means a major change a user could miss: a new window or tab, a change of user agent, a change of viewport, a shift of focus to a different component, or content change that significantly alters the page’s meaning. The criterion is about receiving focus only — acting on a deliberate activation (a click or Enter) is covered separately by 3.2.2 On Input.

  • Keyboard-only users, who tab through controls to explore a page — an unexpected jump or new window strands them away from where they were.
  • Screen reader users, who may not perceive that the window, focus, or page meaning changed, and lose their place.
  • People with cognitive or attention disabilities, who are disoriented by content that shifts without a deliberate action.
  • Low-vision and magnification users, whose narrow viewport makes an unannounced context change easy to miss entirely.

How to detect it

Ways to test for On Focus failures
Check What to look for
Keyboard tabbing Tab through every focusable control. Focus arriving should never open a new window, submit, or jump focus elsewhere.
Select & menu controls Focus (not change) a native select or custom menu — it must not navigate or reload on focus alone.
Screen reader Confirm focus moves predictably and the reading position is not silently relocated.
Zoom / small viewport At 200%+ zoom, verify focus does not cause off-screen content shifts you can’t see.
Automated tools Tools like axe cannot reliably catch this — it is behavioural and needs manual keyboard testing.

How to fix it

  1. Never wire navigation, submission, or window-opening to a focus event. Use deliberate activation events (click, change via Enter/Space) instead.
  2. For dropdowns, let focus and arrow-key browsing reveal options without acting; only act when the user explicitly confirms a choice.
  3. Don’t auto-submit forms or move focus when a field is reached during tabbing.
  4. Provide a visible control (button or link) for any action, so the user triggers the context change on purpose.
<!-- Focus reveals options; action waits for a deliberate change -->
<label for="country">Country</label>
<select id="country" name="country">
  <option value="">Choose…</option>
  <option value="ie">Ireland</option>
</select>
<button type="submit">Apply</button>

Copy-paste tests

Automated coverage

There is no fully automated axe-core rule for 3.2.1 On Focus — it is behavioural, so it needs manual review. Use the console check and steps below to surface suspects, then verify each by keyboard.

Run this in the browser console

console — list focus handlers
// READ-ONLY: flags controls that may act on focus. Review each by keyboard.
const suspects = [...document.querySelectorAll('[onfocus], select, [role="menu"], [role="listbox"]')];
suspects.forEach(el => el.style.outline = '2px solid orange');
console.table(suspects.map(el => ({
  tag: el.tagName.toLowerCase(),
  id: el.id || null,
  onfocus: el.getAttribute('onfocus') || null,
  role: el.getAttribute('role') || null
})));

What to check manually: Tab onto each flagged control and confirm that merely receiving focus opens no new window/tab, submits nothing, and never moves focus elsewhere — no script can confirm whether a context change actually fires on focus.