Skip to content
Wiki
Focus
Visible Focus

Visible Focus

Any keyboard operable user interface has a mode of operation where the keyboard focus indicator is visible. (Level AA)

WCAG 2.4.7 (opens in a new tab)

Focus visible means that any custom component that is built must have a visual indicator when they have the keyboard's focus.

Sometimes, custom styles can override the default browser styles. This can be a problem if that override is simply to turn them off instead of making them consistent.

In the example below, try tabbing onto the buttons and hitting space to increment the counter. Both counters should increment fine, but the left one will be much harder to tell if it's focused or not.

Ways to fix

The simplest way to fix this is to ensure some focus styles are applied to the button. The right hand button effect was achieved by defining a new :focus-visible style and applying it to the button.

This is an example of how that CSS could look in a stylesheet:

.styled-button:focus-visible {
  outline: 2px solid purple;
}

Or in something more modern like styled components or sass

.styled-button {
  outline: none;
  background-color: green;
  ...etc...
 
  &:focus-visible {
    outline: 2px solid purple;
  }
}

Other considerations

A key part of this is making sure that the focus indicator is visible to all users. If the contrast of the added outline is too low then it cannot be considered a visible outline.

There are a couple different options to improve the visibility of the focus indicator.

One option is to alter the outline's colour when the elements are positioned on different coloured backgrounds. Another is to add an offset to the outline so that it doesn't need to contrast with the element and background, it only needs to contrast with the background.

Colour swap

This solution is achieved by changing the colour of the outline when the element is on a certain background colour.

For example, basing this on a prop in something like styled-components:

  &:focus-visible {
    outline: 2px solid ${props => props.$isOnDarkBackground ? 'yellow' : 'purple'};
  }

Outline offset

This solution is achieved by adding an outline-offset to the focus styles.

An outline offset of at least 2px helps with visibility by distinguishing it from the target element.

  &:focus-visible {
    outline: 2px solid green;
    outline-offset: 2px;
  }

Further options

These aren't the only ways to handle focus styles. The main aspect is to ensure it's visually distinguishable from the element and that anything a user can interact with can be interacted with a mouse and a keyboard equally.

Some other ways include:

  • Using the browser default focus indicators
  • Copying the hover style to ensure consistent styles
  • Changing the element's background colour
  • Other visual alterations like changing the element's size or adding an icon
  • Using a custom two-tone indicator (opens in a new tab) with 9:1 contrast of the 2 tones

All of these could be valid solutions, but it's important to make sure that the focus styles are visible to all users.

Resources