auditmysitev2.0.2

Focus indicator removed via CSS

focus/outline-removed

WCAG success criterion
2.4.7 (level AA)
Outcome class
Automatic. An automated check that can report a confirmed violation.
Area
Accessibility, Navigation & Operation
Default severity
high
axe-core rule
focus-visible-outline-none

Why we flag this

Keyboard users cannot see which element currently has focus.

outline: none/0 in :focus rules without an alternative visible focus indicator.

What the rule checks

Scope. Pages whose stylesheets contain a :focus rule that removes the outline (outline: none / 0, outline-style: none, outline-width: 0).

Expectation. violation once per page (page-level) when a stylesheet removes the focus outline under :focus and no rule replaces it: no :focus-visible rule anywhere and no :focus rule that sets another indicator (box-shadow, border, background, text decoration, or the outline itself). Rules inside a media query that applies on the phone viewport count, as do stylesheets a script injects after load. A replacement in the same rule, or a :focus-visible rule for keyboard focus, passes. Pages without such a rule are not applicable.

Source. WCAG 2.2 SC 2.4.7 Focus Visible; failure F78 (styling that removes or renders the focus indicator non-visible)

Detection: shared; needs stylesheets.

Failing example

The check reports a violation here. Corpus case interaction_outline_removed. The page may contain further findings for other rules.

interaction_outline_removed.htmlHTML
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Focus outline removed</title>
    <style>
        body { font-family: sans-serif; margin: 0; padding: 16px; color: #111; background: #fff; }
        a, button { display: inline-block; min-width: 44px; min-height: 44px; padding: 12px; box-sizing: border-box; margin: 4px; }
        .skip { position: absolute; left: -9999px; }
        .skip:focus { left: 16px; }
        /* violation: removes the indicator and nothing replaces it */
        a:focus { outline: none; }
        button:focus { outline: 0; }
    </style>
</head>
<body>
    <a class="skip" href="#main">Skip to main content</a>
    <header><p>Example Bank</p></header>
    <nav aria-label="Main">
        <a href="/" aria-current="page">Home</a>
        <a href="/accounts">Accounts</a>
    </nav>
    <main id="main">
        <h1>Focus outline removed</h1>
        <p>Review your recent payments or <a href="/statements">download a statement</a>.</p>
        <button type="button">Show more payments</button>
    </main>
    <footer><p>Example Bank footer</p></footer>

</body>
</html>

Passing example

The check passes here and reports nothing. Corpus case interaction_outline_replaced. The page may contain further findings for other rules.

interaction_outline_replaced.htmlHTML
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Focus outline replaced</title>
    <style>
        body { font-family: sans-serif; margin: 0; padding: 16px; color: #111; background: #fff; }
        a, button { display: inline-block; min-width: 44px; min-height: 44px; padding: 12px; box-sizing: border-box; margin: 4px; }
        .skip { position: absolute; left: -9999px; }
        .skip:focus { left: 16px; }
        /* pass: the outline gives way to a box shadow in the same rule */
        a:focus, button:focus { outline: none; box-shadow: 0 0 0 3px #1a5fb4; }
        /* pass: a reset for mouse focus, with :focus-visible for the keyboard */
        nav a:focus { outline: none; }
        nav a:focus-visible { outline: 3px solid #1a5fb4; }
    </style>
</head>
<body>
    <a class="skip" href="#main">Skip to main content</a>
    <header><p>Example Bank</p></header>
    <nav aria-label="Main">
        <a href="/" aria-current="page">Home</a>
        <a href="/accounts">Accounts</a>
    </nav>
    <main id="main">
        <h1>Focus outline replaced</h1>
        <p>Review your recent payments or <a href="/statements">download a statement</a>.</p>
        <button type="button">Show more payments</button>
    </main>
    <footer><p>Example Bank footer</p></footer>

</body>
</html>

This page is generated from the rule catalogue and the rule contracts; see therule overview for how the outcome classes are derived.