Cory Rylan

My name is , Google Developer Expert, Speaker, Software Developer. Building Design Systems and Web Components.

Follow @coryrylan
CSS

Don't Override CSS Outline Focus Styles

Cory Rylan

- 4 minutes

It's common to see websites remove the focus outline of focusable items. Removing outline styles, however, causes problems for many users. To keep your websites and web apps accessible focusable items must have a focus outline. Users with mobility disabilities may only be able to use a keyboard or non-mouse interaction with your web app. By removing the outline, your web app can quickly become unusable.

button {
  outline: 0; /* don't do this! */
}

Many developers and designers do not like the default system focus most browsers provide and often override it with a custom outline style.

button:focus {
  outline: 4px solid blue;
}

Custom outlines can introduce a new set of usability problems that we will cover in this post. First, let's look at a set of blue buttons for our demo.

Default Focus Style for Buttons

These are native HTML buttons with some minor style changes for the background color. These buttons can have some issues when focused. The focus outline can blend into the button, making it difficult to see.

Chrome Focus Styles

Improved Focus Styles for Chrome

This screenshot is an example running in Chrome. Each button is focused in the screenshot, and each looks slightly different. The first button is the default focus style in Chrome. We can see it blends in with the button. The second button shows a custom style that makes the outline larger but still blends in. We could change the color but will have to maintain multiple colors for each button color we may provide.

The last two buttons have native focus styles with some offset adjustments. As of Chrome 83 (announcement here), the focus styles have changed as well as the latest Edge. The new native focus style has two borders a light and dark that can be seen and altered by the browser-based on the background color. This feature is great to help ensure the focus is visible regardless of the surrounding colors.

But there is still a slight problem with this approach. The outline is directly next to our first button, making it difficult to see if the colors are similar. Some browsers mitigate this. For example, Safari adds an offset space between the button and the outline automatically.

Safari Focus Styles

Improved Focus Styles for Safari

As you can see, the offset Safari provides makes the focus much more visible. Unfortunately, Safari is currently the only browser that provides this default offset spacing. As we can see in Edge and Firefox, the first two buttons in each have no default offset.

Edge Focus Styles

Improved Focus Styles for Edge

Firefox Focus Styles

Improved Focus Styles for Firefox

Even though only Safari provides an offset, we can still adjust the CSS outline offset ourselves.

button {
  outline-offset: 2px;
}

The outline-offset CSS property will add space between the element and the focus outline, making a visual distinction. But again, we run into some browser compatibility problems.

Offset Outline with Native Defaults

In Chrome and Edge, the outline-offset property does not work on the default outline style. The outline-offset will work only on custom outline styles. We don't want to override the default outline since Chrome and Edge provide the helpful multi background outline support for accessibility.

So what can we do to improve this? We don't want to override the native behavior as it provides the best accessibility support, but we cant apply the outline-offset needed. We can use a trick to create a pseudo-element around our focusable item that is slightly larger to create an offset space.

button {
  /* for browsers that support native offset without custom outline */
  outline-offset: 2px;
}

button:focus {
  position: relative;
}

button:focus::after {
  content: '';
  position: absolute;
  top: -2px;
  left: -2px;
  right: -2px;
  bottom: -2px;
  outline: 5px auto -webkit-focus-ring-color;
}

When the button is focused, we can create a pseudo-element and position it slightly larger, about two pixels, and around the focused button. To apply the native focus style to the pseudo-element, we use this CSS property:

outline: 5px auto -webkit-focus-ring-color;

This CSS line is the CSS that triggers the internal native outline style in Chrome and Edge, which will preserve the multi background color support. Looking back at our examples, the last two buttons have the space between the button and the outline. Since we did not override the native outline style, the outline is automatically visible on light and dark backgrounds.

Chrome Focus Styles

Improved Focus Styles for Chrome

Accessibility can be tricky to get right across several browsers. Often browsers built-in defaults provide a solid foundation and are always improving. When adding custom overrides, we remove the browser's chance to provide better defaults in the future. As Web Developers, we must find that balance between customization and using what is built-in. Check out the full demo code below!

View Demo Code   
Twitter Facebook LinkedIn Email
 

No spam. Short occasional updates on Web Development articles, videos, and new courses in your inbox.

Related Posts

CSS

Design System Architecture - Managing CSS Themes

Learn how to use leverage CSS themes to create a flexible and efficient theming system in your design system architecture.

Read Article
CSS

Flow Charts with CSS Anchor Positioning

Learn how to use CSS Anchor Positioning to create flow charts and diagram with just CSS.

Read Article
CSS

Dynamic Contrast Layers with CSS Style Queries

Learn how to create contrasting layers with CSS style queries ensuring your UI is always the right contrast ratio.

Read Article