Skip to content

How Focus Indicator Contrast Is Evaluated ​

When you navigate a page with the keyboard, each interactive element should show a visible focus indicator that stands out clearly from its surroundings. The tool checks that indicator against the WCAG minimum of 3:1 — and, importantly, it measures it against the correct background depending on where the indicator is drawn.


Internal versus external indicators ​

The tool first looks at how the focus indicator is painted relative to the control.

Internal indicators sit on top of, or within, the control itself:

  • a border that appears or changes colour on focus
  • an inner ring hugging the inside edge
  • an underline that appears on focus
  • a background colour change on the control
  • a text colour change on the control's label

External indicators are drawn around the control, in the space next to it:

  • an outline — the classic focus ring outside the element
  • an outer ring that wraps around the outside edge

This classification decides what the indicator is compared against.


Which visual styles are evaluated ​

The tool inspects the element before and after it receives focus and looks for a change in any of these:

StyleTreated as
OutlineExternal
Outline drawn inside the elementInternal
BorderInternal
Inner shadow ringInternal
Outer shadow ringExternal
Text decoration (underline / overline)Internal
Background colour changeCompared against the surrounding background
Label text colour changeInternal

Only styles that appear or change on focus are considered the focus indicator. A style that is already present when the element is unfocused — a permanent border, say — is not treated as the indicator. There is one exception: some components display a permanent ring on a wrapper element as their focus cue, and that ring is evaluated too.

Cosmetic drop shadows — those with a visible offset or blur, used for depth — are ignored. They are decorative, not focus rings.


What the indicator is compared against ​

This is the core of the internal-versus-external logic.

Internal indicator → compared against the control's own background. An inner ring or a border is measured against the button's own fill colour. If the button's background changes on focus, the focused background is used, since that is what the user actually sees behind the indicator.

External indicator → compared against the surrounding background. An outline or an outer ring is measured against the background directly behind it — the nearest containing element with a solid, non-transparent background.

Background colour change → compared against the surrounding background. When the whole control changes colour on focus, the new colour fills the control, so it is compared against the page or section background around it.

The tool prefers exact colour values from the stylesheet when it can read them, and falls back to sampling the rendered pixels of the focused and unfocused states when it cannot.


How pass and fail are decided ​

  1. The element must first have a visible focus indicator at all. If focusing it produces no perceptible visual change — and no text cursor appears in a text field — it is reported as focus not visible.
  2. If an indicator is present, its colour is compared against the appropriate background and a contrast ratio is calculated.
  3. 3:1 or higher passes. Below 3:1 is reported as a contrast failure, with both colours and the measured ratio.

If a control has more than one indicator — both a border and a ring, say — the element passes as soon as any one of them meets 3:1. The user only needs one sufficiently visible cue. See Focus Indicators with Multiple Focus Styles.


Examples ​

Passes

  • A button on a dark page that gains a light outline on focus — light ring against dark page, ≥ 3:1.
  • A control with a light interior that shows a dark inner ring on focus — dark ring against light control, ≥ 3:1.
  • A link that gains a strongly contrasting underline against the page background.
  • An element using the browser's native focus ring (see below).

Fails

  • A light-grey outer ring around a control sitting on a white page — ring and page are nearly the same, below 3:1.
  • An inner ring only slightly darker than the control's own fill.
  • A focus colour that only contrasts against the wrong background — an outer ring that would pass against the control but fails against the actual page behind it.

Known limitations and intentional exclusions ​

  • The browser's native focus ring. When an element relies on the browser's own default ring, the contrast check is skipped. The browser adapts that ring at paint time and it is exempt from author-defined contrast requirements, so it is treated as visible and not failed.
  • Text fields showing a cursor. If focusing an input shows a blinking text cursor, that counts as a visible focus cue and the element is not flagged for missing visibility. A wrapper ring, if present, is still checked for contrast.
  • Gradient or image backgrounds. When the relevant background is a gradient or an image rather than a solid colour, an exact ratio cannot be computed reliably. The tool skips such backgrounds and searches upward for the nearest solid one; if none is available, the result may be approximate.
  • Unsupported colour formats. Modern colour notations the tool cannot interpret are skipped rather than guessed at.
  • Duplicate controls. Repeated controls that share the same label and styling — several identical "View" buttons, for example — may be grouped, so the issue is reported once rather than for every occurrence.
  • Elements styled only by browser defaults. Controls that receive no focus styling from the site are handled by the visibility logic and may not enter the contrast comparison at all.
  • Approximate colours. In some cases the indicator or background colour is sampled from the rendered page rather than read exactly from the stylesheet. Those values can differ slightly from the authored colour and are noted as approximate in the report.

In short ​

The tool decides whether a focus indicator is internal or external, measures its colour against the control's own background (internal) or the surrounding background (external), and reports a pass when the contrast is 3:1 or higher — with the browser's native focus ring and non-solid backgrounds handled as documented exceptions.


WCAG reference ​

Success Criterion 1.4.11 Non-text Contrast (Level AA)