:focus vs :focus-visible
focus matches any element that has focus, even after a mouse click. focus-visible only shows an indicator where the browser decides it’s actually needed.
Side-by-side comparison
#Matches after a mouse click
- :focus
- Yes, in most browsers, even on buttons
- :focus-visible
- Usually not, except for text fields
Matches after Tab navigation
- :focus
- Yes
Who decides whether to show the indicator
- :focus
- Always matches whenever the element has focus
- :focus-visible
- The browser judges whether the indicator is needed
A text field after a mouse click
- :focus
- Matches
- :focus-visible
- Also matches, because you’re about to start typing
Browser support
- :focus
- Long-standing,
widely - :focus-visible
- Newer, but also
widely
Recommendation for focus styling
- :focus
- Only when you want to react to focus regardless of input device
- :focus-visible
- Yes, this is the modern standard for visible focus
Example
#button:focus-visible {
outline: 3px solid #f59e0b;
outline-offset: 3px;
}<div class="stage" style="display: flex; gap: 10px;">
<button type="button" style="padding: 8px 16px; border: 0; border-radius: 8px; background: #3f3f46; color: #fff;">Click with the mouse</button>
</div>Click the button with the mouse: there’ll be no outline. Now press Tab: it appears, because you’re navigating with the keyboard.
Definition and usage
#The :focus pseudo-class matches an element that has focus no matter how it got it: a mouse click, a tap on a phone, or moving there with Tab. In most browsers, clicking a button also gives it focus, which is why an outline appearing after a plain click can be surprising.
:focus-visible is smarter. The browser itself judges whether a focus indicator is actually needed at that moment. After navigating with Tab it always matches, while after clicking a button or link with the mouse it usually doesn’t, because the user can see what they clicked. Text fields are the exception: they match both, because after clicking you’re about to start typing in them anyway.
In practice, it’s worth writing your focus style in :focus-visible rather than :focus. That way, people clicking with a mouse don’t see an outline on every click, while people navigating with a keyboard still get a clear indicator. Never remove the outline with :focus { outline: none } without a replacement like this.
Syntax
#selector:focus { property: value; }
selector:focus-visible { property: value; }More examples
#button:focus {
outline: 3px solid #f59e0b;
outline-offset: 3px;
}<div class="stage" style="display: flex; gap: 10px;">
<button type="button" style="padding: 8px 16px; border: 0; border-radius: 8px; background: #3f3f46; color: #fff;">Click with the mouse</button>
</div>For comparison: plain :focus shows an outline in most browsers even after a mouse click.
input:focus-visible {
outline: 3px solid #a78bfa;
}<div class="stage"><input placeholder="Click with the mouse" style="padding: 8px 10px; border: 1px solid #52525b; border-radius: 8px; background: #18181b; color: inherit;"></div>A text field matches :focus-visible even after a mouse click, because you’re about to type in it.
Good practices
#- Never write
:focus { outline: none }without a replacement in:focus-visible, because you take away orientation from people navigating with the keyboard. - Style the focus indicator in
:focus-visible, so it doesn’t appear on every mouse click. - Combine hover effects with keyboard focus:
.btn:hover, .btn:focus-visible { ... }.
Related entries
#- :focusMatches the element that has focus, meaning it currently receives keyboard input, such as a clicked form field.
- :focus-visibleMatches a focused element only when the browser decides the indicator should be visible, such as during keyboard navigation.
- :hoverMatches the element the mouse cursor is currently over. The basis of hover effects on buttons, links, and cards.
- outlineDraws an outline around an element that doesn’t take up space in the layout.
- :activeMatches an element at the moment it’s activated, most often while the mouse button is pressed down on a button or link.
Spotted a mistake or missing an example? Write to us.