Video

Difficulty: Intermediate

The <video> element embeds video content in an HTML document, providing native playback without requiring third-party plugins. Similar to the <audio> element, it supports multiple source formats, built-in controls, and various attributes to control playback behavior. Video is one of the most engaging content types on the web, and using the native element correctly is essential for performance and accessibility.

The poster attribute specifies an image to show before the video starts playing. This is the thumbnail that represents the video content. Without a poster, browsers typically show the first frame of the video, which might be a black screen or an unrepresentative frame. A well-chosen poster image gives users a preview of what the video contains and makes the page look polished before any video data is loaded.

Video format support varies across browsers, but two formats cover nearly all modern browsers: MP4 with H.264 codec (video/mp4), which has universal support, and WebM with VP9 codec (video/webm), which offers better compression and is supported in Chrome, Firefox, and Edge. Always provide MP4 as a fallback since it works everywhere. Provide <source> elements in order of preference, with the most efficient format first and the most compatible format last.

Making videos responsive requires CSS since the <video> element behaves like a replaced element with intrinsic dimensions. The simplest approach is setting max-width: 100% and height: auto on the video element. For maintaining aspect ratios in flexible layouts, the modern CSS aspect-ratio property or the traditional padding-bottom trick on a wrapper div can be used. For embedded videos from platforms like YouTube (using iframes), a responsive wrapper is essential.

Video content should be accessible. Provide captions using the <track> element with WebVTT (.vtt) files. Captions are essential for deaf and hard-of-hearing users and also benefit users watching in noisy environments or who prefer reading. Provide at minimum a captions track, and ideally also descriptions and subtitles in multiple languages. The <track> element supports kinds including subtitles, captions, descriptions, chapters, and metadata.

Code examples

Basic Video with Controls and Poster

<video controls 
       poster="/images/video-thumbnail.jpg" 
       width="800" 
       height="450">
  <source src="/video/intro.webm" type="video/webm">
  <source src="/video/intro.mp4" type="video/mp4">
  Your browser does not support the video element.
</video>

The poster attribute shows a thumbnail before playback. Multiple <source> elements provide format fallbacks. WebM is listed first for browsers that support it (better compression), with MP4 as the universal fallback.

Video with Captions Track

<video controls 
       poster="/images/lecture-thumb.jpg"
       width="800" 
       height="450"
       preload="metadata">
  <source src="/video/lecture.mp4" type="video/mp4">
  
  <!-- Captions for deaf/hard-of-hearing -->
  <track kind="captions" 
         src="/captions/lecture-en.vtt" 
         srclang="en" 
         label="English" 
         default>
  
  <!-- Subtitles in Spanish -->
  <track kind="subtitles" 
         src="/captions/lecture-es.vtt" 
         srclang="es" 
         label="Spanish">
  
  <!-- Chapter markers -->
  <track kind="chapters" 
         src="/captions/lecture-chapters.vtt" 
         srclang="en">
</video>

The <track> element adds text tracks to video. 'captions' include sound effects and speaker identification; 'subtitles' are translations of dialogue. The 'default' attribute auto-enables the English captions. Chapter tracks allow navigation to specific sections.

Responsive Video with CSS

<!-- HTML -->
<video class="responsive-video" 
       controls 
       poster="/images/demo-poster.jpg">
  <source src="/video/demo.mp4" type="video/mp4">
</video>

<style>
  /* Simple responsive video */
  .responsive-video {
    max-width: 100%;
    height: auto;
  }

  /* Fixed aspect ratio container (16:9) */
  .video-container {
    position: relative;
    width: 100%;
    aspect-ratio: 16 / 9;
  }
  .video-container video {
    width: 100%;
    height: 100%;
    object-fit: cover;
  }
</style>

Setting max-width: 100% and height: auto makes the video scale down on small screens while maintaining its aspect ratio. The aspect-ratio property provides a clean way to enforce 16:9 or other ratios. object-fit: cover fills the container without distortion.

Video with Playback Attributes

<!-- Muted autoplay (for hero background videos) -->
<video autoplay muted loop playsinline 
       poster="/images/bg-poster.jpg">
  <source src="/video/background.webm" type="video/webm">
  <source src="/video/background.mp4" type="video/mp4">
</video>

<!-- Controlled preloading -->
<video controls 
       preload="none" 
       poster="/images/tutorial-thumb.jpg"
       width="640" 
       height="360">
  <source src="/video/tutorial.mp4" type="video/mp4">
</video>

Muted autoplay with loop is the pattern for background hero videos. The playsinline attribute prevents iOS from forcing fullscreen playback. preload='none' is important for pages with multiple videos to avoid downloading all of them on page load.

Key points

Concepts covered

video Element, poster Attribute, controls, source Element, Responsive Video, Video Formats