Design System Problems

Focus Visible Styles

January 15, 2026 • 5 min read

Focus Visible Styles

Focus visible styles use the CSS :focus-visible pseudo-class to show focus indicators primarily for keyboard navigation while hiding them during mouse interaction. This approach balances accessibility requirements with visual design preferences.

What Are Focus Visible Styles

The :focus-visible pseudo-class applies styles when an element receives focus and the browser determines the user would benefit from a visible focus indicator. Browsers use heuristics to make this determination, typically showing focus-visible styles for keyboard navigation but not for mouse clicks.

This differs from the :focus pseudo-class, which applies whenever an element receives focus regardless of input method. Using :focus alone means focus rings appear after every mouse click, which many users and designers find visually distracting.

The focus-visible approach satisfies WCAG requirements because keyboard users see focus indicators when navigating. Mouse users who do not need focus indicators for navigation see a cleaner interface. Both populations receive appropriate visual feedback for their input method.

How Focus Visible Styles Work

Browsers implement focus-visible using internal heuristics about user input. Generally, keyboard events like Tab trigger focus-visible, while mouse clicks do not. Some elements like text inputs always show focus-visible because users need to know where they are typing.

CSS implementation typically uses both :focus and :focus-visible selectors. A common pattern removes the default outline on :focus but applies custom focus styles on :focus-visible:

The fallback approach ensures older browsers that do not support focus-visible still show focus indicators. These browsers ignore the :focus-visible rule and apply the :focus styles instead. Progressive enhancement means all users receive accessible focus indicators.

Design systems standardize this pattern across components. Rather than each component implementing focus-visible logic independently, shared utilities or mixins provide consistent behavior. Tokens define focus ring appearance while utilities handle the selector logic.

JavaScript polyfills can provide focus-visible behavior in browsers without native support, though browser support has become widespread enough that polyfills are often unnecessary.

Key Considerations

Common Questions

When should focus always be visible regardless of input method?

Certain elements benefit from always-visible focus indicators. Text inputs and textareas should show focus when clicked because users need confirmation of where their typing will appear. Complex widgets like dropdown menus or date pickers may need persistent focus indication during interaction.

Design systems can use :focus instead of :focus-visible for these specific elements while using :focus-visible for simpler interactive elements like buttons and links.

How do focus-visible styles work with custom components?

Custom components that use native focusable elements (buttons, inputs, links) inherit browser focus-visible behavior automatically. Custom elements using tabindex for focusability also receive appropriate focus-visible treatment from modern browsers.

Components with complex focus management, like composite widgets with roving tabindex, may need additional consideration. The active descendant within such widgets should show focus styling when the widget container has focus, regardless of input method.

Can focus-visible behavior be customized?

The browser determines focus-visible heuristics, but CSS allows showing focus unconditionally by styling both :focus and :focus-visible identically. This approach always shows focus indicators, useful for accessibility-critical applications or user preference settings.

Some design systems offer a “high visibility” mode that shows all focus indicators regardless of input method. This accommodates users who prefer explicit focus feedback even when using a mouse.

Summary

Focus visible styles use the :focus-visible pseudo-class to show focus indicators for keyboard navigation while hiding them during mouse clicks. This approach satisfies accessibility requirements while providing cleaner visuals for mouse users, with fallback support for browsers lacking focus-visible support.

Buoy scans your codebase for design system inconsistencies before they ship

Detect Design Drift Free
← Back to Accessibility Compliance