CSS - Pseudo-class :focus-visible



The :focus-visible pseudo-class in CSS represents an element that has received focus. This class is generally triggered when a user clicks, taps on an element or selects an element using the tab key of keyboard.

:focus-visible pseudo-class can be used to apply a different focus indicator, as per the user's preferred mode of functioning (either using a mouse or a keyboard).

Syntax

:focus-visible {
   /* ... */
}

:focus vs :focus-visible

The :focus and :focus-visible pseudo-classes in CSS are used to target elements that currently have keyboard focus, but they behave differently, especially with regard to user experience and accessibility.

:focus :focus-visible
Targets elements that have keyboard focus, whether that focus is achieved through keyboard navigation or by clicking with the mouse. Targets elements that have keyboard focus but are only visible when keyboard navigation is used. It helps improve the user experience by ensuring that styles are applied only when an element is focused via keyboard input and not when focused via mouse or touch input.
It doesn't take into account how the user reached the focused element, so it can include cases where a user clicked on an element with a mouse or tapped it on a touch device. It is especially useful for creating a more accessible and user-friendly experience for keyboard users, as it avoids applying potentially distracting or irrelevant styles to elements when clicked with a mouse.
a:focus {
// Styles for elements 
//that have keyboard focus 
}
button:focus-visible {
//Styles for elements 
//that have keyboard focus 
//and are visible through 
//keyboard navigation 
}

CSS :focus-visible Example

Let us see an example that shows the difference of :focus and :focus-visible. Try to bring the focus on the buttons using mouse, as well as keyboard and see the difference.

<html>
<head>
<style> 
   /* Apply focus styles only when accessed via keyboard navigation */
   button:focus-visible {
      outline: 2px solid green;
      background-color: yellow;
      }

   /* Apply focus styles for all focused elements */
   button:focus {
      outline: 3px solid blue;
   }
</style>
</head>
<body>
   <div>
      <button>focus-visible</button>
      <button>focus-only</button>
   </div>
</body>
</html>

Following is a classic example of button, that shows how selector :focus-visible stands out from :focus. We often would not want to see a focus ring after clicking on a button, but we would want to see a focus indicator on a button when navigating a website using a keyboard. In the below example, try using keyboard and then tabbing to see how :focus-visible helps us with the focus ring issue via keyboard and tabbing.

<html>
<head>
<style>
   label {
      display: grid;
      font-size: 18px;
      color: black;
      width: 400px;
   }

   select {
      padding: 10px 16px;
      font-size: 16px;
      color: black;
      background-color: #fff;
      border: 1px solid #597183;
      border-radius: 8px;
      margin-top: 25px;
      width: 300px;
      transition: all 0.3s ease;
   }

   .focus-only:focus {
      outline: 3px solid orange;
   }

   .focus-visible-only:focus-visible {
      outline: 4px dashed aqua;
   }
</style>
</head>
<body>
    <p>Compare what happens when you click on buttons with a mouse, versus when you tab through them using a keyboard. </p>
   <button class="focus-only"> focus-only button</button><br><br>
   <button class="focus-visible-only"> focus-visible button</button><br><br>
</body>
</html>

CSS :focus - fallback

Check browser support and compatability for :focus-visible with @supports and repeat the same styling within :focus rule, whether it works correctly in old browsers or not. Even when you fail to specify anything at all for :focus as a fallback option, the old browsers will display the native default outline. This demonstarted in the below syntax:

button:focus { /* some exciting button focus styles */ }

@supports (:focus-visible) {
      button:focus { /* undo all the above focused button styles */ }
      button:focus-visible { /* and then reapply the styles here instead */ }
}
Advertisements