Audio and Video in HTML
Native media playback with no plugin. Learn the controls, the source fallback pattern, autoplay rules that will catch you out, and why captions are not optional.
-
HTML Basics
- What is HTML: The Structure Layer of Every Web Page
- HTML Document Structure: DOCTYPE, html, head and body
- Elements, Tags and Attributes: The Vocabulary of HTML
- HTML Comments: Notes That Ship With Your Code
- Block Level and Inline Elements
- Writing and Running Your First HTML Page
- How a Browser Turns Markup Into a Page
- Text and Formatting
- Links and Navigation
- Images and Media
- Lists
- Tables
-
Forms
- Form Structure: form, action and method
- Input Types: Text, Email, Number, Date and the Rest
- Labels: The Most Important Element in a Form
- Checkboxes, Radio Buttons and Grouping
- select, option, optgroup and datalist
- textarea, File Uploads and Hidden Fields
- Buttons: submit, reset and button
- Built In Form Validation
- GET or POST: What Happens When a Form Is Submitted
- Semantic HTML
- HTML5 Features
- Head and Metadata
- HTML with CSS
- HTML with JavaScript
- Accessibility
-
HTML SEO
- How Google Works: Crawling, Indexing and Ranking
- SEO Friendly HTML Structure
- Titles and Descriptions That Earn Clicks
- Headings and Content Structure for Search
- Internal Linking and Anchor Text
- robots.txt and XML Sitemaps
- Canonical URLs and Duplicate Content
- Structured Data and JSON-LD
- Image SEO
- Core Web Vitals and Mobile Friendliness
- DevTools and Debugging
- Editor Productivity
- HTML Best Practices
- HTML Projects
- Advanced Projects
- Practice and Exams
Concept
audio and video play media natively. Before them, sound and video on the web meant a plugin; today the browser provides the player, the keyboard support and the accessibility integration for free.
Syntax
<video src="clip.mp4" controls width="800" height="450"></video>
<audio src="episode.mp3" controls></audio>Neither is a void element. Both need a closing tag, because content between the tags is the fallback for a browser that cannot play them.
The attributes
| Attribute | Effect |
|---|---|
controls | Show the built in player. Without it there is no way to press play. |
autoplay | Start without interaction. Blocked unless also muted. |
muted | Start with no sound. |
loop | Restart when it ends. |
poster | Video only: an image shown before playback starts. |
preload | none, metadata or auto. How much to fetch up front. |
playsinline | Play in place on mobile rather than going full screen. |
Multiple sources
Not every browser supports every codec. Offering several source elements lets the browser take the first one it can play.
<video controls width="960" height="540" poster="/media/cover.jpg" preload="metadata">
<source src="/media/tour.webm" type="video/webm">
<source src="/media/tour.mp4" type="video/mp4">
<track kind="captions" src="/media/tour-en.vtt" srclang="en" label="English" default>
<p>Your browser cannot play this video.
<a href="/media/tour.mp4">Download it instead</a>.</p>
</video>Order matters: put the format you would prefer first. The type attribute lets the browser skip a file it cannot decode without downloading any of it. When source elements are used, the outer element must not also have a src.
Captions and the track element
track attaches a timed text file in WebVTT format. This is not a nice extra; for most public and institutional sites it is a legal requirement, and it benefits far more people than it is usually credited with - anyone in a noisy room, anyone watching without sound, anyone reading in a second language.
<track kind="captions" src="/media/tour-en.vtt" srclang="en" label="English" default>
<track kind="subtitles" src="/media/tour-hi.vtt" srclang="hi" label="Hindi">
<track kind="descriptions" src="/media/tour-desc.vtt" srclang="en" label="Audio description">A minimal WebVTT file looks like this:
WEBVTT
00:00:00.000 --> 00:00:04.500
The workshop opens at seven every morning.
00:00:04.500 --> 00:00:09.000
[machinery starts]
Two presses run until noon.Captions include sound that carries meaning, in square brackets. Subtitles assume the viewer can hear and only translate speech. They are different kinds and browsers treat them differently.
The autoplay rules
Every browser now blocks audible autoplay. A video will start on its own only if it is muted:
<!-- silently blocked in every current browser -->
<video src="ad.mp4" autoplay></video>
<!-- allowed -->
<video src="loop.mp4" autoplay muted loop playsinline></video>This is what a background video hero needs: muted, looping, playing inline, and ideally paused when the reader prefers reduced motion.
Example: a podcast episode
<article>
<h2>Episode 12: The last press operator</h2>
<audio controls preload="metadata">
<source src="/audio/ep12.opus" type="audio/ogg; codecs=opus">
<source src="/audio/ep12.mp3" type="audio/mpeg">
<p><a href="/audio/ep12.mp3">Download episode 12 (MP3, 24 MB)</a></p>
</audio>
<p><a href="/audio/ep12-transcript">Read the full transcript</a></p>
</article>The transcript link is the accessible equivalent of captions for audio, and it is also indexable, which means the episode becomes searchable content rather than an opaque file.
Important rules
- Without
controlsand without a script, the media cannot be started at all. - Autoplay with sound is blocked. Do not design around it.
preload="auto"can pull down megabytes before anyone presses play.metadatais the sensible default.- Captions must be served from the same origin, or with the correct cross origin headers.
- Video files should be hosted where bandwidth is cheap. Self hosting a large video on shared hosting is expensive.
- The
videoelement needswidthandheightfor the same layout shift reason as images.
Common mistakes
- Forgetting
controlsand shipping a player nobody can start. - Expecting
autoplayto work with sound. - Shipping video with no captions and no transcript.
- Providing one format and assuming every browser can play it.
- Using
preload="auto"on a page with several videos, and burning a reader on a metered connection. - Putting
srcon the element as well as usingsourcechildren. - Using video as a decorative background with no way to pause it.
Best practices
- Always supply captions for video and a transcript for audio.
- Set a
posterimage so the video area is not a black rectangle. - Provide MP4 with H.264 as the widest fallback, and WebM first for smaller files.
- Keep
preload="metadata"unless you have a reason not to. - Offer a download link in the fallback content.
- Pause background video when
prefers-reduced-motionis set.
Practice
- Embed a video with two source formats, a poster image and an English caption track.
- Write a five cue WebVTT file including one non speech sound in square brackets.
- Try to autoplay a video with sound, then add
mutedand observe the difference. - Compare network usage on a page with
preload="none",metadataandauto.