Audio & Video
Video & Video Tags
Embed and control videos on your web pages using HTML5's native video element. Learn about formats, accessibility, responsive video, and best practices.
The <video> Element
The <video> element embeds video content natively in HTML, without requiring plugins like Flash.
Basic Video Syntax
HTML
<video controls>
<source src="video.mp4" type="video/mp4">
<source src="video.webm" type="video/webm">
Your browser doesn't support video playback.
</video>Video Attributes
1. controls - Show Player Controls
HTML
<!-- With controls (play, pause, volume, etc.) -->
<video src="video.mp4" controls></video>
<!-- Without controls (requires JavaScript control) -->
<video src="video.mp4"></video>2. autoplay - Auto-start Video
HTML
<!-- Autoplay (needs muted for most browsers) -->
<video src="video.mp4" autoplay muted></video>âš ï¸ Autoplay Restrictions: Most browsers block autoplay with sound. Videos must be muted (
muted) to autoplay.3. loop - Repeat Video
HTML
<!-- Loop indefinitely -->
<video src="video.mp4" loop muted autoplay></video>4. muted - Start Muted
HTML
<!-- Start with audio muted -->
<video src="video.mp4" controls muted></video>5. poster - Thumbnail Image
HTML
<!-- Show poster image before playback -->
<video src="video.mp4" controls poster="thumbnail.jpg"></video>6. preload - Loading Strategy
HTML
<!-- Don't preload (save bandwidth) -->
<video src="video.mp4" controls preload="none"></video>
<!-- Preload metadata only (duration, dimensions) -->
<video src="video.mp4" controls preload="metadata"></video>
<!-- Preload entire video (default) -->
<video src="video.mp4" controls preload="auto"></video>| Value | Behavior | Use Case |
|---|---|---|
none | Don't preload anything | Save bandwidth, user may not watch |
metadata | Load metadata (duration, size) | Show duration, save bandwidth |
auto | Preload entire video (default) | User likely to watch immediately |
7. width and height
HTML
<!-- Fixed dimensions -->
<video src="video.mp4" controls width="640" height="360"></video>
<!-- Responsive with CSS (preferred) -->
<video src="video.mp4" controls style="width: 100%; height: auto;"></video>Video Formats
Different browsers support different video formats. Provide multiple formats:
Multiple Source Formats
HTML
<video controls width="640" height="360">
<!-- MP4 (H.264) - Best compatibility -->
<source src="video.mp4" type="video/mp4">
<!-- WebM (VP9) - Good compression, open source -->
<source src="video.webm" type="video/webm">
<!-- Ogg (Theora) - Older open source format -->
<source src="video.ogg" type="video/ogg">
<!-- Fallback message -->
Your browser doesn't support the video tag.
</video>Video Format Comparison:
| Format | Extension | Codec | Browser Support | Quality |
|---|---|---|---|---|
| MP4 | .mp4 | H.264 | Universal ✅ | Excellent |
| WebM | .webm | VP8/VP9 | Chrome, Firefox, Edge | Excellent |
| Ogg | .ogg, .ogv | Theora | Firefox, Chrome | Good |
💡 Recommendation: Provide MP4 (H.264) for maximum compatibility, plus WebM for better compression. MP4 should be listed first.
Responsive Video
CSS-Only Responsive
HTML
<video src="video.mp4" controls></video>
<style>
video {
max-width: 100%;
height: auto;
display: block;
}
</style>Maintain Aspect Ratio (16:9)
HTML
<div class="video-container">
<video src="video.mp4" controls></video>
</div>
<style>
.video-container {
position: relative;
width: 100%;
padding-bottom: 56.25%; /* 16:9 aspect ratio */
height: 0;
overflow: hidden;
}
.video-container video {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
</style>Common Aspect Ratios:
- 16:9 (widescreen):
padding-bottom: 56.25% - 4:3 (standard):
padding-bottom: 75% - 21:9 (ultra-wide):
padding-bottom: 42.857% - 1:1 (square):
padding-bottom: 100%
Subtitles & Captions
Add accessibility with <track> element:
Video with Subtitles
HTML
<video controls>
<source src="video.mp4" type="video/mp4">
<!-- Subtitles (translations) -->
<track
kind="subtitles"
src="subtitles-en.vtt"
srclang="en"
label="English"
>
<track
kind="subtitles"
src="subtitles-es.vtt"
srclang="es"
label="Español"
>
<!-- Captions (for deaf/hard-of-hearing) -->
<track
kind="captions"
src="captions-en.vtt"
srclang="en"
label="English Captions"
default
>
</video>Track Kinds:
subtitles- Translations of dialoguecaptions- Dialogue + sound effects (for accessibility)descriptions- Audio descriptions of visual contentchapters- Chapter titles for navigationmetadata- Metadata for scripts
WebVTT File Format (.vtt):
captions-en.vtt
HTML
WEBVTT
00:00:00.000 --> 00:00:03.000
Welcome to our video tutorial!
00:00:03.500 --> 00:00:07.000
Today we'll learn about HTML video.
00:00:07.500 --> 00:00:11.000
Let's get started with the basics.Background Video
Create hero sections with background video:
Hero Section with Video Background
HTML
<div class="hero">
<video class="hero-video" autoplay muted loop playsinline>
<source src="hero-video.mp4" type="video/mp4">
<source src="hero-video.webm" type="video/webm">
</video>
<div class="hero-content">
<h1>Welcome to Our Site</h1>
<p>Innovative solutions for modern problems</p>
<button>Learn More</button>
</div>
</div>
<style>
.hero {
position: relative;
width: 100%;
height: 100vh;
overflow: hidden;
}
.hero-video {
position: absolute;
top: 50%;
left: 50%;
min-width: 100%;
min-height: 100%;
width: auto;
height: auto;
transform: translate(-50%, -50%);
z-index: -1;
object-fit: cover;
}
.hero-content {
position: relative;
z-index: 1;
text-align: center;
color: white;
padding: 2rem;
margin-top: 30vh;
}
/* Mobile: use static image instead */
@media (max-width: 768px) {
.hero-video {
display: none;
}
.hero {
background-image: url('hero-fallback.jpg');
background-size: cover;
background-position: center;
}
}
</style>Mobile Consideration: Background videos consume data and battery. Consider using a static image on mobile devices.
Custom Video Controls (JavaScript)
Build custom controls for more control over styling:
Custom Video Player
HTML
<div class="video-player">
<video id="myVideo">
<source src="video.mp4" type="video/mp4">
</video>
<div class="controls">
<button id="playPause">Play</button>
<input type="range" id="seekBar" value="0" max="100">
<button id="mute">Mute</button>
<input type="range" id="volumeBar" min="0" max="100" value="100">
<span id="currentTime">0:00</span> / <span id="duration">0:00</span>
<button id="fullscreen">Fullscreen</button>
</div>
</div>
<script>
const video = document.getElementById('myVideo');
const playPause = document.getElementById('playPause');
const seekBar = document.getElementById('seekBar');
const volumeBar = document.getElementById('volumeBar');
const muteBtn = document.getElementById('mute');
const fullscreenBtn = document.getElementById('fullscreen');
// Play/Pause
playPause.addEventListener('click', () => {
if (video.paused) {
video.play();
playPause.textContent = 'Pause';
} else {
video.pause();
playPause.textContent = 'Play';
}
});
// Seek
seekBar.addEventListener('input', () => {
const time = video.duration * (seekBar.value / 100);
video.currentTime = time;
});
video.addEventListener('timeupdate', () => {
const value = (video.currentTime / video.duration) * 100;
seekBar.value = value;
// Update time display
document.getElementById('currentTime').textContent =
formatTime(video.currentTime);
});
// Volume
volumeBar.addEventListener('input', () => {
video.volume = volumeBar.value / 100;
});
// Mute
muteBtn.addEventListener('click', () => {
video.muted = !video.muted;
muteBtn.textContent = video.muted ? 'Unmute' : 'Mute';
});
// Fullscreen
fullscreenBtn.addEventListener('click', () => {
if (video.requestFullscreen) {
video.requestFullscreen();
}
});
// Duration
video.addEventListener('loadedmetadata', () => {
document.getElementById('duration').textContent =
formatTime(video.duration);
});
function formatTime(seconds) {
const min = Math.floor(seconds / 60);
const sec = Math.floor(seconds % 60);
return `${min}:${sec.toString().padStart(2, '0')}`;
}
</script>Embedding YouTube/Vimeo Videos
YouTube Embed
HTML
<!-- Responsive YouTube embed -->
<div class="video-container">
<iframe
width="560"
height="315"
src="https://www.youtube.com/embed/VIDEO_ID"
title="YouTube video player"
frameborder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowfullscreen
></iframe>
</div>
<style>
.video-container {
position: relative;
padding-bottom: 56.25%; /* 16:9 */
height: 0;
}
.video-container iframe {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
</style>Vimeo Embed
HTML
<div class="video-container">
<iframe
src="https://player.vimeo.com/video/VIDEO_ID"
frameborder="0"
allow="autoplay; fullscreen; picture-in-picture"
allowfullscreen
></iframe>
</div>Video Optimization
✅ Optimization Checklist:
- ☑ Compress videos: Use tools like HandBrake, FFmpeg
- ☑ Multiple formats: MP4 + WebM for best compatibility
- ☑ Appropriate resolution: Don't serve 4K for mobile
- ☑ Use poster images: Show thumbnail before playback
- ☑ Lazy load: Use
preload="none"orpreload="metadata" - ☑ CDN hosting: Serve videos from CDN
- ☑ Add captions: Essential for accessibility
- ☑ Responsive sizing: Scale for different screens
Recommended Settings:
| Device | Resolution | Bitrate |
|---|---|---|
| Mobile | 720p (1280×720) | 1-2 Mbps |
| Tablet | 1080p (1920×1080) | 3-5 Mbps |
| Desktop | 1080p-4K | 5-10 Mbps |
Best Practices Summary
✅ Do
- Provide multiple video formats
- Add subtitles/captions for accessibility
- Use poster images
- Optimize video file sizes
- Make videos responsive
- Include controls attribute
- Use preload wisely
- Test on multiple browsers/devices
⌠Don't
- Autoplay with sound (blocked by browsers)
- Use only one video format
- Serve huge uncompressed videos
- Forget accessibility (captions)
- Assume autoplay will work
- Use background video on mobile
- Forget poster images
- Preload all videos on page