Search topics
Captions stuck in one style, or lost when video is converted
A shop's video player draws its captions small and white with no settings to change them, and its streaming encoder drops the captions and the described soundtrack.
font: 13px/1.3 "Brand Sans", sans-serif; The problem
People who need bigger or higher-contrast captions get no settings to change them, and the streamed version of the video has no captions or audio description at all.
The coffee roaster's brewing video has checked captions and a described soundtrack, and its branded player has CC and AD buttons beside the volume. Two things still go wrong.
The player draws the captions itself, so that they match the shop: 13 pixels, the brand's thin font, white, with no box behind them. Over the kitchen counter, which is light, they are hard to read. A viewer who set large yellow captions on black in their computer's caption settings gets the same small white text, because those settings style captions the browser draws, not text in the player's own box. The player has no caption settings.
Then the video plugin gained a "fast streaming" option, and the shop turned it on. It re-encodes every video into an adaptive stream that starts quickly on phones. The encoder took the video file and its soundtrack, but not the captions file or the described soundtrack uploaded with it. The streamed version plays, with nothing for the CC and AD buttons to turn on.
WCAG says little about how captions look, and nothing about what a conversion keeps; WCAG's 1.2.2 only asks that captions exist, which the streamed version now fails too, as videos without captions, or with unchecked automatic ones explains. These requirements are in EN 301 549, whose Table A.1 applies them to web pages for the EU's web accessibility directive:
- 7.1.3, Preservation of captioning: where a site transmits, converts or records video with sound, it keeps the caption data, so the captions can still be shown in sync. The site converts its uploads, so it must keep their captions.
- 7.2.3, Preservation of audio description: the same for the audio description.
- 7.1.4, Captions characteristics: where a site displays captions, viewers can adapt how they look to their own needs, such as their colours, font, size, background and outline. Captions drawn into the picture are exempt, as they can't be changed.
- 7.1.5, Spoken subtitles: where a site displays video with sound, it has a mode that speaks the captions, unless their text can't be read by software. German BITV testers apply it where the speech is not in the site's main language, subtitles in that language are offered, and no version of the video has a soundtrack in it: that is when a blind viewer needs the subtitles spoken. The brewing video's narrator speaks the captions' language, so reading them aloud would only repeat the narration, and BITV would not apply the clause here, though an auditor who reads the clause literally may still ask for it.
The streaming conversion fails 7.1.3 and 7.2.3. The player falls short of 7.1.4 for every viewer who needs a background behind the captions or their own caption style: it offers no setting, and their system caption settings don't reach it. A BITV tester, who also counts browser zoom and colour schemes, may still rate it met, since zoom enlarges these captions and a contrast theme recolours them; nothing gives them a background.
Everyone sees the same small white text, and everyone gets the streamed version, but many viewers never turn captions on, so the shop doesn't notice.
5 of 10 groups affected
- No vision (affected)
- Low vision (affected)
- Colour vision (not affected)
- No hearing (affected)
- Hard of hearing (affected)
- No speech (not affected)
- Motor (not affected)
- Reach, strength (not affected)
- Cognitive (affected)
- Seizures (not affected)
- Limited vision Thin 13-pixel white letters on the light kitchen counter are hard to make out. The large yellow-on-black captions they set in their system settings never reach a player that draws its own, and the player offers nothing instead.
- Without hearing The captions are how they follow the recipe. In the streamed version they are gone, and where they show, the player offers no way to make them easier to read on a light picture.
- Limited hearing People who hear some of the speech turn captions on to catch what they miss. The streamed version has none, and the player's small thin captions can be made bigger only by zooming the whole page.
- Without vision The streamed version has lost the described soundtrack, so what the picture shows never reaches them.
- Limited language, cognitive and learning abilities People who read slowly, or who have dyslexia, can find captions easier in a plainer font, larger, or on a solid background.
No WCAG rule covers this, so axe and other WCAG scanners don't look; a page whose video has a captions track passes them even when the stream it plays has none. EaseWeb's audit lists every video for review, and for a player with its own controls it asks a person to check that viewers can change the captions' size, colours and background. It doesn't compare a stream with the file it came from, open a stream's manifest, or try caption settings. A code assistant asked to "make the captions match the brand" is likely to write a fixed font, size and colour, which is how this happened.
Try it
Play the brewing video. Can you read the captions, or make them bigger?
Broken 1 is the shop’s player, drawing captions in one thin white style with no settings. Broken 2 is the streamed version, which lost its captions and described soundtrack. Apply a fix to get both back, with captions drawn by the browser in your system’s caption style, or with the player’s own settings.
Broken Can you fix this?
How to brew our house blend
The stream carries: picture, sound, described sound, captions
Captions drawn by: the player, in one style; your system caption settings don’t reach it
The fix
Keep captions and description through conversion, and let viewers restyle the captions.
- 1Every converted video keeps every captions language and the audio description.
- 2Viewers can change caption size, colour and background, from the player or their system.
- 3Subtitles that translate speech in another language can also be heard.
Captions drawn in one style
// The player hides the browser's captions and draws each cue itself.const track = video.textTracks[0];track.mode = 'hidden';track.addEventListener('cuechange', () => { captionBox.textContent = track.activeCues[0]?.text ?? '';});Tracks kept through conversion, captions drawn by the browser
// The browser draws the captions, so the viewer's system caption style applies.const track = video.textTracks[0];track.mode = 'showing';The captions are text, so they could be restyled, but the player offers no settings, and the viewer's system caption settings don't reach text in its own box. Thin white letters with no background are hard to read on a light picture. Browser zoom makes them bigger, along with the rest of the page, and a contrast theme changes their text colour, but nothing gives them a background.
The encoding job now carries the captions as a subtitles rendition and the described soundtrack as a second audio rendition, marked as describing the video, so every player of the stream can offer both, in sync. With no box of its own, the player leaves the captions to the browser, which draws them in the viewer's system caption style in Safari and in Chromium-based browsers such as Chrome and Edge. Firefox doesn't read the system caption settings, on macOS at least, so its users there get the page's style, and viewers who don't know the setting exists won't find it from the player.
Both keep the tracks through conversion, and both let viewers restyle the captions. Use the player's own settings: they work in every browser, sit where viewers look for them, and start from a readable style, while the browser's drawing leaves Firefox users, on macOS at least, with one style and asks everyone else to know about a setting deep in their operating system. Letting the browser draw is the smaller change, and a fair choice for a player that uses the browser's own controls.
Check every route a video takes after upload.
- A streaming encoder, as here: map the captions file to a subtitles rendition and the described soundtrack to an audio rendition in the job's settings, for every language, and check the output manifest lists them. DASH manifests carry them as text and audio adaptation sets, with roles for captions and description.
- A video platform, such as YouTube or Vimeo: upload the captions file to the video there, and check the embed offers it; re-uploading a new cut loses the old captions unless you add them again.
- A file made for social media, or a shorter edit: it is a new video, so it needs its own captions, cut to its timing; captions drawn into the picture go wherever the file goes, where a separate captions file may not.
- A recording the site makes, such as a webinar or a support call: save the live captions with it, and offer them with the recording.
Keep what the captions' look says. EN 301 549 notes that position, colour and style can carry meaning, such as a caption moved to the top so it doesn't cover text on screen, or a colour for each speaker. A conversion that keeps the words but drops the positions should be fixed, and viewer settings should change the size and colours without moving captions back over what they were avoiding.
Full screen: when a player draws its own captions, put the player's container into full screen with requestFullscreen(), not the video, or the captions box is left behind. Browser-drawn captions follow the video by themselves.
Videos in another language: when a video's speech is in another language than its subtitles, such as an interview in Spanish with English subtitles, a blind viewer who doesn't understand Spanish needs the subtitles spoken. The better way is a spoken-subtitles soundtrack, which EN 301 549 suggests delivering as a separate audio track, offered like the described soundtrack. A player can also offer a Read subtitles aloud option, off by default, that speaks each cue with speech synthesis: a SpeechSynthesisUtterance whose lang comes from the track, with the previous cue cancelled when the next starts so it never falls behind, and with the original speech turned down while it talks. Speech synthesis depends on the voices the device has for the language. There is no need to offer either for a video whose speech is in the captions' language: it only repeats the narration over itself.
Captions drawn into the picture are exempt from 7.1.4 and 7.1.5, because nothing can change or read them; that is the reason not to use them alone, not a way around these clauses. Video players that hide captions in a settings menu covers where the CC and AD buttons go.
Fixing this with an AI coding assistant? Get this guide as Markdown, or get every guide in your coding agent.
Verify the fix
4 checks, no mouse.
Test with: Caption settings, Screen off, Keyboard
Record the OS, browser and assistive-technology versions, the build, the date, and the actual result of each step. Repeat whenever the encoder, the player or the video platform changes.
Limits
This is a starting pattern, not a guarantee for every application. Settings only help when the captions are right and complete, and some viewers need settings beyond these three, such as an outline around the letters or a different font. Test the complete journey with the people who will watch, in the players and platforms the video really plays in.
This is a recreated teaching example, not a finding about a named client. The code is a starting pattern: test it in your own product. No completed assistive-technology test is claimed here.
References
- etsi.org: en_301549v030201p.pdf (opens in a new tab)
- bitvtest.de: bitv-20-web-7-1-3-erhaltung-von-untertiteln (opens in a new tab)
- bitvtest.de: bitv-20-web-7-1-4-untertitel-anpassungen (opens in a new tab)
- bitvtest.de: bitv-20-web-7-1-5-gesprochene-untertitel (opens in a new tab)
- w3.org: player (opens in a new tab)
- developer.apple.com: hls-authoring-specification-for-apple-devices (opens in a new tab)
- developer.mozilla.org: cuechange_event (opens in a new tab)
- developer.mozilla.org: SpeechSynthesis (opens in a new tab)
Keep this fixed as your code changes.
Turn guides like this into rules your coding agents and CI follow, then have the result retested with a keyboard and screen readers.