3.2.1 On Focus

Level: A | Principle: Understandable | Since: WCAG 2.0 | Automation: Manual


What This Means

When a UI component receives focus, it must not trigger an unexpected change of context. Simply moving focus to an element — by tabbing to it or clicking on it — should never automatically submit a form, navigate to another page, open a new window, or significantly rearrange content. Users must explicitly activate a control (press Enter, click a button) to trigger such changes.

Who This Affects

  1. Keyboard-only users — Tab through elements sequentially; unexpected navigation or form submission on focus is disorienting
  2. Screen reader users — unexpected context changes interrupt the screen reader and cause the user to lose their place
  3. Cognitive disability users — surprise page changes create confusion and anxiety
  4. Switch device users — navigate by focus; unintended actions waste time and effort

Common Pitfalls

1. Select dropdown that navigates on focus/change

<!-- Bad: navigates as soon as user selects an option
     (keyboard users cycle through options with arrows, triggering navigation
     before they reach their intended choice) -->
<select onchange="window.location.href = this.value">
  <option value="/home">Home</option>
  <option value="/about">About</option>
  <option value="/contact">Contact</option>
</select>

2. Form that submits when a field receives focus

// Bad: form submits when the last field gets focus
lastInput.addEventListener('focus', () => {
  form.submit();
});

3. New window opens on focus

// Bad: focusing a link opens it in a new window
link.addEventListener('focus', () => {
  window.open(link.href);
});

4. Content rearranges when an element receives focus

// Bad: focusing a search input expands a panel and shifts page layout
searchInput.addEventListener('focus', () => {
  expandSearchPanel(); // moves other content around
});

How to Fix

Use explicit activation, not focus

<!-- Good: navigation requires clicking a Go button -->
<label for="nav-select">Go to page:</label>
<select id="nav-select">
  <option value="/home">Home</option>
  <option value="/about">About</option>
  <option value="/contact">Contact</option>
</select>
<button onclick="window.location.href = document.getElementById('nav-select').value">
  Go
</button>

If behavior on change is needed, warn users

<!-- Acceptable: behavior change is expected and documented -->
<fieldset>
  <legend>Sort results (changes apply immediately)</legend>
  <label>
    <input type="radio" name="sort" value="date" onchange="sortResults('date')" />
    By date
  </label>
  <label>
    <input type="radio" name="sort" value="name" onchange="sortResults('name')" />
    By name
  </label>
</fieldset>

Focus can trigger visual changes, but not context changes

These are acceptable on focus:

/* OK: visual highlight on focus */
input:focus {
  border-color: #005fcc;
  box-shadow: 0 0 0 3px rgba(0, 95, 204, 0.3);
}
// OK: showing a tooltip or hint on focus
input.addEventListener('focus', () => {
  showHint('Enter your email address');
});

What counts as a "change of context"

| Change | Context Change? | |--------|----------------| | Navigate to new page | Yes | | Open new window/tab | Yes | | Submit a form | Yes | | Significantly rearrange content | Yes | | Move focus to a different element | Yes | | Show a tooltip or hint | No | | Highlight the focused element | No | | Show inline validation | No | | Expand a dropdown menu | No (if focus stays) |

How to Test

  1. Starting from the top of the page, press Tab to move focus to each interactive element one by one.
  2. At each element, verify that receiving focus does not trigger a page navigation, form submission, new window, or significant layout change.
  3. Pay special attention to <select> elements: use Arrow keys to cycle through options and confirm nothing happens until you explicitly press Enter or click a button.
  4. Check that focusing a form field does not trigger submission or navigation to another page.
  5. Pass: No element triggers a change of context (navigation, submission, new window, or major layout shift) on receiving focus alone.
  6. Fail: Any element triggers navigation, form submission, a new window, or major content rearrangement when it receives focus.

axe-core Rules

| Rule | What It Checks | |------|---------------| | — | No automated axe-core rule for this criterion. Focus behavior requires manual interaction testing. |

Sources

  1. W3C WCAG 2.2 — Understanding 3.2.1
  2. WebAIM: Keyboard Accessibility