HTML Captions
Imagine watching a video with the sound off: on a train, in a library, or because you cannot hear. Without captions, you lose everything that is spoken. For many people, that is not an occasional problem but an everyday one.
Captions are the fix. They are the spoken words and important sounds, written as text, in time with the video. They are one of the most useful accessibility features you can add, and they are surprisingly easy to attach with HTML. The harder (and more important) part is writing them well.
What You Will Learnβ
- What captions are, and how they differ from subtitles and transcripts
- Adding captions with
<track kind="captions"> - What good captions contain
- Timing, reading speed, and line length
- Styling captions, and keeping them readable
- Open versus closed captions, and checking automatic captions
- Common mistakes
Who Needs Captions?β
| Person | Why captions help |
|---|---|
| People who are deaf or hard of hearing | They are the only way to follow the speech and sounds |
| Someone in a noisy or quiet place | A busy station, an open office, or a sleeping baby |
| A language learner | Reading along helps them understand and remember |
| People with attention or processing differences | Text and sound together support focus |
| Anyone with a poor connection or bad speakers | Words stay clear, even if the sound is not |
Captions also let search engines and tools index what is said, and let visitors search and skim the text of a talk.
Adding Captionsβ
- HTML Code
- What Viewers See
<video controls width="640" height="360" src="lesson.mp4" crossorigin="anonymous">
<track
kind="captions"
src="lesson.en.vtt"
srclang="en"
label="English"
default
>
</video>
WEBVTT
00:00.000 --> 00:02.500
Welcome back! Today we will build
a signup form.
00:02.500 --> 00:05.000
[keyboard clicking]
First, open the editor.
00:06.000 --> 00:08.000
<v Asha>Any questions so far?
Contrast: 9.6 to 1. Excellent (7 to 1 or more).
This is a simulation of a video frame, so you can experiment safely. Real viewers can also override your styling with their own caption settings.
The player adds a "CC" or captions button, and viewers choose a track from its menu. The default attribute turns the track on from the start, and is a good idea for captions, since the people who need them may not be able to find the menu.
You met the <track> element in detail in Track. Captions are <track> with kind="captions", and a lot of care in the text.
Captions, Subtitles, and Transcriptsβ
| Captions | Subtitles | Transcript | |
|---|---|---|---|
| Audience | People who cannot hear | People who can hear but do not know the language | Anyone who prefers to read |
| Contains | Speech and important sounds and speakers | The translated speech only | The full text, on a page |
| Timed to the video? | Yes | Yes | No |
| HTML | track kind="captions" | track kind="subtitles" | Plain text next to the media |
You can offer all three. See Subtitles and Accessible Media.
What Good Captions Containβ
Good captions are complete, accurate, and clear:
- All the speech, in the order and way it is said, including words in other languages.
- Who is speaking, whenever it is not obvious:
<v Asha>, or a name in capital letters if your style guide uses them. - Important sounds: "[door slams]", "[phone ringing]", "[audience laughs]". Include sounds that carry meaning, but not every background noise.
- Music, described where it matters: "[tense music]", "[upbeat piano]". For songs, show the lyrics.
- Tone and manner when it changes the meaning: "[sarcastically]", "[whispering]".
- Off-screen speech and narration, marked so viewers know the speaker is not in view.
- Correct spelling and punctuation, with proper names written correctly.
What to avoid:
- Leaving things out to save space. If the speaker says it, the caption shows it.
- "Cleaning up" the meaning. You may drop "um" and stutters in most cases, but do not change what was said.
- Describing the picture ("A man walks into the room"). That is a job for descriptions, not captions.
- Spoilers in sound labels, such as "[the killer laughs]" before the reveal.
- Jokes or opinions in the sound labels.
Timing, Speed, and Line Lengthβ
Readable captions respect how people read:
| Guideline | Typical value |
|---|---|
| Characters per line | About 42 or fewer |
| Lines per cue | Two at most |
| Reading speed | About 15 to 20 characters per second (slower for children's content) |
| Cue length on screen | At least 1 second, and no more than about 7 seconds |
| Sync with speech | Appears within a fraction of a second of the words |
| Line breaks | At natural phrase breaks, not in the middle of a name or a phrase |
| Gap between cues | A brief gap, so the viewer sees one change to the next |
Style guides differ a little, so treat these as sensible defaults.
Good line breaks follow meaning:
Poor: I think the best way to build a
signup form is to start small.
Better: I think the best way
to build a signup form is to start small.
Try It: Check Your Captionsβ
Type captions in the form start-end | text, and the checker shows reading speed and problems. The example has one cue that flies by too fast. Try fixing it by splitting it into two cues, or by shortening the text.
- HTML Code
- Browser Output
// The same maths the checker uses
const characters = text.replace(/\s+/g, " ").trim().length;
const speed = characters / (end - start); // characters per second
if (speed > 20) console.log("Too fast: " + Math.round(speed) + " cps");
4 cues checked. 2 with problems.
| Time | Text | Speed | Notes |
|---|---|---|---|
| 0β2.5 s | Welcome back! Today we will build a signup form. | 19 cps | Good |
| 2.5β3.2 s | [keyboard clicking] First, open the editor and create a new file called index.html | 117 cps | Shown for under 1 second. Too short to read. Too fast: 117 characters per second (aim for about 15 to 20). A line is 82 characters. Keep lines to about 42 or fewer. |
| 3.2β6 s | [keyboard clicking] First, open the editor and create a new file. | 23 cps | Too fast: 23 characters per second (aim for about 15 to 20). |
| 6β8 s | ASHA: Any questions so far? | 14 cps | Good |
The numbers (about 42 characters per line, two lines, 15 to 20 characters per second) are common guidelines, not browser rules. Different style guides pick slightly different limits.
Styling Captionsβ
By default, browsers draw white text on a dark box at the bottom of the video. That is a safe choice. If you restyle with ::cue, do it carefully:
video::cue {
color: #fff;
background: rgba(0, 0, 0, 0.75);
font-family: system-ui, sans-serif;
font-size: 1.1rem;
}
- Keep strong contrast: at least 4.5 to 1 between the text and what is behind it. Play with the demo above to see how the picture behind the captions changes the contrast.
- Do not use colour alone to show speakers. Add names, too.
- Do not make captions too small. A viewer's own browser or device settings may also change them, and you should allow that.
- Use the VTT
linesetting to move captions away from important text in the picture (for example, a name tag at the bottom). - Respect viewer preferences. Many people set their own caption look in the device settings. Do not use
!importantto fight them.
Open and Closed Captionsβ
| Type | What it is | Good | Not so good |
|---|---|---|---|
| Closed captions | Separate text track that can be turned on and off | Searchable, resizable, translatable, can be turned off | Needs a player that supports them |
| Open captions | "Burned into" the picture | Always shown, even where there is no player support | Cannot be turned off, resized, translated, or searched. Poor on small screens |
For websites, use closed captions (<track>). Burned-in text is sometimes added in addition, for short social media clips, but it should never be the only option.
Automatic Captionsβ
Speech recognition tools can create a first draft quickly. But drafts are not finished captions:
- They misspell names, technical words, and accents.
- They miss punctuation, speaker changes, and sound descriptions.
- They can make serious or embarrassing mistakes, and sound sure of themselves while doing it.
A sensible workflow:
- Generate a draft with a tool.
- Review and fix every cue: spelling, names, speakers, sounds, line breaks, and timing.
- Have a second person check important content.
- Save as UTF-8
.vtt, and test it in the browser.
Plan for live content too. Live events need real-time captioning, either by a human captioner or a service, and the standards for live and pre-recorded video are different. For published, pre-recorded video, accurate captions are the usual expectation, and a legal requirement in many places. Check the rules that apply to you.
Accessibility at a Glanceβ
- Provide captions for all pre-recorded video with speech or meaningful sound.
- Include speakers and important sounds, not just the words.
- Make them accurate, in sync, and readable (line length, speed, and timing).
- Use
kind="captions"and a clearlabelandsrclang. - Use
default, so captions are on for people who need them. - Keep contrast high, and respect viewer settings.
- Check the menu with a keyboard and a screen reader.
- Also give a transcript where you can.
- Do not rely on auto-captions without a human review.
Security and Privacy Notesβ
- Captions are public text. A caption file can be read by anyone, so do not include private remarks, internal notes, or unreleased information in it, even in comments.
- Treat cue text as text, not HTML, when your script shows it on the page. Use
textContent. - Names and sensitive details spoken in a video appear in captions, and are searchable. Review them with the same care you give the video.
- Be careful with auto-caption services. Uploading recordings to a third party shares the audio, so check who receives it, where it is stored, and for how long.
- Serve
.vttfiles over HTTPS, with the correct type (text/vtt) and, for another origin, the right CORS headers.
Global Audience Notesβ
- Write the captions in the language of the audio. Translations belong in subtitles. See Subtitles.
- Set
srclangcorrectly (en,hi,ar), and write thelabelin the language itself. - Save files as UTF-8, so every script appears correctly.
- Line breaks differ between languages. A good break in English may be wrong in Japanese, Arabic, or German. Check with a native reader.
- Right-to-left languages are supported in WebVTT, but test numbers, English words, and punctuation, which can appear out of order.
- Reading speed varies by language and script. Languages with dense characters, such as Chinese, may use fewer characters per second, and some alphabets use more. Follow the guidance for each language.
- Do not translate sound labels word for word. Use the usual phrase in that language.
Common Mistakes to Avoidβ
- Using subtitles where captions are needed, so sounds and speakers are missing.
- Publishing automatic captions without review.
- No speaker names when the voice is unclear.
- Leaving out sounds that matter to the story.
- Cues that flash too fast, or stay on screen for too long.
- Long lines, or three or more lines.
- Line breaks in the middle of a phrase.
- Low contrast, or captions hidden behind other on-screen text.
- Burned-in captions as the only option.
- Captions that are out of sync with the speech.
- No
default, so the people who need captions must find the menu. - Files not saved as UTF-8, so non-English characters are broken.
Practice Timeβ
Try these in your editor, with a short video clip you have the right to use:
- Write a
.vttfile with five captioned cues, and attach it withkind="captions"anddefault. - Add a speaker name using
<v Name>. - Add two sound descriptions, such as "[applause]".
- Use the checker above to find a cue that is too fast, and fix it.
- Split a long cue into two, with natural line breaks.
- Style the captions with
::cue, and check the contrast. - Turn the captions on and off with the keyboard in your browser.
- Move a cue to the top with the VTT
linesetting. - Run an automatic captioning tool on a clip, and list every mistake it made.
- Bonus: write the transcript of the same clip, and put it next to the video in a
detailswidget.
Quick Recapβ
Click a question to check your answer.
1. What is the difference between captions and subtitles?
Captions are for people who cannot hear, so they include speech, speaker names, and important sounds. Subtitles translate speech for people who can hear but do not know the language.
2. How do you add captions in HTML?
Add a track element with kind="captions", src pointing to a WebVTT file, srclang, label, and usually default, inside the video element.
3. What should good captions include besides the words?
Speaker names where unclear, meaningful sounds and music, and tone where it changes the meaning, all with accurate spelling and good timing.
4. What are sensible limits for reading comfort?
About 42 characters per line, two lines per cue, roughly 15 to 20 characters per second, and a cue on screen for between about 1 and 7 seconds.
5. Why use closed captions instead of burned-in captions on a website?
Closed captions can be turned on and off, resized, translated, and searched. Burned-in text cannot, and it often looks poor on small screens.
6. Are automatic captions enough?
No. They are a first draft that needs a human review for names, technical words, punctuation, speakers, and sounds.
Key Takeawaysβ
- Captions turn speech and important sound into timed text, using
<track kind="captions">and a WebVTT file. - Good captions are complete, accurate, and in sync, with speaker names and sound descriptions.
- Aim for about 42 characters per line, two lines, and 15 to 20 characters per second, with line breaks at natural phrases.
- Keep contrast high (4.5 to 1 or better), and respect viewers' own caption settings.
- Prefer closed captions to burned-in ones, and add
default. - Review automatic captions by hand before publishing.
- Treat caption files as public text, and use
textContentwhen your script shows them. - Save as UTF-8, and write the captions in the language of the audio.
Next, learn how to reach viewers in other languages in Subtitles, or return to the Audio and Video overview.