Interactions
On this page
Focus indicator styles
Focus styles visually indicate when interactive elements like links and buttons are selected (usually via keyboard) and ready to receive input. All interactive elements are required to have a visible focus indicator to conform with the Web Content Accessibility Guidelines (WCAG).
To view keyboard focus states on a computer, open a web page in your browser and start pressing the Tab key. You will likely see the interactive elements on that page display some sort of indicator (e.g. an outline) as you navigate each of them.
How we style focus
Users who depend on focus indicators need styles that are clear and consistent, so they always know where they are in an experience. Our focus styles align with our brand standards and the latest WCAG guidance.
When focus is applied to an interactive element, we apply an outline that:
- is solid (not dashed or dotted).
- is 3px thick.
- is offset from the element by 3px.
- has 3:1 or greater contrast from the background colors just outside and inside of it.
- temporarily disables any transition animations on the element (so entering or exiting the focus state is not distracting).
Basic CSS
In CSS terms, here is some minimal code that meets these requirements:
:is(*, :hover):focus-visible {
outline-color: light-dark(--rh-color-blue-50, --rh-color-blue-30);
outline-offset: 3px;
outline-style: solid;
outline-width: 3px;
transition: none;
}
Styling options
Adjust the offset as needed. If an offset risks overflowing the focus ring outside the boundary of a page or the visible edge of a region, that offset can be removed or even made inset (see the example CSS below).
We have designated focus ring colors that align with our brand standards for both light and dark schemes.
| Property | Light scheme | Dark scheme |
|---|---|---|
| Focus ring color | --rh-color-blue-50 |
--rh-color-blue-30 |
Styling considerations
Note that there may be cases where a focus ring appears against a light background in dark mode and vice versa. For example, an inset focus ring for a text field may appear against a white background, even in dark mode. In these cases, you may need to manually override the default dark scheme ring color (--rh-color-blue-30) with the light scheme color (--rh-color-blue-50).
Example CSS
:is(*, :hover):focus-visible {
outline-color: light-dark(--rh-color-blue-50, --rh-color-blue-30);
outline-offset: 3px;
outline-style: solid;
outline-width: 3px;
transition: none;
}
/* Placeholder `.inset` class for inset focus. */
.inset:is(*, :hover):focus-visible {
outline-offset: -7px;
}
/* Placeholder `.no-offset` class for focus on element border. */
.no-offset:is(*, :hover):focus-visible {
outline-offset: 0;
}
/* Placeholder `.light-bg` class for focus against light backgrounds. */
.light-bg:is(*, :hover):focus-visible {
outline-color: --rh-color-blue-50;
}
/* Placeholder `.dark-bg` class for focus against dark backgrounds. */
.dark-bg:is(*, :hover):focus-visible {
outline-color: --rh-color-blue-30;
}
:focus:not(:focus-visible) {
outline: none;
}
Technical notes on the CSS
- We use the
color-schemeproperty on our websites, which allows us to use thelight-dark()function. If your website does not usecolor-scheme, you can separate out the dark mode focus ring color into another selector or query. The good news is that, even if you do not have acolor-schemeand you do not account for this, the fallback ring color of--rh-color-blue-50is WCAG conformant against both our dark and light backgrounds. - The
:is(*, :hover)pseudo-class prevents potential hover state style conflicts from making the focus outline disappear, for cases where an element has both keyboard focus and mouse cursor hover. - WCAG 2.2 requires 2px outlines for AAA conformance when focus is offset. However, inset focus must be greater than 2px. So, for the sake of consistency, we go with 3px in all cases.
- We add a
transition: noneproperty to temporarily remove any animations that may be on the element, so the focus ring appearance does not animate. - Inset focus rings receive a negative
outline-offsetjust large enough to leave some whitespace between the ring and the border of the element. - Note that we prefer
:focus-visibleto:focus. Avoid using the latter. In fact, our code above disables the latter.
Best Practices
Custom focus indicator styles
Always use the default focus indicator styles.
Do not create custom focus styles.