Focus indicators: visible, high contrast and never hidden

A focus indicator is the outline or highlight that shows which element has keyboard focus. WCAG requires that it can be seen (2.4.7, Level AA), that a custom one has at least 3:1 contrast with the colors next to it (1.4.11, AA), and that content you add, such as a sticky header, never hides the focused item entirely (2.4.11, AA). Keep the browser's default ring or style your own with :focus-visible, and never remove the outline without putting something in its place.

Published . Last reviewed .

A focus indicator is the visible change, usually an outline or ring, that shows which element has keyboard focus. W3C defines it as the pixels changed to show that a component is in a focused state. Without one, a sighted keyboard user cannot tell what the next keystroke will act on. W3C's Understanding page for 2.4.7 names keyboard users and people with attention, short-term memory or executive function limitations as beneficiaries, and its page for 2.4.11 adds switch and voice input users and people who use screen magnification.

Three Level AA criteria cover focus indicators, and two Level AAA criteria describe the stronger version. This guide covers what each asks, how to style a ring that passes, and how to keep it visible. The full keyboard routine is in our keyboard accessibility test, where focus goes next is in focus order and tabindex, and contrast in general is in the color contrast guide.

What WCAG asks of a focus indicator

The WCAG 2.2 criteria that govern keyboard focus indicators
CriterionLevelWhat it asksW3C explanation
2.4.7 Focus VisibleAAA mode of operation where the keyboard focus indicator is visible. The criterion does not say what form the indicator takes; contrast is covered by 1.4.11.Understanding 2.4.7
1.4.11 Non-text ContrastAAThe visual cue for a focused component has at least 3:1 contrast against adjacent colors. An unchanged browser default is exempt from the ratio but must still be visible.Understanding 1.4.11
2.4.11 Focus Not Obscured (Minimum)AA, new in 2.2A focused component is not entirely hidden by author-created content, such as a sticky header, footer or cookie banner.Understanding 2.4.11
2.4.12 Focus Not Obscured (Enhanced)AAA, new in 2.2No part of the focused component is hidden by author-created content.Understanding 2.4.12
2.4.13 Focus AppearanceAAA, new in 2.2An indicator at least as large as a 2 CSS pixel thick perimeter of the unfocused component, with 3:1 contrast between the same pixels in the focused and unfocused states. Unchanged browser indicators are excepted.Understanding 2.4.13

Read together, 2.4.7 requires that an indicator exists, 1.4.11 that a custom one can be seen against its surroundings, and 2.4.11 that the focused item is not covered up. W3C says 2.4.7 requires that a visible indicator exists and 2.4.13 defines a minimum level of visibility. It measures the change between the focused and unfocused states, where 1.4.11 measures contrast with the neighbors, so an indicator can pass one and fail the other.

Neither AAA criterion is part of Level AA, and WCAG 2.2 itself says it is not recommended that Level AAA conformance be required as a general policy for entire sites, because some content cannot satisfy every AAA criterion. In GotAlt's reading, 2.4.13 is still a useful design target for an indicator, because it turns "visible" into a size and a ratio (see WCAG conformance levels).

Is the browser's default focus ring enough?

It can be. W3C lists using the platform's default focus indicator (technique G165) as sufficient for 2.4.7. Understanding 1.4.11 exempts a component whose appearance the browser determines and the author has not modified, and 2.4.7 still requires the indicator to be visible. G165 adds a reason to keep it where it works: users can customize the platform's indicator, and that customization carries over only when the page uses the native one.

The default has two weaknesses. W3C's 2.4.13 page says default indicators vary by component, browser and operating system, and can be difficult to see in some browsers. And the 2.4.13 exception for an unmodified default holds only when the author changes neither the indicator nor the background behind it. In GotAlt's reading, test a default ring on any button or panel you have recolored.

Why outline: none breaks keyboard use

The CSS outline property controls the browser's default ring. MDN says a value of 0 or none removes the browser's default focus style, and that an element you can interact with must have a visible focus indicator. WebAIM advises avoiding outline:0, outline:none and other styles that remove or limit the visibility of keyboard focus indicators.

W3C names the removal as failure F78, which applies to 2.4.7, 1.4.11 and 2.4.13. Its examples include a rule that removes the outline, a thin dotted link outline that looks like the focus indicator, and a thick border in the same color. Failure F55 covers a script that calls blur on an element as soon as it receives focus.

/* Fails: the ring is gone and nothing replaces it */
button:focus {
  outline: none;
}

A second trap is the cascade. MDN says each pseudo-class adds 0-1-0 to a selector's specificity, so a:focus (0-1-1) outweighs a site-wide :focus-visible rule (0-1-0), and a reset such as a:focus { outline: none } can cancel the ring you wrote. Search your CSS for outline, then Tab through the page. The MDN specificity page explains the weights.

Style your own ring with :focus-visible

Browsers once keyed focus rings to :focus alone, and, as MDN's :focus-visible page records, some authors removed the rings because of how they looked. The :focus-visible pseudo-class matches a focused element only when the browser decides focus should be made evident: generally after keyboard use, and in a text box too, but not after a mouse click on a button. It changes how the indicator looks without changing when it appears.

:focus-visible {
  outline: 3px solid #1a56db;
  outline-offset: 2px;
}

MDN lists :focus-visible as Baseline widely available, in browsers since March 2022. W3C's technique C45 covers the approach and adds a condition: it is sufficient only if the styles give a visible indicator.

Contrast, thickness and changing backgrounds

3:1 against which colors?

When you style the indicator, 1.4.11 applies, and Understanding 1.4.11 says where to measure. A ring outside the component needs 3:1 against the background the component sits on. A border that changes color needs 3:1 against both adjacent colors. An indicator inside the component is measured against the colors inside it, and for a split indicator either part may contrast. A ring around a button on a colored panel is therefore checked against the panel, not the page.

How thick?

W3C's 2.4.13 page says a solid outline must be at least 2 pixels thick, and that an indicator inset inside the component must be thicker to cover the same area (its example uses 3 pixels). Treat 2 pixels as the floor, and prefer an outline outside the component with a small offset.

One ring for every background

No single color passes everywhere. The table shows contrast ratios computed with GotAlt's contrast checker, using the WCAG formula, for three single-color rings on four backgrounds and the best band of a two-color ring.

Contrast ratios of focus rings against four backgrounds; 3:1 is the 1.4.11 threshold
RingWhite #ffffffLight gray #e5e7ebDark blue #1e3a8aNear-black #111111
Blue #1a56db6.18:1, passes4.99:1, passes1.67:1, fails3.05:1, passes
White #ffffff1.00:1, fails1.23:1, fails10.35:1, passes18.88:1, passes
Near-black #1a1a1a17.40:1, passes14.05:1, passes1.68:1, fails1.08:1, fails
Two-color: white and #1a1a1a17.40:1, passes14.05:1, passes10.35:1, passes18.88:1, passes

W3C's technique C40 gives the rule behind the last row: pair a light and a dark color with at least 9:1 contrast between them, and at least one of the two reaches 3:1 against any solid background. White and #1a1a1a are 17.40:1 apart. C40 builds the indicator from an inner outline and an outer box-shadow, each band 2 CSS pixels thick:

:focus-visible {
  outline: 2px solid #ffffff;
  box-shadow: 0 0 0 4px #1a1a1a;
}

C40 says this holds only over one solid background at a time, not over an image, a gradient or another component. A ring over a photo is the problem our text over images guide describes for text. Check the ring in every theme, including dark mode, and pick its color with your brand palette in mind.

Rings that get cut off or disappear

  • Clipping. MDN says overflow: hidden clips content at the element's padding box, so an outside outline at the edge of such a parent can be cut off. A negative outline-offset draws it inside instead. This is GotAlt's practical note, not WCAG text.
  • Forced colors. In forced colors mode, of which Windows High Contrast mode is the example, MDN says box-shadow is forced to none and outline-color takes browser-specified values. C40 warns against relying on box-shadow alone for this reason, which is why the example above keeps the outline.
  • Timers. W3C's intent text for 2.4.7 says that when keyboard focus is shown, it must remain visible, so an indicator that fades out on a timer is a problem.

Keeping focus from being hidden

Success criterion 2.4.11 is about the focused component, not the ring: it must not be entirely hidden by author-created content. W3C names sticky headers, sticky footers and non-modal dialogs as the usual causes. A sticky element stays in view as the page scrolls. At Level AA, partly covering the component is allowed, though W3C says authors should minimize how much and how often, and covering all of it fails. Failure F110 describes a footer that covers the focused item as the user tabs down and a header that does so as the user tabs back up, so test both directions.

A sticky cookie banner that fully covers a focused component fails, W3C says, and approaches that pass include making the banner modal, using scroll padding, or closing it when it loses focus. Our accessible modals guide covers modals. For scroll padding, technique C43 uses the scroll-padding property to leave room around the scrolling area, so a focused item scrolls clear of a fixed bar:

html {
  scroll-padding-top: 5rem;
  scroll-padding-bottom: 6rem;
}

Set the values to your bars' real heights, and check at narrow widths and at 200% zoom. Content the user opens is treated differently: a menu or tooltip that closes when it is no longer in use does not fail, and a persistent panel such as a chat window may cover the item if the user can reveal it without moving focus. W3C adds that a semi-transparent overlay can pass 2.4.11 but fail 1.4.11 if the indicator is no longer distinguishable through it. Level AAA 2.4.12 allows no part of the component to be hidden.

Which WCAG version covers this?

Criteria 2.4.7 and 1.4.11 are in WCAG 2.1, so standards that name WCAG 2.1 Level AA include them, such as the ADA Title II web rule (see our Title II deadline guide) and EN 301 549 v3.2.1 (see our EN 301 549 page). Criteria 2.4.11 to 2.4.13 arrived in WCAG 2.2, so they apply where a law or contract names 2.2, as GOV.UK's guidance for UK public sector bodies does (see UK accessibility law). See which WCAG version to use and what's new in WCAG 2.2. This page is general information, not legal advice.

Check it yourself

  1. Tab through each page template. At every stop, ask whether you can see where focus is, including in dark sections, over photos, in custom widgets and in open dialogs. Our keyboard accessibility test has the full routine.
  2. Measure the ring. Enter the ring color and the color next to it in the free contrast checker. A custom ring needs 3:1. For a two-color ring, check that the bands are at least 9:1 apart and that one passes on each background.
  3. Force the state. In Chrome DevTools, select an element and use the :hov panel in the Styles tab to switch on :focus or :focus-visible, as Google's DevTools CSS reference describes.
  4. Test the sticky content. Tab down and back up near any sticky header, footer or banner, at a narrow width and at 200% zoom.
  5. Run the page check. The accessibility bookmarklet reads the rendered page, including pages behind a login, and measures text contrast. It does not check focus indicators, and its limits list says it cannot tell whether a page works with a keyboard, so use it beside the steps above, not instead of them.

The free scan reads the HTML your server sends, and whether a ring is visible depends on computed styles, which a markup parser never produces (what we check explains why), so scanners miss issues like this. To track every Level A and AA criterion, use the WCAG 2.2 checklist.

Focus indicator questions

What is a focus indicator?

A focus indicator is the visual change that shows which element currently has keyboard focus, most often an outline or ring. W3C defines it as the pixels changed to show that a component is in a focused state. Browsers draw one by default, and WCAG 2.4.7 requires that keyboard users can see one.

Is it ever okay to use outline: none?

Only if you replace it with another visible indicator, such as your own outline, a border or a background change. W3C lists removing the outline with nothing in its place as failure F78, and MDN says an element you can interact with must have a visible focus indicator. Browsers already hide the default ring after a mouse click on a button, so removal is rarely needed.

What contrast ratio does a focus indicator need?

If you style the indicator yourself, WCAG 1.4.11 asks for at least 3:1 against the adjacent colors. An unchanged browser default is exempt from that ratio but must still be visible. The AAA criterion 2.4.13 separately asks for a 3:1 change between the focused and unfocused states, which is a different measurement.

What is the difference between :focus and :focus-visible?

The :focus pseudo-class matches whenever an element has focus, including after a mouse click. The :focus-visible pseudo-class matches only when the browser decides focus should be made evident, such as after keyboard use, and in text boxes, as MDN explains. Style the ring with :focus-visible so keyboard users see it without it appearing on every click.

Does WCAG require a focus ring when someone clicks with a mouse?

No. Criterion 2.4.7 requires a mode of operation where the focus indicator is visible, and W3C says a visible indicator may also help mouse and pointer users, as a best practice rather than a requirement. Browsers usually hide the ring after a mouse click on a button but show it in text fields. What matters is that keyboard users always see it.

What does Focus Not Obscured mean?

It is WCAG 2.4.11, Level AA, new in WCAG 2.2. When a component receives keyboard focus, content the author created, such as a sticky header, footer or cookie banner, must not hide it entirely. Partly covered passes at AA. The AAA version, 2.4.12, allows no part to be hidden. CSS scroll padding is one fix.

Is Focus Appearance (2.4.13) required?

It is Level AAA, so a Level AA target does not include it, and WCAG 2.2 says it is not recommended that Level AAA conformance be required as a general policy for entire sites. It is still a useful design target: a solid outline at least 2 CSS pixels thick with strong contrast is hard to miss. Check what your law or contract names before you decide.

Run the automated part first

The free scan reads the HTML your server sends, so it cannot see whether a focus ring is drawn or hidden. It runs 16 rule-based checks on up to 3 pages of your site and flags what a parser can find, such as positive tabindex values. No signup.

Scan my site for free