WCAG 2.4.7 Focus Visible — Testing Guide
WCAG 2.4.7 Focus Visible (Level AA) requires that any keyboard-operable UI has a visible focus indicator. For keyboard users and users of switch control, assistive keyboards, or screen magnification,
WCAG 2.4.7 Focus Visible (Level AA) requires that any keyboard-operable UI has a visible focus indicator. For keyboard users and users of switch control, assistive keyboards, or screen magnification, the focus indicator is what tells them where they are. Missing or invisible focus indicators make the app unusable without a mouse or touch.
What it requires
When an interactive element receives focus (via keyboard, programmatic focus, or assistive tech), a visible indicator must appear on it. The indicator can be an outline, a highlight, a border change, a shadow — any visual change that distinguishes the focused element from surrounding elements.
The indicator must:
- Be visible in all themes (light, dark, high contrast)
- Meet contrast requirements (3:1 against adjacent colors per WCAG 2.4.11, AA in 2.2)
- Not be hidden by overlapping elements
Common violations
1. Removed outline without replacement
/* Bad — invisible focus */
button:focus { outline: none; }
Designers often remove the default outline because it does not match the brand. Without a replacement, the app fails 2.4.7.
2. Focus indicator too subtle
A 1px border change in a very similar color. Technically visible, practically invisible.
3. Focus hidden behind a modal overlay
Modal opens, focus moves to the first field, but the focus indicator is underneath the overlay.
4. Custom components that skip focus altogether
Divs with onclick — clickable but not focusable. tabindex="-1" on buttons.
5. Native mobile apps lacking focus for external keyboard
Works great on touch, terrible with a connected Bluetooth keyboard (accessibility device).
How to fix
Web:
:focus-visible {
outline: 3px solid #0066cc;
outline-offset: 2px;
}
/* Also style :focus for browsers without :focus-visible */
:focus {
outline: 3px solid #0066cc;
outline-offset: 2px;
}
:focus-visible shows focus for keyboard navigation but not mouse clicks — the pattern users expect.
Android:
<Button
android:background="@drawable/button_bg_focus" />
<!-- In the drawable, include a state_focused variant -->
Compose:
Button(
onClick = {},
modifier = Modifier.onFocusChanged { state ->
// Compose focus is handled by default; customize the indicator
}
) { Text("Submit") }
iOS:
iOS has less developed focus model for keyboard. UIButton has focused styling for tvOS/iPadOS-with-keyboard. For iOS 15+ with external keyboards, implement focusBackgroundColor:
button.configurationUpdateHandler = { btn in
btn.configuration?.background.backgroundColor = btn.isFocused ? .blue : .clear
}
Testing
Manual
- Disconnect your mouse / trackpad
- Navigate with Tab, Shift-Tab, Arrow keys, Enter, Space
- At every stop, is the focused element visually distinct?
- Try in light and dark themes
- Try with high contrast system setting on
Automated
- axe-core has
focus-visiblerules - Playwright test: programmatic focus, screenshot, visually diff against baseline
- Lighthouse accessibility audit includes focus checks
Browser testing
- Chrome DevTools → "Emulate focused page" — shows focus without tab
- Firefox Accessibility Inspector → focus order view
How SUSA tests focus
For web, SUSA drives through interactive elements with Tab key in the accessibility_user persona and checks for focus indicators via:
- Screenshot diff between focused and unfocused states
- computed CSS outline properties
- axe-core focus rules
For native, SUSA tests external-keyboard scenarios on Android and flags activities where key events do not produce visible focus changes.
susatest-agent test webapp-url --persona accessibility_user --keyboard-test
Focus order matters too (2.4.3)
2.4.3 Focus Order is distinct but related. Focus must move in a predictable order — usually visual reading order. Tabbing through a form should go top-to-bottom, left-to-right, not jumping around.
Test by tabbing through the entire page and writing down the order. If it matches the visual order, you pass. If it does not, rearrange DOM or use tabindex sparingly to correct.
Focus is the keyboard user's cursor. Make it visible, make it follow a logical path, and your app becomes usable by a large population that would otherwise struggle.
Test Your App Autonomously
Upload your APK or URL. SUSA explores like 10 real users — finds bugs, accessibility violations, and security issues. No scripts.
Try SUSA Free