focus-visible vs focus Explained
- CSS Basics
- Selectors & Specificity
- Box Model & Units
- Typography & Text Styling
- Colors & Color Spaces
- Positioning & Stacking Context
- Flexbox
- Grid
- Grid Advanced
- Responsive Design
- Container Queries
- Pseudo-classes & Pseudo-elements
- Modern Selectors
- CSS Custom Properties
- CSS Functions
- Transitions & Animations
- Transforms
- Forms & Input Styling
- CSS Architecture & Methodologies
- Accessibility in CSS
- Performance & Optimization
- View Transitions & Modern APIs
- Cascade Layers & Scope
The Problem :focus Alone Creates
:focus applies whenever an element gains focus - whether that happens from a mouse click or from pressing Tab on a keyboard. This means a visible focus ring can appear after a simple mouse click, which many designers find visually unnecessary for mouse users, leading some to remove focus outlines entirely - which then breaks the experience for keyboard users who genuinely need that indicator.
What :focus-visible Solves
:focus-visible only applies when the browser determines that a focus indicator is actually useful - typically after keyboard navigation, and not after a plain mouse click. This lets a focus ring appear specifically when it matters, without appearing on every mouse click.
.btn:focus-visible {
outline: 2px solid #1d4ed8;
}
.btn:focus:not(:focus-visible) {
outline: none;
}How the Browser Decides
The exact heuristic is left to the browser, but in practice: keyboard interaction (Tab) reliably triggers :focus-visible, while a mouse click on a button typically does not - matching what most users would intuitively expect.
Why This Matters for Accessibility
Before :focus-visible existed, many sites removed focus outlines globally with outline: none purely for aesthetic reasons, which made keyboard-only navigation - used by many people who cannot use a mouse - very difficult to follow. :focus-visible removes the excuse: it gives clean visuals for mouse users and a clear indicator for keyboard users, at the same time.
Practical Recommendation
Prefer :focus-visible over unconditionally hiding focus styles. Never remove focus indicators entirely without this kind of conditional replacement.