The heart of Cursalia is the video-lesson player: every course is hours of video with voice-over, screen captures, and demos. A video is, by its very nature, a double barrier: Diego (deaf/hard of hearing) cannot hear the narration, and Marta (blind) cannot see what is shown on screen. Hugo, with dyslexia and ADHD, needs to be able to read and control the pace. Making multimedia accessible means offering the same content through several sensory channels at once. In this lesson we implement the criteria from the WCAG 1.2.x family on the Cursalia player: we will distinguish the different types of alternative, look at the <track> element and the WebVTT format, and build keyboard-operable controls (linking to 05-02).
Contents
- The four types of multimedia alternative
- What each WCAG level requires (A and AA)
- The
<track>element and the WebVTT format - An accessible player: real controls and keyboard
- No autoplay with sound and avoiding flashes
- Third-party embedded players
- Common mistakes, exercises, and conclusion
- The four types of multimedia alternative
They are easy to confuse, but each one solves a different barrier. This table is the mental reference:
| Alternative | What it is | Who it mainly benefits |
|---|---|---|
| Subtitles | Translation of the spoken dialogue into another language (assumes you can hear the audio) | People who do not know the original language |
| Captions | Synchronized text of the dialogue + relevant sounds (music, "[applause]", who is speaking) | Diego and anyone deaf or in a silent environment |
| Transcript | Full text of the content, not synchronized, readable end to end | Hugo (follows his own pace, rereads), Marta (with a screen reader), SEO |
| Audio description | Narration of the visual information (what is seen but not said) during the pauses in the dialogue | Marta and blind people |
| Sign language | A sign interpreter overlaid or in a window | Deaf people whose first language is sign language |
The subtitles vs captions distinction is the one most often confused: subtitles assume you can hear (they only translate the dialogue); captions assume you cannot hear, and include sounds like "[tense music]" or "[the app emits a beep]". For Diego, captions are essential; subtitles are not enough for him because he would miss the sounds that carry information.
- What each WCAG level requires (A and AA)
The criteria of Guideline 1.2 scale according to the level of conformance you aim for:
| Criterion | Level | Requires |
|---|---|---|
| 1.2.1 Audio-only / video-only (prerecorded) | A | A text alternative for audio-only (transcript); a description for video-only |
| 1.2.2 Captions (prerecorded) | A | Captions for every video with audio |
| 1.2.3 Audio description or alternative (prerecorded) | A | Audio description or a full transcript that includes the visual information |
| 1.2.4 Captions (live) | AA | Captions on live broadcasts |
| 1.2.5 Audio description (prerecorded) | AA | Audio description proper |
In practice, for Cursalia's prerecorded video-lessons and a realistic goal of level AA, the minimum is: captions (1.2.2), audio description (1.2.5) and, as reinforcement that also more than covers 1.2.3, a full transcript. The transcript is the alternative with the best cost/benefit ratio: cheap to produce, it benefits many profiles, and it improves SEO.
- The
<track> element and the WebVTT format
<track> element and the WebVTT formatNative HTML offers the <track> element to associate timed text tracks with a <video>. Its kind attribute defines the type:
<video controls>
<source src="lesson-01.mp4" type="video/mp4">
<!-- Captions: dialogue + sounds, in the video's language -->
<track kind="captions" src="lesson-01-en.vtt" srclang="en" label="English (captions)" default>
<!-- Subtitles: translation of the dialogue into another language -->
<track kind="subtitles" src="lesson-01-es.vtt" srclang="es" label="Español">
<!-- Descriptions: text audio description (read by the AT) -->
<track kind="descriptions" src="lesson-01-desc.vtt" srclang="en" label="Audio description">
</video>Key points:
kind="captions"for Diego,kind="subtitles"for translation,kind="descriptions"for the visual information.- The
defaultattribute marks the track that activates without the user doing anything. labelis the text the user will see in the tracks menu: make it descriptive.
The format of the tracks is WebVTT (.vtt), a simple plain-text file: the WEBVTT header, and blocks with a start --> end timestamp and the text:
WEBVTT
00:00:00.000 --> 00:00:03.500
Welcome to the web accessibility lesson.
00:00:03.500 --> 00:00:06.000
[soft intro music]
00:00:06.000 --> 00:00:10.200
Marta: today we'll look at how to build an accessible player.Notice the [soft intro music] block: that is what turns subtitles into captions. The relevant non-verbal sound is annotated in brackets and, when there are several speakers, you indicate who is speaking.
- An accessible player: real controls and keyboard
If you use <video controls>, the browser gives you native controls that are already fairly accessible. But at Cursalia the player is custom (own branding, speed, notes). The moment you replace the native controls, you become responsible for their accessibility. Rules:
<!-- BAD: fake controls, neither keyboard operable nor named -->
<div class="play" onclick="play()">▶</div>
<!-- GOOD: a real button, with an accessible name, keyboard operable -->
<button type="button" id="play" aria-label="Play">
<svg aria-hidden="true" focusable="false"><!-- ▶ icon --></svg>
</button>- Controls as real buttons. Each control (play/pause, mute, fullscreen) is a
<button>, not a<div>. That way it is focusable and operable withEnter/Spacewithout extra JavaScript (see 05-02). - Accessible name. The
▶icon says nothing to Marta. Add anaria-label(or hidden text) and mark the decorative<svg>witharia-hidden="true"(we will cover this in depth in 05-04). - Dynamic state. The play/pause button changes function; reflect it by updating its name: when playing,
aria-label="Pause"; when paused,aria-label="Play". - Visible focus. The controls must show focus (
:focus-visible, Module 4) so Lucía knows which one she is about to activate.
const video = document.querySelector('video');
const playBtn = document.getElementById('play');
playBtn.addEventListener('click', () => {
if (video.paused) {
video.play();
playBtn.setAttribute('aria-label', 'Pause'); // sync name and state
} else {
video.pause();
playBtn.setAttribute('aria-label', 'Play');
}
});In addition, offer the transcript as text on the page, beneath the player or in a collapsible panel (the disclosure pattern from 05-01). It lets Hugo read at his own pace and Marta consult it with NVDA without depending on playback.
- No autoplay with sound and avoiding flashes
Two criteria that directly affect the player:
- 1.4.2 (Audio Control). If audio plays automatically for more than 3 seconds, there must be a mechanism to pause or mute it. The practical and respectful rule: do not autoplay with sound. Unexpected audio drowns out NVDA's synthetic voice (Marta cannot even hear her own screen reader) and startles anyone. If you autoplay a video, keep it muted by default.
<!-- Acceptable: autoplay ONLY if muted -->
<video autoplay muted playsinline>…</video>
<!-- Avoid: <video autoplay> with sound -->- 2.3.1 (Three Flashes or Below Threshold). Content must not flash more than three times per second, so as not to trigger seizures in people with photosensitive epilepsy. Check that no video-lesson contains sequences with fast or strobe flashing; if the original material has them, edit them out.
- Third-party embedded players
Many platforms embed video from YouTube or Vimeo via <iframe> instead of serving it themselves. This has advantages (bandwidth, transcoding) but also accessibility limitations you should know about:
- You inherit their interface. Keyboard and screen reader accessibility depends on the third-party player, not on you. YouTube's and Vimeo's are reasonable, but you do not control their changes.
- Captions depend on the platform. You can upload your own
.vtt, but the quality of automatic captions is low: do not rely on them for conformance. Always review and correct the tracks. - Give the iframe a name. An
<iframe>without a title is a black hole for Marta. Always add atitle:
<!-- The title describes WHAT the iframe contains -->
<iframe src="https://www.youtube.com/embed/…"
title="Video-lesson: introduction to accessibility"
allowfullscreen></iframe>- Limited audio description. Embedded players rarely support audio description tracks; this is usually solved with an alternative version of the video or with a transcript expanded to include the visual content.
Practical conclusion: embedding third-party video is valid, but you are still responsible for having correct captions, a title on the iframe, and your own transcript.
Common Mistakes and Tips
- Confusing subtitles with captions. Publishing only subtitles (dialogue) thinking you meet 1.2.2. Diego needs captions with the sounds.
- Trusting automatic captions. YouTube's automatic transcription has errors; for conformance you have to review and correct it.
<div>controls withonclick. Neither keyboard operable nor announced. Use a<button>with an accessible name.- Icons without a name. A button that only contains a
▶says nothing to NVDA. Add anaria-labeland hide the icon witharia-hidden. - Autoplay with sound. It drowns out the screen reader and annoys everyone. Muted or nothing.
- Tip: always produce the transcript. It is the cheapest alternative, helps Diego, Marta, and Hugo all at once, meets 1.2.3, and improves ranking as a bonus.
Exercises
Exercise 1. A colleague says: "I've already added subtitles, the video is compliant for deaf people." They used kind="subtitles" with only the dialogue. Is it correct? What would you change?
Exercise 2. Write a three-block WebVTT snippet for the start of a lesson where a melody plays, the instructor speaks, and an app notification sounds. Annotate the sounds appropriately.
Exercise 3. You have this play control. List all the accessibility problems and rewrite it.
Solutions
Solution 1. It is not correct. kind="subtitles" with only the dialogue is subtitles, not captions. For deaf people you need kind="captions" that includes, in addition to the dialogue, the relevant sounds ("[music]", "[app beep]") and identifies who is speaking. Diego would miss all the non-verbal sound information with mere subtitles.
Solution 2.
WEBVTT
00:00:00.000 --> 00:00:02.500
[intro melody]
00:00:02.500 --> 00:00:07.000
Instructor: let's start by setting up the player.
00:00:07.000 --> 00:00:08.200
[the application emits a notification]The non-verbal sounds go in brackets and the speaker is named before the dialogue: that turns them into valid captions for Diego.
Solution 3. Problems: (1) it is a <div>, neither focusable nor keyboard operable, so Lucía cannot activate it; (2) onclick without Enter/Space handling; (3) the ▶ has no accessible name, so Marta does not know what it is; (4) there is no state (it does not change to "pause"). Rewrite:
<button type="button" class="btn-play" id="play" aria-label="Play">
<span aria-hidden="true">▶</span>
</button>With a <button> it is focusable and keyboard operable for free; the aria-label gives it a name; the ▶ is hidden from the AT with aria-hidden. In JS you update aria-label to "Pause" when playing.
Conclusion
We have made the Cursalia player accessible: we distinguished subtitles, captions, transcript, audio description, and sign language; we know what each WCAG level requires, how to associate tracks with <track> and WebVTT, how to build keyboard-operable controls with an accessible name, and the rules for autoplay and flashes. One last type of non-text content remains, one that is everywhere on the platform: images. Course thumbnails, the logo, category icons, the progress chart… all of them need a text alternative. In the next and final lesson of the module, 05-04: Providing Text Alternatives for Images, we will close out criterion 1.1.1 with a complete decision tree.
Web Accessibility Course
Module 1: Introduction to Web Accessibility
- What Is Web Accessibility?
- The Importance of Web Accessibility
- Overview of Accessibility Laws and Standards
- Introduction to WCAG
Module 2: Understanding Disabilities and Assistive Technologies
Module 3: Principles of Accessible Design
- Perceivable: Making Content Available to the Senses
- Operable: User Interface and Navigation
- Understandable: Information and Operation
- Robust: Compatibility with Current and Future Technologies
Module 4: Implementing Accessibility in HTML and CSS
Module 5: Accessibility in JavaScript and Multimedia
- Creating Accessible JavaScript Widgets
- Keyboard Accessibility
- Accessible Video and Audio Content
- Providing Text Alternatives for Images
Module 6: Accessibility Testing and Evaluation
- Manual Testing Techniques
- Automated Testing Tools
- User Testing with Assistive Technologies
- Interpreting Accessibility Reports
