HTML5 Video Element
The <video> element embeds video content in HTML without requiring plugins. It supports various formats, provides built-in controls, and offers a JavaScript API for custom players.
Basic Video Element
The <video> tag embeds video content with specified width and height.
The src attribute specifies the video file, or use <source> elements for multiple formats.
The controls attribute adds play, pause, volume, and fullscreen controls.
The poster attribute specifies an image to show before the video plays.
Always include fallback text or links for browsers without video support.
<!-- Simple video -->
<video src="movie.mp4" width="640" height="360" controls></video>
<!-- Video with poster image -->
<video width="640" height="360" controls poster="poster.jpg">
<source src="movie.mp4" type="video/mp4">
Your browser doesn't support HTML5 video.
</video>
<!-- Responsive video (uses CSS) -->
<video controls style="width: 100%; max-width: 800px;">
<source src="video.mp4" type="video/mp4">
</video>
Video Formats and Codecs
MP4 (H.264 codec) has the widest support - works in all modern browsers.
WebM (VP8/VP9 codec) is an open format supported by Chrome, Firefox, and Edge.
Ogg Theora is an older open format with declining support.
Always provide at least MP4 for compatibility, and optionally WebM for better compression.
Use the type attribute to specify the MIME type so browsers can skip unsupported formats quickly.
<!-- Best practice: MP4 and WebM -->
<video width="640" height="360" controls>
<source src="video.mp4" type="video/mp4">
<source src="video.webm" type="video/webm">
<p>Your browser doesn't support this video.
<a href="video.mp4">Download MP4</a></p>
</video>
<!-- With codec specifications -->
<video controls>
<source src="video.mp4" type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"'>
<source src="video.webm" type='video/webm; codecs="vp8, vorbis"'>
</video>
Video Attributes
width and height set dimensions in pixels (maintain aspect ratio with CSS instead).
controls shows the browser's default media controls.
autoplay starts playing automatically (may not work without muted attribute).
loop repeats the video continuously.
muted starts the video without sound.
preload suggests buffering behavior: none, metadata (default), or auto.
playsinline prevents fullscreen mode on iOS (useful for inline background videos).
<!-- Background video (autoplay, muted, loop) -->
<video autoplay muted loop playsinline id="bgVideo">
<source src="background.mp4" type="video/mp4">
</video>
<!-- Video that doesn't preload -->
<video controls preload="none" poster="thumbnail.jpg">
<source src="large-video.mp4" type="video/mp4">
</video>
<!-- Auto-playing video (must be muted) -->
<video autoplay muted controls width="640" height="360">
<source src="intro.mp4" type="video/mp4">
</video>
Subtitles and Captions
Use the <track> element to add subtitles, captions, or descriptions.
WebVTT (.vtt) is the standard format for text tracks.
The kind attribute specifies the track type: subtitles, captions, descriptions, chapters, or metadata.
The srclang attribute specifies the language (e.g., 'en', 'es', 'fr').
Use default attribute to enable a track by default.
Captions include sound effects and speaker identification, subtitles just translate dialogue.
<!-- Video with multiple caption tracks -->
<video width="640" height="360" controls>
<source src="movie.mp4" type="video/mp4">
<!-- English captions (default) -->
<track src="captions-en.vtt"
kind="captions"
srclang="en"
label="English"
default>
<!-- Spanish subtitles -->
<track src="subtitles-es.vtt"
kind="subtitles"
srclang="es"
label="EspaƱol">
<!-- Audio descriptions -->
<track src="descriptions.vtt"
kind="descriptions"
srclang="en"
label="Audio Descriptions">
</video>
JavaScript Video Control
The video element provides extensive JavaScript API for custom controls.
Properties: currentTime, duration, paused, ended, volume, playbackRate, videoWidth, videoHeight.
Methods: play(), pause(), load(), canPlayType().
Events: play, pause, ended, timeupdate, loadedmetadata, volumechange, error.
Use requestVideoFrameCallback() for frame-accurate operations.
<video id="myVideo" width="640" height="360">
<source src="video.mp4" type="video/mp4">
</video>
<div>
<button onclick="vid.play()">Play</button>
<button onclick="vid.pause()">Pause</button>
<button onclick="vid.currentTime = 0">Restart</button>
<input type="range" min="0" max="1" step="0.1" value="1"
onchange="vid.volume = this.value">
<span id="time">0:00 / 0:00</span>
</div>
<script>
const vid = document.getElementById('myVideo');
vid.addEventListener('timeupdate', function() {
const current = Math.floor(vid.currentTime);
const total = Math.floor(vid.duration);
document.getElementById('time').textContent =
`${current}:${String(current % 60).padStart(2,'0')} / ` +
`${total}:${String(total % 60).padStart(2,'0')}`;
});
</script>