Focus states that show
Why focus must be visible
Focus is the element that currently receives keyboard input. When a user presses Tab, the focus indicator is the only sign of where they are on the page.
WCAG 2.4.7 Focus Visible (level AA) requires that any keyboard-operable interface has a visible focus indicator. Without it, keyboard, switch and screen magnifier users are navigating blind.
Designing a good indicator
- Never remove the outline without a replacement. Writing <code>outline: none</code> with nothing in its place breaks WCAG 2.4.7.
- Aim for 3:1 contrast between the indicator and the colours next to it, in line with the non-text contrast guidance (WCAG 1.4.11).
- Make it thick enough to notice. A 2 px outline with a small offset is a common, readable choice.
- Check every background. A blue ring that works on white can vanish on a dark or coloured section.
Two-colour rings (a light and a dark line) stay visible on almost any background.
:focus vs :focus-visible
The <code>:focus</code> selector matches whenever an element has focus, including after a mouse click. That is why many teams removed outlines: buttons showed rings after clicking.
The <code>:focus-visible</code> selector lets the browser decide. It generally matches for keyboard focus and for text fields, and usually not for mouse clicks on buttons.
A simple pattern: style <code>:focus-visible</code> with a clear outline and let the default behaviour handle the rest.
Focus must not be hidden
WCAG 2.2 added 2.4.11 Focus Not Obscured (Minimum), level AA. A focused item must not be entirely hidden by author-created content, such as a sticky header, a cookie banner or a chat widget.
- Put your mouse away and press Tab through the whole page.
- Watch the indicator. Is it always visible and always on screen?
- Check that sticky bars never cover the focused element. In CSS, <code>scroll-padding-top</code> helps keep it clear.
Focus design is easy to forget because it never appears in a static mockup. Add focus states to the component library so every button, link, input and card has one by default.
- Every interactive element has a focus state in the design file, next to hover and pressed.
- The indicator is not clipped by a parent with <code>overflow: hidden</code>.
- Custom components, such as cards that act as links, show focus on the whole clickable area.
- Focus looks different from hover, so users can tell the two apart.
If the page is demonstrated only with a mouse, focus problems stay invisible until a keyboard user finds them.
Sources
- W3C. Understanding SC 2.4.7 Focus Visible. https://www.w3.org/WAI/WCAG22/Understanding/focus-visible.html
- W3C. Understanding SC 2.4.11 Focus Not Obscured (Minimum). https://www.w3.org/WAI/WCAG22/Understanding/focus-not-obscured-minimum.html
- MDN Web Docs. :focus-visible. https://developer.mozilla.org/en-US/docs/Web/CSS/:focus-visible
This guide was drafted with AI assistance from public standards and references. For the exact wording of a standard, use the sources listed above.