auditmysitev2.0.2

Missing captions for videos

video-caption

WCAG success criterion
1.2.2 (level A)
Outcome class
Hint only. An automated check that by design reports review hints only: its findings are marked for manual review, never as confirmed violations.
Area
Accessibility, Content & Alternatives
Default severity
high
axe-core rule
video-caption

Why we flag this

Deaf or hard-of-hearing users cannot perceive spoken content.

Missing track element for captions.

What the rule checks

Scope. Pages with a rendered native <video> or a known video-platform embed iframe.

Expectation. Pass (positive signal, no finding) only when every rendered <video> has a <track kind="captions"|"subtitles"> whose src resolves same-origin as a caption file (.vtt/.srt or a vtt content type). Anything less — no caption track, a track that does not resolve or is cross-origin, only description/chapter tracks, more caption tracks than the probe budget of 10 checks, or third-party embeds — is one page-level UNTESTED note: captions may exist in ways the tool cannot see (open captions, platform players), so never a violation. A page without rendered video is not applicable; a video in a hidden panel is not presented in this state.

Source. WCAG 2.2 SC 1.2.2 Captions (Prerecorded) (H95, G87, F8); HTML §4.8.11.11 track

Detection: page; needs dom, network.

Failing example

The check flags this for review. Corpus case content_video_dynamic. The page may contain further findings for other rules.

content_video_dynamic.htmlHTML
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Video added after load</title>
    <style>
        nav a, .skip-link { display: inline-block; min-width: 44px; min-height: 44px; }
    </style>
</head>
<body>
    <a class="skip-link" href="#main">Skip to main content</a>
    <header>
        <p>City Library</p>
        <nav aria-label="Main"><a href="/" aria-current="page">Home</a> <a href="/catalogue">Catalogue</a> <a href="/visit">Visit</a></nav>
    </header>
    <main id="main">
        <h1>Featured video</h1>
        <div id="player-slot"></div>
        <script>
            document.getElementById('player-slot').innerHTML =
                '<video id="featured" controls width="320" height="180" src="/featured.mp4"></video>';
        </script>
    </main>
    <footer><p>City Library, 1 Market Square</p></footer>
</body>
</html>

Passing example

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

content_video_captioned.htmlHTML
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Library tour video</title>
    <style>
        nav a, .skip-link { display: inline-block; min-width: 44px; min-height: 44px; }
    </style>
</head>
<body>
    <a class="skip-link" href="#main">Skip to main content</a>
    <header>
        <p>City Library</p>
        <nav aria-label="Main"><a href="/" aria-current="page">Home</a> <a href="/catalogue">Catalogue</a> <a href="/visit">Visit</a></nav>
    </header>
    <main id="main">
        <h1>Library tour</h1>
        <video id="tour" controls width="320" height="180" src="/tour.mp4">
            <track kind="captions" src="/tour.en.vtt" srclang="en" label="English">
        </video>
        <video id="workshop" controls width="320" height="180" src="/workshop.mp4">
            <track kind="subtitles" src="/workshop.de.srt" srclang="de" label="Deutsch">
            <track kind="chapters" src="/workshop.chapters.html" srclang="en">
        </video>
    </main>
    <footer><p>City Library, 1 Market Square</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.