Skip to content
Back to blog
WCAGfocus visiblekeyboardhow-to

How to make keyboard focus visible (WCAG 2.4.7)

Keyboard focus visible is WCAG 2.4.7, Level AA. What it requires, the CSS that breaks it, and how to build a focus indicator that passes.

P

Pavel Charkasau

WCAG 2.4.7, Focus Visible, asks for one thing: a keyboard user must be able to see which element has focus. The criterion reads, "Any keyboard operable user interface has a mode of operation where the keyboard focus indicator is visible" (W3C). It is a Level AA success criterion, so it applies to almost every real conformance claim, and it is the one people break most often with a single line of CSS. To fix a focus visible problem you do two things. First, stop removing the indicator: find every outline: none and outline: 0 in your stylesheets and confirm each one puts a visible focus style back. That deletion, with no replacement, is failure F78 (W3C). Second, make the indicator you keep or add actually visible against its background, which usually means a :focus-visible rule with an outline that has real contrast and a bit of offset. The rest of this guide is those two moves in detail: what the criterion requires, the CSS that breaks it, a focus style that passes, and what a scanner can and cannot check for you.

What does WCAG 2.4.7 actually require?

The bar is lower than most people assume. The criterion needs one mode of operation where the keyboard focus indicator is visible, not a visible indicator in every state at all times (W3C). A keyboard user tabbing through your page has to be able to tell, at each stop, where they are. That is it.

Two things sit outside 2.4.7 and trip people up. The criterion says nothing about how the indicator looks — its size, its contrast, its shape. A faint one-pixel dotted line technically satisfies 2.4.7 even if it is hard to see. The quality bar lives in a separate, newer criterion (more on that below). And 2.4.7 is about the keyboard. A mouse user who never sees a focus ring is not a 2.4.7 problem, which is exactly why :focus-visible exists: it lets you show the ring to keyboard users and hide it from mouse clicks, without failing anyone.

WCAG 2.2 became a W3C Recommendation on 5 October 2023, and 2.4.7 carried over from 2.1 unchanged (W3C). If you fixed it years ago, it still passes the same way today.

What CSS breaks focus visible?

Almost always one of two lines, written to make focus rings "look cleaner":

/* both of these remove the indicator with nothing to replace it */
:focus { outline: none; }
button:focus { outline: 0; }

Stripping the outline and putting nothing back is failure F78, "styling that removes or renders non-visible the visual focus indicator" (W3C). The design reason is understandable — the default ring shows up on mouse clicks too, and designers dislike that — but the fix for "I don't want a ring on click" is not "remove the ring." It is :focus-visible.

The other way to fail is with script. F55 covers using script to remove focus when a component receives it, so focus never visibly lands anywhere (W3C). This shows up in custom widgets that call blur() on focus, or that move focus off-screen without a visible cue. Rarer than the CSS case, but it fails the same criterion.

One more quiet failure: an indicator that is technically present but hidden behind other content. A custom color scheme where the focus outline is the same color as the background leaves nothing to see. The outline is "there" in the DOM and invisible to the eye, which is still an F78.

How do I write a focus style that passes?

Add the indicator back with :focus-visible, and give it contrast and offset so it reads on any background. Here is a style that passes 2.4.7 and holds up well:

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

/* remove the ring only for genuine mouse/touch focus, never for keyboard */
:focus:not(:focus-visible) {
  outline: none;
}

The first rule is the sufficient technique C15, using CSS to change presentation when a component receives focus, paired with G195, an author-supplied visible focus indicator (W3C). :focus-visible itself is technique C45, using the pseudo-class for keyboard focus indication (W3C). The browser applies :focus-visible when it heuristically decides the user is likely relying on the keyboard, so a keyboard user gets the ring and a mouse user clicking a button does not. That is the outcome designers actually wanted when they reached for outline: none.

Two details matter. outline-offset pushes the ring a couple of pixels away from the element so it does not blend into the border. And outline, not border or box-shadow, is the safer choice: outlines do not change layout, and unlike box-shadow they stay visible in Windows High Contrast Mode. If you need to match a rounded corner, box-shadow can work, but add an outline: 2px solid transparent fallback so High Contrast users still get a ring.

If you cannot rely on :focus-visible for an old browser, the plainer sufficient path is G165, using the default platform focus indicator, which means: do not override it at all (W3C). The most reliable focus style is often the one the browser already ships. You only need author CSS when you have a reason to change it.

Does the focus indicator need enough contrast?

For 2.4.7 alone, no — the criterion asks for visible, not for a specific contrast ratio. But two other criteria set the quality bar, and you should design to them.

2.4.11 Focus Not Obscured (Minimum) is Level AA and new in WCAG 2.2. It says that when a component receives keyboard focus, it "is not entirely hidden due to author-created content" (W3C). This is the sticky-header trap: you tab to a link, the focus indicator is technically visible, but a fixed header or a cookie banner sits on top of it and you cannot see where focus went. Because it is Level AA, it counts toward the same conformance claim as 2.4.7. Test it by tabbing with a sticky header in place, not just on a static page.

2.4.13 Focus Appearance is the one that governs how the ring looks, and it is Level AAA, new in 2.2. It asks that the focus indicator be at least as large as a 2 CSS pixel thick perimeter of the component, and have a contrast ratio of at least 3:1 between the focused and unfocused states of the same pixels (W3C). Most teams do not claim AAA, so 2.4.13 is not usually a hard requirement. I still use its numbers as a design target, because "2px and 3:1 contrast" is a concrete spec you can build once and reuse. The 2px solid outline in the example above is chosen to meet it. You can check the 3:1 figure against your background with our contrast checker.

How do I test focus visible across a whole site?

Tab through it. There is no substitute for putting your hands on the keyboard and pressing Tab from the top of the page to the bottom. Watch for three things: a stop where nothing visibly changes (a missing or removed indicator), a stop where the ring is there but washed out against its background, and a stop where a sticky element covers the focused control.

A few practical checks:

  • Test on real backgrounds, not the default white. A dark outline on a dark footer disappears. If your site has light and dark sections, your focus style has to survive both, which argues for a two-color indicator (technique C40) (W3C).
  • Test the interactive components, not only the links. Custom dropdowns, date pickers, and modal dialogs are where scripted focus handling (and F55) hides.
  • Test with a sticky header on screen to catch the 2.4.11 obscured case.

Can a scanner detect a focus visible failure?

Partly, and it helps to know which part. A scanner is good at finding the mechanical failure: a :focus { outline: none } rule with no visible replacement is a static-analysis catch, and tools flag it. What a scanner cannot judge is whether the indicator that is present is easy enough to see, whether it survives a dark background, or whether a sticky header hides it when you actually tab there. Those are visual, stateful questions that need a person.

That split is the usual one for accessibility testing. Across more than 2,000 audits, Deque found automated tools caught about 57% of issues by volume, with other estimates near 30% by the share of success criteria a tool can evaluate at all (Deque). Focus visible sits right on that line: the missing-outline half is machine-detectable, the is-it-actually-visible half is not.

The opinion I hold here: outline: none in a shared stylesheet is one of the few accessibility bugs worth blocking at code review, because it is cheap to catch and expensive to notice later — nobody sees a missing focus ring until a keyboard user hits it. Overlay widgets that promise to "add focus indicators" at runtime miss the point too; they inject a ring you cannot style to match your design and cannot test in your own CSS. Fix it in the stylesheet, once, with :focus-visible. WCAG 2.4.7 is part of EN 301 549, the standard behind the European Accessibility Act, and it applies under the ADA through WCAG as well, so a visible focus ring is part of the legal floor in both the EU and the US, not just a nicety.

Frequently asked questions

What is WCAG 2.4.7 Focus Visible in one sentence?

It requires that a keyboard user can see which element currently has focus — any keyboard operable interface must have a mode where the focus indicator is visible (W3C).

What conformance level is Focus Visible?

Level AA. That means it applies to any site claiming WCAG 2.1 or 2.2 AA conformance, which is the level most laws and procurement rules point to (W3C).

Is it OK to remove the default focus outline?

Only if you replace it with a visible one. Removing the outline with outline: none and adding nothing back is failure F78. Use :focus-visible to keep a clear ring for keyboard users while hiding it on mouse clicks (W3C).

Does the focus indicator have to meet a contrast ratio?

Not under 2.4.7, which only requires visible. The 3:1 contrast and minimum-size numbers come from 2.4.13 Focus Appearance, a Level AAA criterion new in WCAG 2.2 (W3C). Most teams use those numbers as a design target rather than a hard requirement.

Why does my focus ring disappear behind the header?

That is a separate failure, 2.4.11 Focus Not Obscured (Minimum), a Level AA criterion in WCAG 2.2. A sticky header or banner that entirely covers the focused control fails it even if the ring itself is fine (W3C).

Find the removed focus styles on your site

The fastest start is to see where your CSS strips focus indicators, then tab through the pages that matter to check the ones that remain. Run a free scan to surface the machine-detectable focus failures across your key pages, and use our WCAG checklist for the manual checks a scanner cannot make: is the ring visible on every background, and does anything cover it when you get there. The scanner finds the missing outlines; you confirm the rest with the Tab key.


Pavel Charkasau, founder, wcagc.com. Last updated 6 August 2026.

Sources