LEARNING OBJECTIVES โต
- Understand the role of the
<track>element in embedding synchronized timed text streams into<video>and<audio>players. - Author valid WebVTT (
.vtt) files adhering strictly to the W3C WebVTT specification (timestamps, headers, voice tags). - Position and align cue boxes across the video canvas using cue settings (
line,position,size,align). - Style timed captions dynamically using the CSS
::cuepseudo-element and voice/class selector targets.
๐ The Mental Model & Story (Intuitive Foundation)
Imagine an opera performance where the performers sing in Italian. High above the stage, an electronic display board projects synchronized translations in English so the entire audience can follow the drama in real time.
+-----------------------------------------------------------------------------------+
| THE TIMED TEXT TRACK MENTAL MODEL |
+-----------------------------------------------------------------------------------+
| [ VIDEO TIMELINE CLOCK: 00:01:24.500 ] |
| | |
| v |
| [ WebVTT Cue Engine ] ---> Looks up active cues matching timestamp 01:24.500 |
| | |
| v |
| [ Rendered Overlay Surface ] ------------------------------------------------+ |
| | | |
| | (Actor speaking on left side of screen) | |
| | | |
| | +-------------------------------------------------------------+ | |
| | | [Dr. Sarah]: "The quantum encryption key is compromised." | | |
| | +-------------------------------------------------------------+ | |
| +----------------------------------------------------------------------------+ |
+-----------------------------------------------------------------------------------+
The <track> element acts as that digital projection system. It instructs the browser media engine to fetch a standalone text file formatted in WebVTT (Web Video Text Tracks), parse its millisecond-precision timestamps, synchronize words with the master video clock, and project styled caption overlays on top of the video frame.
Technical Deep Dive & Specifications
The <track> Element Syntax & Attributes
The <track> element is a void (self-closing) element placed as a child of <video> or <audio>:
<video controls src="presentation.mp4" width="800" height="450">
<!-- Primary English Captions (Turned on by default) -->
<track
kind="captions"
src="captions-en.vtt"
srclang="en"
label="English (CC)"
default>
<!-- Secondary Spanish Subtitles -->
<track
kind="subtitles"
src="subtitles-es.vtt"
srclang="es"
label="Espaรฑol">
</video>
| Attribute | Type | Description & Spec Rules |
|---|---|---|
kind |
Enum | Defines track type: subtitles, captions, descriptions, chapters, or metadata. (Defaults to subtitles). |
src |
URL | Path to the .vtt file. Must be served with MIME type text/vtt and proper CORS headers. |
srclang |
BCP 47 Language Tag | The language of the text track (e.g., en, es, fr, zh-CN). Required if kind="subtitles". |
label |
String | User-visible title shown in the native caption selection menu (e.g., "English Closed Captions"). |
default |
Boolean | Enables this track automatically when playback begins. Only one track per media element can have default. |
The Anatomy of a WebVTT File
A valid WebVTT file is a UTF-8 text file that MUST begin with the string WEBVTT:
WEBVTT - Optional Title or Metadata Header
NOTE
This is a multi-line comment block in WebVTT.
Comments are ignored by the browser parser.
00:00:01.000 --> 00:00:04.500
Welcome to the HTML5 Video Architecture Masterclass.
cue-identifier-02
00:00:05.250 --> 00:00:09.800 position:10%,line-left align:left size:80%
<v Professor Evans>Today, we'll explore <b>hardware decoders</b> and <c.highlight>GPU pipelines</c>.
Strict Syntax Rules for WebVTT:
- Header Signature: The file must begin with
WEBVTTon line 1, followed by a space, tab, or newline. - Timestamp Formatting:
hh:mm:ss.ttt(e.g.,01:14:22.500) ormm:ss.ttt(e.g.,04:12.800).- Milliseconds must be separated by an ASCII period (
.), never a comma (unlike legacy SRT formats which use commas).
- Arrow Delimiter: The timestamp separator
-->must have spaces on both sides:00:00:01.000 --> 00:00:04.000. - Blank Lines: Every cue must be separated from preceding cues by at least one blank newline.
Cue Placement Settings
By default, captions render centered at the bottom of the video. You can customize position via cue settings after the timestamp arrow:
00:00:02.000 --> 00:00:06.000 line:10% position:80% align:right size:50%
This text is positioned near the top-right corner!
+-------------------------------------------------------------------------------+
| WEBVTT CUE POSITIONING GRID |
+-------------------------------------------------------------------------------+
| line: 10% (Top of screen) -------------------------------------------+ |
| | |
| line: 50% (Middle of screen) -------------------------------------------+ |
| | |
| line: 90% (Bottom of screen) -------------------------------------------+ |
| |
| position: 0% (Left) position: 50% (Center) position: 100% (Right) |
+-------------------------------------------------------------------------------+
line:<percentage>|<integer>: Vertical offset.line:0%is top,line:90%is near bottom. Negative integers (e.g.,line:-1) count upwards from the bottom line.position:<percentage>: Horizontal anchor point across the video box (0% to 100%).size:<percentage>: Width of the caption bounding box (default is 100%).align:start|center|end|left|right: Text alignment within the cue box.
WebVTT Inline Formatting Tags
WebVTT allows semantic markup within cue payloads:
| Tag Syntax | Purpose | Rendered Result |
|---|---|---|
<b>Bold Text</b> |
Bold font weight | Displays Bold Text. |
<i>Italic Text</i> |
Italicized emphasis | Displays Italic Text. |
<u>Underline</u> |
Underlined text | Displays Underline. |
<v Speaker Name>Dialogue</v> |
Voice / Speaker identifier | Identifies who is speaking for accessibility. |
<c.warning>Alert</c> |
Custom CSS class hook | Allows targeted styling via ::cue(.warning). |
<lang es>Hola</lang> |
Inline language declaration | Declares pronunciation/text rules for screen readers. |
Styling Captions with the CSS ::cue Pseudo-Element
You can style WebVTT captions using the standard CSS ::cue pseudo-element:
/* Style all video cues universally */
video::cue {
background-color: rgba(15, 23, 42, 0.9);
color: #38bdf8;
font-family: system-ui, -apple-system, sans-serif;
font-size: 1.1rem;
line-height: 1.4;
border-radius: 4px;
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.8);
}
/* Style specific speaker voices */
video::cue(v[voice="Professor Evans"]) {
color: #facc15; /* Yellow text for professor */
}
/* Style custom classes defined in VTT */
video::cue(.highlight) {
color: #4ade80;
font-weight: bold;
}
๐ป Interactive Code Playground
Starter Code
Line-by-Line Code Breakdown
- Lines 26โ39 (
video::cue { ... }):- Applies styling to WebVTT cues across all tracks rendered by the browser's User-Agent Shadow DOM text renderer.
- Line 50 (
crossorigin="anonymous"):- Crucial Requirement: The
<track>element strictly obeys CORS. If your.vttfile is served from a remote origin, you must setcrossoriginon the<video>tag; otherwise, the track will be blocked.
- Crucial Requirement: The
- Line 57 (
<track kind="captions" srclang="en" default ...>):- Declares an English closed captions track and activates it by default via the boolean
defaultattribute.
- Declares an English closed captions track and activates it by default via the boolean
Expected Browser Render Output
+-------------------------------------------------------------+
| Synchronized WebVTT Timed Text |
| +---------------------------------------------------------+ |
| | | |
| | [ FLOWER BLOOMING ] | |
| | | |
| | +-------------------------------------------+ | |
| | | Narrator: The sun gently illuminates... | | |
| | +-------------------------------------------+ | |
| | | |
| | [ > ] [===o=========================] 0:01 / 0:05 [๐][โถ]| |
| +---------------------------------------------------------+ |
+-------------------------------------------------------------+๐๏ธ Hands-On Exercise
๐ฏ The Challenge: Author & Style a Multi-Speaker WebVTT Caption File
Instructions:
- Create a
<video>element withcontrols,crossorigin="anonymous", and sample videohttps://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.mp4. - Construct a valid WebVTT string containing at least 2 distinct dialogue cues:
- Cue 1 (0.5s to 2.5s): Voice tag for
<v Alice>Hello Bob, how is the deployment going?</v>. - Cue 2 (2.8s to 5.0s): Voice tag for
<v Bob>The edge nodes are <c.status-ok>healthy</c> and responding.</v>.
- Cue 1 (0.5s to 2.5s): Voice tag for
- Add custom CSS with
::cueso that:- Alice's text renders in
#38bdf8(sky blue). - Bob's text renders in
#f59e0b(amber). - The
.status-okclass renders in#22c55e(green) with bold text.
- Alice's text renders in
๐ Starter Code Sandbox
โ ๏ธ Common Pitfalls
- Using Commas in WebVTT Timestamps: In legacy SubRip (
.srt) files, timestamps use commas (00:00:01,500). In WebVTT, timestamps must use a period (00:00:01.500). A comma will cause the parser to discard the cue entirely. - Missing
crossoriginon Remote Track Requests: Even if your video loads fine from an external CDN, WebVTT track files are subject to strict CORS checks. If the CDN lacksAccess-Control-Allow-Origin: *or if the<video>tag lackscrossorigin="anonymous", the track will silently fail to load. - Missing
WEBVTTHeader on Line 1: If the file does not begin withWEBVTTas the first 6 bytes, the browser's timed-text parser will reject the file as invalid MIME/text.
๐ก Pro Tips
- Server MIME Type Configuration: Ensure your web server (Nginx/Apache/Caddy) serves
.vttfiles withContent-Type: text/vtt; charset=utf-8. If served astext/plainorapplication/octet-stream, some browsers will refuse to parse cues. - Programmatic Cue Inspection via
TextTrackList: You can access active subtitles in JavaScript usingvideo.textTracks[0].activeCuesto display real-time live transcripts in an external DOM container outside the video viewport!
๐ Key Takeaways
- The
<track>element links synchronized timed text (WebVTT) to<video>and<audio>elements. - Valid WebVTT files must begin with
WEBVTTand use period-delimited millisecond timestamps (00:00:00.000). - Cue settings (
line:,position:,size:,align:) allow precise rectangular placement of captions across the video canvas. - WebVTT supports voice markup (
<v Speaker>) and class markup (<c.classname>). - Subtitles can be styled in CSS using the
::cue,::cue(v[voice="..."]), and::cue(.class)pseudo-elements. - --