Skip to main content
Home / CSS Almanac / Selectors / F / :focus-visible


The :focus-visible pseudo-class (also known as the "Focus-Indicated" pseudo-class) is a native CSS way to style elements that:

  1. Are in focus
  2. Need a visible indicator to show focus (more on this later)

:focus-visible is used similarly to :focus: to bring attention to the element that currently has the focus.

.element:focus-visible {
  background-color: pink; /* Something to get the user's attention */

:focus-visible is part of the CSS4 Selectors working draft. Prior to adoption, Mozilla introduced the :-moz-focusring pseudo-class to bring the functionality to Firefox ahead of a formal specification.

Why do we need :focus-visible?

Doesn't :focus do this already? Yes, but there are problems. The clearest illustration is a button that fires some JavaScript. Imagine an image carousel with buttons to swap between images. Let's say you've added a tabindex to the buttons so they can be selected with a keyboard, but when you go to test the carousel with your mouse, you see this outline around your gorgeous button:

Outline added by the browser on :focus

Not that you would want to do this (for accessibility concerns), but how do you get rid of it? By setting the :focus pseudo-class:

.next-image-button:focus {
  outline: none;

Now your button looks great when it is in focus, but what happens when a user tabs to your button without a mouse but a keyboard instead? They can't see where they've tabbed! That's a problem because now there's no way to tell which button is focused for keyboard actions:

One of these is focused, but you can't see it!

Is there a way to remove the blue focus outline but still show a focus that's more in line with the site design? Sure, you can have your cake and eat it too, thanks to :focus-visible!

:focus-visible only applies when you actually want a visual indicator to help the user see where the focus is. In other words, it can't hide the outline like :focus can. (Well, it could by blending it into the design, but whatever.) The two have to be used together in that sense. Let's add one to our button:

.next-image-button:focus {
  outline: none;
.next-image-button:focus-visible {
  outline: 3px solid blanchedalmond; /* That'll show 'em */

Now, when the keyboard is used to tab to the button, there will be a visual indication of the focus:

:focus-visible makes focus visible!

How do browsers determine when something is :focus-visible?

Browsers are given a bit of leeway to determine when this pseudo-selector should be applied to a given element using their own heuristics. First, let's look at the CSS4 working draft, and then we'll try to break it down. From the specifications:

  • If a user has expressed a preference (such as via a system preference or a browser setting) to always see a visible focus indicator, the user agent should honor this by having :focus-visible always match on the active element, regardless of any other factors. (Another option may be for the user agent to show its own focus indicator regardless of author styles.)
  • Any element which supports keyboard input (such as an input element, or any other element which may trigger a virtual keyboard to be shown on focus if a physical keyboard is not present) should always match :focus-visible when focused.
  • If the user interacts with the page via the keyboard, the currently focused element should match :focus-visible (i.e. keyboard usage may change whether this pseudo-class matches even if it doesn’t affect :focus).
  • If the user interacts with the page via a pointing device, such that the focus is moved to a new element which does not support user input, the newly focused element should not match :focus-visible.
  • If the active element matches :focus-visible, and a script causes focus to move elsewhere, the newly focused element should match :focus-visible.
  • Conversely, if the active element does not match :focus-visible, and a script causes focus to move elsewhere, the newly focused element should not match :focus-visible.

If that's a little abstract, here's an interpretation:

Situation Does :focus-visible apply?
The user says they always want the focus to be visible via a setting Yes
An element needs a keyboard to function (like text <inputs>) Yes
The user is navigating with a keyboard Yes
The user is navigating with a pointing device (like a mouse or finger on a touchscreen) No
A script causes focus to move from a :focus-visible element to another element Yes
A script causes focus to move from a non-:focus-visible element to another element No

It bears repeating: These are guidelines, and browsers will be able to make their own determination about what is selected by :focus-visible. We can expect that the obvious case of keyboard navigation will be handled in a predictable way, but the browsers have the ability to make the determination themselves, like any other feature.

See the Pen :focus-visible example by CSS-Tricks (@css-tricks) on CodePen.

Related Selectors

Browser Support

This browser support data is from Caniuse, which has more detail. A number indicates that browser supports the feature at that version and up.



Mobile / Tablet

iOS SafariOpera MobileOpera MiniAndroidAndroid ChromeAndroid Firefox

At the time of writing, browser support is only available by enabling an experimental flag, which you can do in browser settings (e.g. chrome://flags in Chrome). The exception is Firefox which uses the :-moz-focusring selector to do similar but not quite the same things.

Additional Information