{"id":281230,"date":"2019-01-11T11:45:42","date_gmt":"2019-01-11T18:45:42","guid":{"rendered":"http:\/\/css-tricks.com\/?page_id=281230"},"modified":"2021-02-10T09:22:58","modified_gmt":"2021-02-10T17:22:58","slug":"focus-visible","status":"publish","type":"page","link":"https:\/\/css-tricks.com\/almanac\/selectors\/f\/focus-visible\/","title":{"rendered":":focus-visible"},"content":{"rendered":"\n

The :focus-visible<\/code> pseudo-class (also known as the “Focus-Indicated” pseudo-class) is a native CSS way to style elements that:<\/p>\n\n\n\n

  1. Are in focus<\/strong><\/li>
  2. Need a visible<\/strong> indicator to show focus (more on this later)<\/li><\/ol>\n\n\n\n

    :focus-visible<\/code> is used similarly to :focus<\/code>: to bring attention to the element that currently has the focus.<\/p>\n\n\n\n\n\n\n\n

    .element:focus-visible {\n  background-color: pink; \/* Something to get the user's attention *\/\n}<\/code><\/pre>\n\n\n\n

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

    Why do we need :focus-visible?<\/h3>\n\n\n

    Doesn’t :focus<\/code> 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<\/code> 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:<\/p>\n\n\n\n

    \"\"
    Outline added by the browser on :focus<\/code><\/figcaption><\/figure>\n\n\n\n

    Not that you would want to do this (for accessibility concerns<\/a>), but how do you get rid of it? By setting the :focus<\/code> pseudo-class:<\/p>\n\n\n\n

    .next-image-button:focus {\n  outline: none;\n}<\/code><\/pre>\n\n\n\n

    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:<\/p>\n\n\n\n

    \"\"
    One of these is focused, but you can’t see it!<\/figcaption><\/figure>\n\n\n\n

    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<\/code>!<\/p>\n\n\n\n

    :focus-visible<\/code> only applies when you actually want<\/em> a visual indicator to help the user see where the focus is. In other words, it can’t hide the outline like :focus<\/code> can. (Well, it could<\/em> 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:<\/p>\n\n\n\n

    .next-image-button:focus {\n  outline: none;\n}\n.next-image-button:focus-visible {\n  outline: 3px solid blanchedalmond; \/* That'll show 'em *\/\n}<\/code><\/pre>\n\n\n\n

    Now, when the keyboard is used to tab to the button, there will be a visual indication of the focus:<\/p>\n\n\n\n

    \"\"
    :focus-visible<\/code> makes focus visible!<\/figcaption><\/figure>\n\n\n

    How do browsers determine when something is :focus-visible?<\/h3>\n\n\n

    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<\/a>:<\/p>\n\n\n\n