WCAG Success Criteria · Level AA
WCAG 1.2.4: Captions (Live)
WCAG 1.2.4 requires that all live audio content in synchronized media—such as webinars, live streams, and broadcasts—be accompanied by real-time captions. This ensures that deaf and hard-of-hearing users can access spoken content as it happens, in real time.
- Level AA
What This Rule Means
\nWCAG 1.2.4 (Captions — Live) requires that captions be provided for all live audio content in synchronized media. Synchronized media is defined as audio or video content that is synchronized with another format for presenting information or with time-based interactive components, such as a webcast, live stream, or real-time broadcast on the web.
\nIn practical terms, this means any live event published on a website or web application that includes audio — a press conference streamed on a news site, a company all-hands broadcast, a government hearing, a live online class, or a sports commentary stream — must display real-time captions that accurately reflect what is being spoken as it occurs.
\nWhat counts as a pass: A live stream passes this criterion when synchronized, accurate real-time captions are visible to the user during playback. The captions must represent all dialogue and relevant non-speech audio information (such as "[applause]" or "[alarm sounds]"). Common approaches include CART (Communication Access Realtime Translation) provided by a professional captioner, automatic speech recognition (ASR) captions from a qualified live captioning service, or third-party integrations such as those offered by streaming platforms.
\nWhat counts as a fail: A live stream fails this criterion when no captions are available, when captions are not synchronized with the spoken audio, when captions omit significant portions of the dialogue, or when the caption accuracy is so poor that comprehension is severely impaired. Providing a transcript after the fact does not fulfill this requirement — captions must be available live, in real time.
\nOfficial exceptions: WCAG defines one exception to this rule: media that is itself a media alternative for text, and that is clearly labeled as such, is exempt. For example, if you publish a detailed text transcript of an interview and then also provide a live audio version of the same content that is explicitly labeled as an audio alternative to the text, captions may not be strictly required. However, this exception is narrow and rarely applicable in practice.
\nThe criterion applies to all synchronized media published on the web — regardless of whether the video has been pre-produced or is truly live. A pre-recorded webinar replay streamed as though it were live still falls under 1.2.3 or 1.2.5, but a genuine real-time broadcast falls squarely under 1.2.4.
\n\nWhy It Matters
\nApproximately 430 million people worldwide have disabling hearing loss according to the World Health Organization, and that number is projected to rise to over 700 million by 2050. For deaf and hard-of-hearing users, real-time captions are not a convenience — they are the primary or sole means of accessing audio content in a live context. Without captions, these users are entirely excluded from participating in or understanding any live media event.
\nBeyond deafness and hearing loss, live captions benefit a much broader audience. Users in noisy environments — airports, open offices, public transit — may be unable to use audio. Users watching in quiet environments without headphones, or users who have muted their devices, rely on captions to follow along. Non-native speakers often find captions indispensable for comprehension, particularly when speakers use complex vocabulary, accents, or technical jargon. Cognitive and language processing differences can also make captions essential for accurate understanding.
\nConsider a concrete scenario: a municipality in Turkey streams a live city council meeting on its official website. A resident who is deaf wants to follow the debate about zoning changes in their neighborhood. Without real-time captions, that resident is completely excluded from civic participation. The same applies to a deaf student attending a live online class on a private school's learning management system, or a customer trying to follow a bank's live product announcement webinar.
\nFrom a practical standpoint, live captioning infrastructure also produces a transcript that can be indexed by search engines, improving the discoverability of video content. Organizations that invest in live captioning often find that the transcript artifact becomes a valuable resource for post-event documentation, summaries, and archival search.
\n\nRelated Axe-core Rules
\nWCAG 1.2.4 requires manual testing. No automated axe-core rule can reliably detect the presence or quality of live captions, and this is an important distinction to understand when planning your accessibility audit strategy.
\n- \n
- Manual testing required — live caption presence: Automated tools like axe-core can scan the DOM for the presence of a
<track>element withkind='captions'on a<video>element, but live streams are almost never delivered via a simple HTML<video>element with a<track>. They typically use adaptive bitrate formats (HLS, DASH) delivered through JavaScript-based players such as Video.js, JW Player, or native platform players. These players render captions dynamically in ways that axe-core cannot introspect. A tool cannot watch a live stream in real time, evaluate caption accuracy, measure synchronization delay, or determine whether a caption overlay is genuinely reflecting spoken content or is a static placeholder. \n - Manual testing required — caption quality and accuracy: Even if an automated tool could detect that a caption feed exists, it has no way to assess whether the captions are accurate, complete, or synchronized to an acceptable degree. CART-produced captions and poor-quality auto-generated captions may both appear as "captions present" to a tool, but only one of them satisfies WCAG 1.2.4. Human review during a live event is the only reliable way to verify compliance. \n
- Manual testing required — caption accessibility within the player: Automated tools generally cannot determine whether caption controls within a custom media player are keyboard accessible, whether the caption display can be resized or customized by the user, or whether caption styling meets users' needs. These aspects require hands-on testing with actual keyboard navigation and screen reader usage. \n
How to Test
\n- \n
- Identify all live media on the page: Review the page for any live video or audio streams. Check for embedded players, iframes, or dynamically loaded media components. Note whether the content is genuinely live (real-time broadcast) or pre-recorded. Only genuinely live audio content in synchronized media falls under 1.2.4. \n
- Run an automated scan with axe DevTools or Lighthouse: Open axe DevTools in Chrome DevTools and run a full-page scan. While axe cannot validate live captions, it can flag related issues such as missing
aria-labelon media player controls, inaccessible play/pause buttons, or missing focus management. Note any flagged issues as supporting evidence, but understand that a clean axe report does not confirm 1.2.4 compliance. \n - Manually verify caption availability during a live event: Access the live stream during an active broadcast. Check whether captions are displayed. If the player has a captions toggle (CC button), activate it and confirm that captions appear and update in near real time as the speaker talks. Confirm that the caption delay is acceptable — typically no more than a few seconds for CART, or slightly more for ASR. \n
- Assess caption accuracy: Listen to the audio while reading the captions. Check for missed words, systematic errors, or significant omissions. Captions do not need to be verbatim, but they must convey the full meaning of the spoken content. Note speaker identification if multiple speakers are present — captions should indicate who is speaking when it is not obvious. \n
- Test with NVDA + Firefox: Navigate to the media player using the Tab key. Verify that all player controls including the captions toggle are reachable and operable by keyboard. Confirm that NVDA announces the state of the captions button (on/off). Activate captions and verify that caption text appears in a DOM element that NVDA can read if the user tabs to or around the player. \n
- Test with VoiceOver + Safari (macOS or iOS): Use VoiceOver gestures or keyboard commands to navigate the player. Verify that the captions toggle is announced and operable. Confirm that caption text changes are surfaced appropriately within the player's accessible region. \n
- Test with JAWS + Chrome: Navigate to the player controls using Tab. Verify that JAWS reads all control labels. Confirm the captions toggle is identified as a button with an appropriate label and state. Activate captions and verify that the caption display updates as expected. \n
- Check caption display customization: Verify whether the player allows users to resize caption text, change colors, or adjust contrast. While not strictly required by 1.2.4, this is a best-practice evaluation point and relevant to WCAG 1.4 criteria. \n
How to Fix
\nLive stream with no caption track — Incorrect
\n<!-- A live HLS stream embedded with no caption configuration -->\n<video id='live-player' controls autoplay>\n <source src='https://stream.example.com/live/event.m3u8' type='application/x-mpegURL'>\n <!-- No <track> element and no caption configuration in the player -->\n</video>\nLive stream with integrated CART caption track — Correct
\n<!-- Live stream using Video.js with a live WebVTT caption track fed by a CART service.\n The src for the track points to a live caption endpoint that updates in real time. -->\n<video\n id='live-player'\n class='video-js vjs-default-skin'\n controls\n autoplay\n aria-label='Live conference stream with real-time captions'>\n <source src='https://stream.example.com/live/event.m3u8' type='application/x-mpegURL'>\n <track\n kind='captions'\n src='https://captions.example.com/live/event.vtt'\n srclang='tr'\n label='Turkish captions'\n default>\n</video>\n<script>\n var player = videojs('live-player');\n // Enable captions by default for accessibility\n player.ready(function() {\n player.textTracks()[0].mode = 'showing';\n });\n</script>\nEmbedded live stream from a platform with captions disabled in the embed — Incorrect
\n<!-- YouTube live embed with closed captions explicitly disabled via cc_load_policy=0.\n This removes the user's ability to enable captions, causing a 1.2.4 failure. -->\n<iframe\n src='https://www.youtube.com/embed/live_stream?channel=CHANNEL_ID&cc_load_policy=0'\n title='Company all-hands live stream'\n allowfullscreen>\n</iframe>\nEmbedded live stream from a platform with captions enabled — Correct
\n<!-- YouTube live embed with closed captions enabled by default (cc_load_policy=1).\n The platform's native caption infrastructure is used, which supports live auto-captions\n and human-reviewed CART when configured in the YouTube Studio settings.\n The host page also provides a direct link to the captioned stream for users\n who cannot interact with the iframe. -->\n<iframe\n src='https://www.youtube.com/embed/live_stream?channel=CHANNEL_ID&cc_load_policy=1'\n title='Company all-hands live stream with captions enabled'\n allowfullscreen>\n</iframe>\n<p>\n <a href='https://www.youtube.com/watch?v=LIVE_VIDEO_ID'>\n Watch with captions directly on YouTube\n </a>\n</p>\nCustom player with a caption toggle that is not keyboard accessible — Incorrect
\n<!-- Caption toggle implemented as a non-interactive <div>.\n Keyboard users and screen reader users cannot activate this control. -->\n<div class='player-controls'>\n <div class='cc-button' onclick='toggleCaptions()'>CC</div>\n</div>\nCustom player with an accessible caption toggle — Correct
\n<!-- Caption toggle implemented as a <button> with an explicit label and\n ARIA pressed state so keyboard and screen reader users can discover\n and operate it. The state updates dynamically when captions are toggled. -->\n<div class='player-controls'>\n <button\n class='cc-button'\n id='captions-toggle'\n aria-pressed='false'\n aria-label='Toggle captions'\n onclick='toggleCaptions(this)'>\n CC\n </button>\n</div>\n<script>\n function toggleCaptions(btn) {\n var isActive = btn.getAttribute('aria-pressed') === 'true';\n btn.setAttribute('aria-pressed', String(!isActive));\n // logic to show/hide the caption track\n }\n</script>\n\nCommon Mistakes
\n- \n
- Providing a post-event transcript instead of real-time captions: Publishing a text transcript of a live event after it concludes does not satisfy 1.2.4. Captions must be available concurrently with the live audio, enabling deaf users to follow the content in real time alongside sighted hearing users.
(Content truncated due to token limit — please retry this article.)
