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
- Keyboard-only users — Tab through elements sequentially; unexpected navigation or form submission on focus is disorienting
- Screen reader users — unexpected context changes interrupt the screen reader and cause the user to lose their place
- Cognitive disability users — surprise page changes create confusion and anxiety
- 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
- Starting from the top of the page, press Tab to move focus to each interactive element one by one.
- At each element, verify that receiving focus does not trigger a page navigation, form submission, new window, or significant layout change.
- 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. - Check that focusing a form field does not trigger submission or navigation to another page.
- Pass: No element triggers a change of context (navigation, submission, new window, or major layout shift) on receiving focus alone.
- 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. |