⚔IntermediateAdvanced Media

Video Tracks and Captions

Add captions, subtitles, and descriptions to video with the <track> element and WebVTT format.

Overview

The <track> element adds timed text tracks to <video> and <audio> elements captions, subtitles, descriptions, chapters, and metadata. It is how you make multimedia content accessible to deaf/hard-of-hearing users and non-native speakers. Track files use the WebVTT (Web Video Text Tracks) format a plain text file with .vtt extension. Each cue has a start time, end time, and text. Track kinds: - subtitles: translations of the dialogue - captions: transcription including sound effects and speaker cues (for deaf users) - descriptions: spoken audio descriptions for blind users - chapters: navigation chapters - metadata: non-visible data used by JavaScript

Key Points

  • •<track src="captions.vtt" kind="captions" srclang="en" label="English" default>
  • •kind="captions" includes non-speech audio cues; kind="subtitles" is for translations
  • •srclang specifies the language of the track (ISO 639-1 code: en, fr, es)
  • •label is the user-visible name shown in the CC menu
  • •default selects this track by default if the user's preferences match
  • •WebVTT format: WEBVTT header, then cue blocks with timestamps

Examples

Video with captions and subtitles

<video controls width="640" height="360" poster="thumbnail.jpg">
  <source src="lecture.mp4" type="video/mp4">
  <source src="lecture.webm" type="video/webm">

  <!-- English captions (for deaf users) -->
  <track
    src="captions-en.vtt"
    kind="captions"
    srclang="en"
    label="English"
    default
  >

  <!-- Spanish subtitles (translation) -->
  <track
    src="subtitles-es.vtt"
    kind="subtitles"
    srclang="es"
    label="EspaƱol"
  >

  <!-- Audio description for visually impaired -->
  <track
    src="descriptions.vtt"
    kind="descriptions"
    srclang="en"
    label="Audio Descriptions"
  >
</video>

WebVTT file format

WEBVTT

00:00:01.000 --> 00:00:04.000
Hello, and welcome to this HTML tutorial.

00:00:04.500 --> 00:00:08.000
Today we will cover the track element
and WebVTT captions.

00:00:08.500 --> 00:00:12.000
[Typing sounds]
Let's look at the code.

Save as captions.vtt. Times are HH:MM:SS.mmm format.

Accessing tracks via JavaScript

const video = document.querySelector('video');

// List all tracks
[...video.textTracks].forEach(track => {
  console.log(track.kind, track.label, track.language);
});

// Enable a specific track
video.textTracks[0].mode = 'showing'; // 'showing' | 'hidden' | 'disabled'

// Listen for cue changes
video.textTracks[0].addEventListener('cuechange', () => {
  const activeCues = video.textTracks[0].activeCues;
  if (activeCues.length) {
    console.log(activeCues[0].text);
  }
});

Common Mistakes

  • Confusing captions and subtitles: captions include all audio context; subtitles are dialogue translations
  • Not including default on any track no captions are shown unless the user manually enables them
  • Using absolute paths for track src in development use relative paths or a local server

Note

WCAG 2.1 SC 1.2.2 requires captions for all pre-recorded video. The <track kind="captions"> element is the HTML-native way to comply. Auto-generate VTT files with tools like YouTube's auto-captions export or OpenAI Whisper.

Exercises

Write HTML to solve each exercise. Use Preview to see it render in a live iframe, then mark as done.

Loading editor…

Completed: 0 / 5 exercises

Knowledge Check

Question 1 of 4

What is the difference between track kind="captions" and kind="subtitles"?