css-focus-indicator-suppressed

Focus indicator must not be removed without a replacement

manualWCAG 2.4.7 (AA)confidence: mediumseverity: seriousoperable

Flags elements in the tab order whose focus outline is removed, by a :focus/:focus-visible rule or by a rule with no state such as a { outline: none }, with no replacement indicator (border, box-shadow, background, ...) in any focus rule matching them.

Applies to. Elements in sequential focus navigation (tabbable and rendered) on a page whose accessible stylesheets contain at least one rule that removes the outline. With no such rule anywhere, every element keeps the user agent's own indicator and there is nothing to check.

Expectation. No element is matched by a rule that removes the outline (outline: none, outline: 0, outline-color: transparent, ...) unless some focus rule matching it draws a replacement: a border, box-shadow, background, color change, a positive outline of its own, or a ::before/::after decoration. The removing rule is either a :focus/:focus-visible rule, or a rule with no state at all (a { outline: none }, * { outline: 0 }): an author declaration outranks the user agent's focus outline whatever its specificity, so it removes the indicator in the focused state too (WCAG F78). A rule that removes it only under :not(:focus-visible) keeps it for keyboard focus and is not counted; nor is the focus-visible polyfill's form of it, :not(.focus-visible) under .js-focus-visible, or :not([data-focus-visible-added]) under [data-js-focus-visible].

What a finding reports.

  • suppressingSelectors: the selector of each style sheet rule that removes the element's outline, one item per selector.

These data.details fields help to read and reproduce a finding. Apart from reasonCode and the few fields Output schema names as stable, they are not a stable contract: a field may be renamed or dropped in a minor release, so don’t build on them.

Examples

can't tell
<style>.reset-only:focus { outline: none; }</style>
<a class="reset-only" href="/pricing">Pricing</a>

:focus { outline: none; } removes the focus indicator, and no other rule matching this link draws a replacement.

can't tell
<style>a { outline: none; }</style>
<a href="/news">News</a>

A rule with no :focus still applies while the link has focus, and it outranks the browser's own focus outline (F78). No focus rule draws a replacement.

n/a
<style>.reset-shadow:focus { outline: none; box-shadow: 0 0 0 3px navy; }</style>
<button class="reset-shadow" type="button">Send</button>

The same rule that removes the outline draws a box-shadow in its place.

How to check

When this rule can’t decide, it reports cantTell and leaves the question to a person. Each question it can ask is listed here under its reason code, with the steps to answer it. A finding carries the same steps as howToCheck, in the scan’s language. See Output schema.

FOCUS_INDICATOR_SUPPRESSED

  1. Click just before the element the report names, then press Tab until it has focus.
  2. Look at the element, and the area around it, for any visible change when it receives focus.
  3. Press Tab and Shift+Tab to move focus off and back on, comparing the two states.

Pass. A visible indicator, such as an outline, border, underline, color or background change, shows when the element has focus.

Fail. Nothing visible changes when the element receives focus, which fails WCAG 2.4.7 (F78).

View source