2.4.7 Focus Visible
Level: AA | Principle: Operable | Since: WCAG 2.0 | Automation: Manual
What This Means
When an interactive element receives keyboard focus, there must be a visible indicator showing which element is focused. Without a focus indicator, keyboard users are navigating blind — they have no idea where they are on the page.
Who This Affects
- Keyboard-only users — completely depend on the focus indicator to know which element is active
- Low-vision users — need a clear, high-contrast indicator to track focus
- Cognitive disability users — visible focus helps maintain orientation on the page
- Switch device users — sequential navigation requires knowing current position
Common Pitfalls
1. Removing outline with no replacement
This is the single most common accessibility violation on the web. Designers remove the default browser outline for aesthetics and provide nothing in return.
/* Bad: kills focus visibility with no replacement */
*:focus {
outline: none;
}
/* Bad: also kills focus visibility */
button:focus,
a:focus {
outline: 0;
}
2. Focus indicator with insufficient contrast
A light gray ring on a white background is technically present but practically invisible.
/* Bad: low contrast focus ring */
button:focus {
outline: 2px solid #ccc;
}
3. Focus indicator only on some elements
Links have a visible focus style, but buttons or custom components do not.
4. Using :focus instead of :focus-visible
Applying :focus styles shows the focus ring on mouse clicks too, which leads developers to remove it entirely. Using :focus-visible only shows it for keyboard navigation.
How to Fix
Use :focus-visible for keyboard-only indicators
/* Remove default outline only when replacing it */
:focus {
outline: none;
}
/* Show custom focus ring for keyboard navigation */
:focus-visible {
outline: 3px solid #1a73e8;
outline-offset: 2px;
}
High-contrast focus styles
/* Good: thick, high-contrast outline */
:focus-visible {
outline: 3px solid #005fcc;
outline-offset: 2px;
}
/* Good: double ring for complex backgrounds */
:focus-visible {
outline: 3px solid #005fcc;
box-shadow: 0 0 0 6px #ffffff;
}
Ensure all interactive elements are covered
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
[tabindex]:focus-visible {
outline: 3px solid #005fcc;
outline-offset: 2px;
}
Never suppress focus for keyboard users
If a design system removes outline, it must add a visible replacement:
/* Bad */
.btn:focus { outline: none; }
/* Good */
.btn:focus-visible {
outline: none;
box-shadow: 0 0 0 3px #005fcc;
}
How to Test
- Starting from the top of the page, press Tab to move through every interactive element (links, buttons, inputs, custom controls).
- At each element, verify a clearly visible focus indicator appears (outline, box-shadow, background change, or border).
- Check that the focus indicator has sufficient contrast against its background so it is easy to see.
- Inspect the CSS for
:focus { outline: none }or:focus { outline: 0 }rules that remove the focus ring without providing a replacement. - Test custom components (dropdowns, modals, carousels, tabs) to confirm they also show a visible focus indicator.
- Pass: Every interactive element shows a clearly visible focus indicator when reached by keyboard.
- Fail: Any element has no visible focus indicator, or the indicator is too faint to see against the background.
axe-core Rules
| Rule | What It Checks | |------|---------------| | — | No automated axe-core rule reliably checks focus visibility. It requires manual keyboard testing. |
Tools
Test this criterion with the Focus Order Visualizer.