Visible focus indicators
Whenever a control receives keyboard focus, the page must show a clear, high-contrast indicator. Removing focus outlines without a replacement is a top accessibility failure.
What it is
A focus indicator is the visible cue that tells a keyboard user which control will receive their next keystroke. Browsers ship one by default — usually a thin outline ring. WCAG 2.4.7 (Level AA) requires the active focus location to be visible at all times when navigating by keyboard.
WCAG 2.2 added two more rules. 2.4.11 (AA) requires that the focused element is not entirely hidden behind sticky headers or cookie banners. 2.4.13 (AAA) sets minimum size and contrast for the focus indicator itself.
Why it matters
Without a focus ring, a keyboard user is navigating blind — they tab three times, do not know where they are, and give up. The single most common cause is a stylesheet that hides the default ring to “tidy up the design”:
/* Don't ship this. */
*:focus { outline: none; }
This is a Level AA failure. If you remove the default style, you must replace it with something equal or better.
How to implement
Use :focus-visible so the focus style appears for keyboard users but not for every mouse click on a button:
button:focus-visible,
a:focus-visible,
[role="button"]:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible {
outline: 3px solid #0b5fff;
outline-offset: 2px;
border-radius: 4px;
}
Guidelines:
- Contrast at least 3:1 against the adjacent colour, both focused and unfocused (1.4.11).
- At least 2 CSS pixels thick to meet 2.4.13’s enclosed-area minimum.
- Offset the outline away from the control so it never disappears into the border.
- Two-tone rings (a light ring and a dark ring) work on any background.
- Keep focus visible across sticky UI. Use
scroll-marginso anchor jumps land below sticky headers, and avoid full-viewport modals that overlay the focused element below.
:focus-visible is supported in every current browser. If you need to support older engines, pair it with :focus as a fallback.
Common mistakes
outline: nonewith no replacement.- A focus style that only changes the text colour by a small amount.
- A focus ring drawn inside the button so the button’s own background hides it.
- Sticky headers covering the focused control after Tab scrolls it into view.
- Custom widgets (cards, tab lists) that never style their focused state.
Verification
- Tab through every page template; the focused control must be obvious from across the room.
- Check the contrast of the focus ring against its background.
- Resize the viewport and test with sticky headers in place — focus must stay visible.