Keyboard-only focus rings · WCAG compliance · Two-tone patterns
Tab through elements in each column to see the difference. Then click the same elements with a mouse. The key behavior: :focus-visible shows a ring for keyboard, hides it for mouse.
Ring appears on both Tab key AND mouse click. Correct but can feel jarring for mouse users when clicking buttons.
Ring shows on Tab key. Hidden on mouse click. Best of both worlds — keyboard users see the ring, mouse users don't.
No ring ever. Tab through this column — you can't tell where focus is. Keyboard users are lost. This violates WCAG 2.4.7.
Applies to the element that is focused — only when focus was triggered by keyboard.
Applies to the parent when any descendant has focus. Used for form group highlighting.
Eight different visual approaches. Tab through each button to see the keyboard focus indicator. All use :focus-visible so mouse clicks show nothing.
The standard approach. outline respects High Contrast Mode. outline-offset creates breathing room.
Outline for accessibility compliance + box-shadow for soft glow. The outline is what matters for HCM.
Visually clean but box-shadow is invisible in Windows High Contrast Mode. Add a thin outline: transparent alongside.
The black outline + white inner ring is visible on any background. Tab through the buttons above — all look great even on gradient and image backgrounds.
Focus ring inside the element. Works well for inputs and cards where an external ring would overlap adjacent elements.
For inline links, a styled underline can be a natural focus indicator. Combine with a background change for extra visibility.
Works for nav items and menu links where an outline would look out of place. Must be clearly distinguishable from the hover state.
Subtle animation makes the ring appear to "expand" from the element. Always disable with prefers-reduced-motion.
Production patterns and the WCAG 2.2 requirements for focus indicators.
Audit your CSS reset. Many include *:focus { outline: none } or *:focus { outline: 0 } that silently kills keyboard navigation site-wide.
The progressive enhancement pattern: apply focus styles broadly, then remove for mouse using :not(:focus-visible). Old browsers that don't support :focus-visible still show focus.
In Windows High Contrast Mode, custom colors are replaced by system colors. CanvasText is the high-contrast foreground. outline (but NOT box-shadow) is respected by forced-colors.
WCAG 2.4.11 (Focus Appearance, Level AA in WCAG 2.2) requires: minimum 2px thickness, 3:1 contrast ratio. The two-tone black+white pattern exceeds this universally.
| Criterion | Level | Requirement | CSS pattern |
|---|---|---|---|
| 2.4.7 Focus Visible | AA | Keyboard focus must be visible | :focus-visible { outline: 3px solid … } |
| 2.4.11 Focus Appearance | AA | ≥2px thick, ≥3:1 contrast | outline: 3px + high-contrast color |
| 2.4.13 Focus Appearance | AAA | Enhanced size + contrast | Two-tone outline pattern |
| 1.4.11 Non-text Contrast | AA | UI component states: ≥3:1 | Focus color vs bg: check ratio |