( Operable / WCAG 2.4.7 )

Focused element has no visible focus indicator

SeriousLevel AAWCAG 2.4.7 — Focus Visible

What is this issue?

An interactive element (a button, link, or form field) has CSS that removes its browser-default focus outline, most commonly outline: none or outline: 0 applied globally with a universal selector or reset stylesheet, and no other style provides a visible replacement when the element receives keyboard focus. Tabbing to the element produces no visual change at all: no outline, no border shift, no background change, nothing distinguishing it from its unfocused state.

This rule sits first in a trio of related WCAG 2.2 focus checks: 2.4.7 Focus Visible (this page) asks the binary question of whether an indicator exists at all. Focus indicator does not meet minimum size or contrast (2.4.13) and Focused element is hidden behind a sticky header or footer (2.4.11) both assume this check already passes, and dig into whether the existing indicator is good enough and actually visible on screen.

Why does this matter?

Focus indicator: the visible outline, border, or highlight that shows which element currently has keyboard focus. It is the only thing that tells a sighted keyboard user where they are on a page. Without one, every Tab press moves them somewhere new with zero visual confirmation of where that somewhere is, turning ordinary navigation into a guessing game about what will happen if they press Enter next.

This is one of the most common and highest-impact keyboard-accessibility failures on the web, largely because it’s invisible to anyone testing only with a mouse: a page with outline: none applied globally looks completely normal to a sighted mouse user, since they never trigger the focus state that’s missing. The defect only surfaces the moment someone actually tries to use the keyboard, which is exactly the population least likely to be represented in a typical visual QA pass.

Who is affected?

  • Low vision users: rely on a strong, clearly visible focus indicator to track position on a page they may already be viewing with magnification or reduced acuity; with none present, keyboard navigation becomes effectively unusable.
  • Keyboard users: lose all visual confirmation of their current position on the page, forcing them to track focus by memory and by guessing what each Tab press likely landed on.
  • Motor impairments: users navigating with a switch device or head pointer that simulates keyboard input face the identical blindness, with no mouse-driven fallback available to confirm position visually.
  • Cognitive disabilities: users who rely on clear, consistent visual feedback to build confidence while completing a task lose that feedback loop entirely, increasing the mental effort every interaction requires.

What users experience

Priya has low vision and navigates mostly by keyboard, using a screen magnifier for the small percentage of content she reads visually. On a checkout page, a global CSS reset applies outline: none to every focusable element with no replacement style. She tabs through the payment form and sees no change anywhere on screen as focus moves (no ring, no border, no highlight), so she has no way to confirm which field is currently active before she starts typing her card number. She resorts to tabbing once, typing a single test character, and checking which field it landed in before continuing, turning a simple form into a multi-step verification exercise for every single field.

How do I fix it?

Never remove the default focus outline without providing a visible replacement in the same rule or a paired rule. This works because it guarantees every interactive element keeps some form of visible focus indicator at every point in the page’s lifecycle: the specific style can change, but the guarantee that one always exists shouldn’t.

Use :focus-visible instead of :focus when writing the replacement style, so the indicator shows for keyboard navigation specifically without also appearing on every mouse click, which some teams find visually noisy and remove the outline entirely to avoid, exactly the mistake this rule exists to catch. A visible custom style commonly means a solid outline with clear color contrast against the background, though other techniques (a background color change, a box-shadow ring) can work as long as the change is genuinely easy to notice at a glance.

Code Examples

Before
* {
  outline: none;
}
button:focus {
  outline: 0;
}
After
:focus-visible {
  outline: 3px solid #0066cc;
  outline-offset: 2px;
  border-radius: 2px;
}

/* Optional: suppress the ring for mouse clicks, keep it for keyboard */
button:focus:not(:focus-visible) {
  outline: none;
}
button:focus-visible {
  outline: 3px solid #0066cc;
  outline-offset: 2px;
}

The fix replaces a blanket removal with a targeted one: :focus-visible gives keyboard users a clear, custom-styled indicator, while :focus:not(:focus-visible) (supported in every modern browser) suppresses that same indicator specifically for mouse clicks, if the visual noise of an outline on every click is a genuine design concern; the outline itself is never removed without this replacement present.

Common Mistakes

Mistake: “The default browser outline looks inconsistent across browsers, so removing it entirely is cleaner.” Inconsistent default styling is a real design concern, but the fix is replacing the default with a consistent custom style, not removing it with nothing in its place. outline: none alone solves the visual-inconsistency complaint by eliminating the indicator for everyone, which trades a cosmetic issue for a functional one.

Mistake: “We tested by clicking through the page and everything looked fine.” Clicking with a mouse never triggers the failure this rule catches, since mouse-focused elements aren’t what a keyboard user relies on to navigate. Only tabbing through the page with the keyboard, with no mouse involved, reveals whether a focus indicator is actually present.

Mistake: “Our design system’s buttons have a hover state, so users can tell what’s active.” A hover state only appears under a mouse cursor; a keyboard user tabbing to an element never hovers it, so a hover-only visual cue provides zero information to them. Focus and hover are separate states requiring separate, independently visible styling.

How RedFlag Detects This

Manual check: RedFlag prompts a guided manual review; no automated flagging. RedFlag’s extension drives a guided per-element review during the same tab-order walkthrough used for Manual check flagged an incorrect tab order: as a reviewer tabs through the page, they judge whether each focused element shows a visible indicator and record a pass or fail verdict, which the extension persists and raises as a violation on a fail. No CSS or outline heuristic makes this determination automatically; a person judges visibility during the walk.

False negative: not applicable in the automated sense; a reviewer who tabs quickly and misses a subtle failure on one element simply won’t record it, the same limitation any manual review process has. False positive: not applicable either, since there’s no algorithmic pass/fail being second-guessed, only a recorded human judgment. Manual step: this entire rule is the manual step; the walkthrough itself is the only way this finding gets recorded.

Manual Testing

  1. Open the page in Chrome or Firefox using only the keyboard, with no mouse involvement.
  2. Tab through every interactive element on the page: links, buttons, form fields, custom controls.
  3. At each stop, look for a clear visual change (an outline, border, background shift, or similar) that distinguishes the focused element from its resting state.
  4. If no visible change is apparent at any element, that element fails this check.
  5. Repeat at a lower zoom or with a screen magnifier active if low-vision users are part of your intended audience, since a subtle indicator that’s technically present can still be effectively invisible at higher magnification levels.

2.4.7 Focus Visible: Any keyboard-operable interface must have a mode where the keyboard focus indicator is visible. This rule is a direct, literal test of that requirement: an element with no indicator at all fails it outright, regardless of any other consideration.

Focus indicator does not meet minimum size or contrast is this rule’s companion under WCAG 2.2’s newer 2.4.13 Focus Appearance criterion; it assumes an indicator already exists (this page’s concern) and asks whether it’s large and contrasty enough to actually work.

Focused element is hidden behind a sticky header or footer is the third page in this trio, covering 2.4.11 Focus Not Obscured (Minimum): an indicator that exists and looks fine, but gets visually covered by a sticky header, footer, or overlay the moment focus lands behind it.

Focus is trapped inside a component and Element in the focus order has no matching interactive role cover different keyboard-accessibility failures in the same broader cluster: reachability and semantics, rather than visibility.

References

Frequently asked questions

Is this the same as Focus indicator does not meet minimum size or contrast?

No, they check different things and map to different WCAG 2.2 criteria. This rule (2.4.7 Focus Visible) asks whether a focus indicator exists at all. Focus indicator does not meet minimum size or contrast (2.4.13 Focus Appearance) only comes into play once an indicator already exists, and asks whether that indicator is big and contrasty enough to actually see clearly.

What's the difference between :focus and :focus-visible?

:focus applies to any element that has focus, however it got there, including a mouse click. :focus-visible applies only when the browser determines keyboard (or similar non-pointer) navigation caused the focus, which is why it is the right selector for showing a focus ring to keyboard users without also showing it on every mouse click.

Does removing outline:none always break focus visibility?

Only if nothing replaces it. outline: none on its own removes the browser's default focus ring with no substitute, which fails this rule outright. Pairing it with a custom :focus-visible style that provides an equally or more visible replacement is a legitimate, common pattern; the failure is removing the indicator, not customizing it.

Do all browsers show a default focus outline if I do nothing?

Mostly yes, but the appearance varies significantly between browsers and operating systems, and some component libraries strip it via global resets without providing a replacement. Relying on default browser behavior without verifying it in your actual rendered page is common enough that this rule stays a guided manual check rather than something RedFlag verifies automatically.