auditmysitev2.0.2

Missing alternative text on SVG graphics

svg/name-missing

WCAG success criterion
1.1.1 (level A)
Outcome class
Automatic. An automated check that can report a confirmed violation.
Area
Accessibility, Content & Alternatives
Default severity
high
axe-core rule
svg-img-alt

Why we flag this

Screen reader users receive no information about the graphic's content.

SVG without a <title> child element, aria-label, or aria-labelledby.

What the rule checks

Scope. <svg> elements in the accessibility tree that are not marked decorative (role none/presentation, aria-hidden) and not an icon inside a named link or button.

Expectation. Fails for an <svg> with an explicit image role (img, graphics-document, graphics-symbol) and no name. Without a role the graphic may be decoration next to text: review. Names from <title> or aria-label pass, decorative SVGs pass, and an icon in a named button passes. Hidden subtrees are out of scope.

Source. WCAG 2.2 SC 1.1.1 Non-text Content; SVG-AAM; ACT 7d6734 (svg element with explicit role has non-empty accessible name)

Detection: shared; needs dom, ax_tree.

Failing example

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

svg_graphics_role_no_name.htmlHTML
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>SVG with explicit graphics role and no accessible name</title>
</head>
<body>
    <main>
        <h1>SVG with role="graphics-document" and no title/aria-label</h1>
        <svg role="graphics-document" width="120" height="80" viewBox="0 0 120 80">
            <rect x="0" y="0" width="120" height="80" fill="steelblue"></rect>
        </svg>
    </main>
</body>
</html>

Passing example

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

aria_names_valid.htmlHTML
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Media player - Example radio</title>
</head>
<body>
    <header>
        <p>Example radio</p>
    </header>
    <main>
        <h1>Live stream</h1>

        <!-- Every alternative name source: aria-label, aria-labelledby,
             <label>, title on a native field, content -->
        <div id="volume" role="slider" tabindex="0" aria-label="Volume" aria-valuenow="7" aria-valuemin="0" aria-valuemax="10"></div>
        <div id="autoplay" role="switch" tabindex="0" aria-checked="false" aria-labelledby="autoplay-label"></div>
        <span id="autoplay-label">Autoplay</span>
        <label for="station">Station</label>
        <input id="station" type="text">
        <input id="search" type="search" title="Search stations">
        <div id="genre" role="radiogroup" aria-label="Genre">
            <div role="radio" id="genre-jazz" tabindex="0" aria-checked="true">Jazz</div>
            <div role="radio" id="genre-pop" tabindex="-1" aria-checked="false">Pop</div>
        </div>

        <!-- One-character names that are letters or digits, and a symbol
             from content rather than from an attribute -->
        <button type="button" id="channel-1" aria-label="1">1</button>
        <button type="button" id="umlaut" aria-label="&#x00C4;">&#x00C4;</button>
        <button type="button" id="next-arrow">&#x2192;</button>

        <!-- Title only adds to a visible name -->
        <button type="button" id="share" title="Opens the share dialog">Share</button>

        <!-- Name contains the visible label; a symbol label is exempt -->
        <button type="button" id="play" aria-label="Play live stream">Play</button>
        <a href="/notes#fn1" id="fn-ref" aria-label="Footnote 1"><sup>&#x00B9;</sup></a>

        <!-- Description adds information beyond the name -->
        <button type="button" id="mute" aria-describedby="mute-desc">Mute</button>
        <span id="mute-desc" hidden>Silences the stream until you unmute it</span>

        <!-- Named summary, also through aria-label on an icon-only summary -->
        <details id="lyrics">
            <summary id="lyrics-summary">Lyrics</summary>
            <p>No lyrics available.</p>
        </details>
        <details id="credits">
            <summary id="credits-summary" aria-label="Credits"><span aria-hidden="true">&#x2139;</span></summary>
            <p>Produced by Example radio.</p>
        </details>

        <!-- SVGs: named by title, by aria-label, decorative, and an icon inside
             a named button -->
        <svg id="cover" role="img" width="120" height="120" viewBox="0 0 120 120">
            <title>Album cover: Blue Nights</title>
            <rect width="120" height="120" fill="#335"></rect>
        </svg>
        <svg id="logo" role="img" aria-label="Example radio logo" width="40" height="40"><circle cx="20" cy="20" r="18"></circle></svg>
        <svg id="divider" role="presentation" width="200" height="4"><path d="M0 2 L200 2" stroke="#000"></path></svg>
        <button type="button" id="like"><svg id="like-icon" width="16" height="16"><circle cx="8" cy="8" r="6"></circle></svg> Like</button>
    </main>
    <footer>
        <p>Example radio</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.