🎉
Lesson Complete!
Video embedding mastered! Next: iframe — embed YouTube, maps, and third-party content.
🎬 Phase 7 · Media & Embeds🟢 BeginnerModule 08

HTML Video

⏱ 16 min read📖 4 sections🧩 5-question quiz
Course Progress77% complete
The <video> element works almost identically to <audio> — same <source> pattern, same attribute family — but adds visual-specific features: a poster image, width/height, and the crucial <track> element for synchronized captions. Accessible video is also a legal requirement in many jurisdictions.

The video Element

The most important video attribute beyond controls is poster — the image shown before playback starts. Without it, the video shows a black frame (or the first frame) while loading, which looks broken.

HTMLFull-featured video player
<video
  controls
  poster="thumbnail.jpg"
  width="800"
  height="450"
  preload="metadata">

  <!-- Sources — browser picks the first it supports -->
  <source src="lesson.webm" type="video/webm">
  <source src="lesson.mp4"  type="video/mp4">

  <!-- Captions (WebVTT format) -->
  <track
    kind="captions"
    src="captions-en.vtt"
    srclang="en"
    label="English"
    default>

  <!-- Fallback for very old browsers -->
  <p>Your browser can't play this video.
     <a href="lesson.mp4">Download it</a>.
  </p>
</video>
💡
Always set width and height
Setting width and height on <video> lets the browser reserve space before the video loads, preventing Cumulative Layout Shift (CLS) — a Core Web Vitals metric that affects SEO. Use the video's actual aspect ratio. You can then override with CSS to make it responsive.

Video Formats & Attributes

FormatMIME typeChromeFirefoxSafariNotes
MP4 / H.264video/mp4YesYesYesUniversal — safest single format
WebM / VP9video/webmYesYes14.1+Smaller than MP4 at same quality
OGG / Theoravideo/oggYesYesNoOutdated — avoid

Strategy: Encode WebM (VP9) as the first <source> (smaller file, Chrome/Firefox pick it) and MP4 (H.264) as the fallback (Safari + universal compatibility).

controls
boolean
Shows native play/pause, seek bar, volume, fullscreen
poster
URL string
Image shown before playback starts — use a custom thumbnail
autoplay
boolean
Blocked by browsers unless muted is also present
muted
boolean
Starts muted. Required to allow autoplay
loop
boolean
Restarts video when it ends
playsinline
boolean
iOS: plays in-page instead of fullscreen. Required for background/looping videos on iPhone
preload
"none"|"metadata"|"auto"
Download hint. Use "metadata" for videos above the fold
width / height
integer (px)
Intrinsic dimensions — reserve space, prevent layout shift

Captions with <track>

The <track> element adds synchronized text to a video. Captions are mandatory for accessibility compliance (WCAG 2.1 AA, ADA). The file format is WebVTT (.vtt) — a plain text file with timestamped cues.

VTTcaptions-en.vtt — minimal WebVTT file
WEBVTT

00:00:00.000 --> 00:00:03.500
Welcome to Lesson 27 — HTML Video.

00:00:03.600 --> 00:00:07.200
In this lesson we'll cover the video element,
formats, and captions.

00:00:07.300 --> 00:00:10.000
Let's get started.
track kindPurpose
captionsDialogue + sound effects for deaf/hard-of-hearing users
subtitlesDialogue translation for users who don't speak the audio language
descriptionsAudio descriptions of visual content for blind users
chaptersNamed chapter points for navigation
metadataData processed by scripts — not displayed to users
⚠️
Captions vs Subtitles — not the same
kind="captions" includes non-speech audio information ("[doorbell rings]", "[tense music]") — it's the full accessibility version. kind="subtitles" is just spoken dialogue, translated. Use captions when your audience might be deaf or hard-of-hearing; use subtitles for language translation only.

Responsive Video

By default <video> is a fixed-width element. To make it fluid — expanding to fill its container while maintaining aspect ratio — use the modern aspect-ratio CSS property:

HTML + CSSResponsive 16:9 video
<!-- HTML -->
<div class="video-wrap">
  <video controls poster="thumb.jpg"
         width="1280" height="720">
    <source src="video.webm" type="video/webm">
    <source src="video.mp4"  type="video/mp4">
  </video>
</div>

/* CSS */
.video-wrap {
  width: 100%;
  aspect-ratio: 16 / 9;    /* maintains ratio */
}
.video-wrap video {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

For hero background videos (autoplay, muted, looping, no controls) that fill a section, also add playsinline — without it, iOS Safari opens the video in a fullscreen native player instead of playing it inline.

HTMLHero background video — correct attributes
<video
  autoplay muted loop playsinline
  poster="hero-fallback.jpg"
  aria-hidden="true">   <!-- decorative: hide from AT -->
  <source src="hero.webm" type="video/webm">
  <source src="hero.mp4"  type="video/mp4">
</video>
🧩 Quick Check — Lesson 27
5 questions · instant feedback
1. What does the poster attribute on a video element do?
2. Which video format should you list FIRST in your source elements for best results?
3. What is the difference between track kind="captions" and kind="subtitles"?
4. Why should you add playsinline to a background/looping video?
5. Why is setting width and height on the video element important for performance?
🎬
Video Mastered!
Next: iframes — embed YouTube, Google Maps, and any third-party content.
🏆
Lesson 27 Challenge
Build exercise · 20 min
Build a video course lesson page with accessible video player.

Requirements:
- A responsive video player (100% width, 16:9 aspect-ratio) with WebM + MP4 sources, a poster image, preload="metadata"
- A track element for English captions (create a minimal .vtt file with 3 cues)
- A figure element wrapping the video with a figcaption showing the video title
- Below the video: video metadata section with the duration (use <time>), author, and upload date
- A "Video description" section using <details>/<summary>
- A sidebar aside with "Up next" — 3 linked video thumbnails (fake img elements with aspect-ratio:16/9)

Bonus: Add a CSS class .decorative-video for the hero scenario (autoplay muted loop playsinline aria-hidden) and write CSS that positions it as a full-width background with a dark overlay on top.
Show hints
  • aspect-ratio: 16/9 on the wrapper div, then video { width:100%; height:100%; }
  • VTT file needs "WEBVTT" on the first line, then blank line, then timestamp --> timestamp, then text
  • The hero overlay: position:relative on wrapper, ::after pseudo-element with position:absolute inset:0 background:rgba(0,0,0,.5)
  • Thumbnail cards: div with aspect-ratio:16/9, background-color:#111, border-radius
← Audio
Lesson 27 of 35