Media Sources & Codecs (<source>)
The <source> element is the connective tissue between <audio>/
<video> and the variety of file formats browsers actually support. Instead
of betting on one format working everywhere, you list several — the
browser evaluates them in order and plays the first one it can decode.
How <source> Works
<source> is a self-closing (void) element used only as a child of
<audio>, <video>, or <picture>. When used inside audio/video, the
parent element must not also have its own src attribute — you use
either a single src on the parent, or one/more <source> children,
not both.
source-basic.html
<video controls width="640" height="360"> <source src="movie.webm" type="video/webm" /> <source src="movie.mp4" type="video/mp4" /> </video>
The type Attribute
type declares the file's MIME type (and optionally its codec) so the
browser can skip downloading a source it already knows it can't play,
rather than discovering that only after fetching part of the file.
Media | Common type values |
|---|---|
Video |
|
Video with codec detail |
|
Audio |
|
Audio with codec detail |
|
source-codecs.html
<audio controls> <source src="track.opus" type="audio/ogg; codecs=opus" /> <source src="track.aac" type="audio/aac" /> <source src="track.mp3" type="audio/mpeg" /> </audio>
Order Matters
Browsers pick the first <source> whose type they can play — they
don't necessarily pick the "best" one by any other measure. Put your most
efficient/preferred format first, with broadly-compatible fallbacks after.
source-order.html
<video controls> <!-- Smaller file size, great Chrome/Firefox/Edge support --> <source src="clip.webm" type="video/webm" /> <!-- Larger but nearly universal, including older Safari --> <source src="clip.mp4" type="video/mp4" /> </video>
The media Attribute — Responsive Video Switching
<source> also accepts a media attribute with a CSS media query,
letting the browser choose between sources based on viewport size — a
"different clip per screen size" pattern, similar in spirit to what{' '}
<picture> does for images.
source-media.html
<video controls> <source src="hero-vertical.mp4" media="(max-width: 600px)" type="video/mp4" /> <source src="hero-widescreen.mp4" type="video/mp4" /> </video>
<source> Inside <picture> — a Quick Contrast
The same element name is reused inside <picture> for responsive images,
but the attributes differ slightly — srcset and sizes there instead of
src. It's worth keeping the two usages mentally separate even though the
tag looks identical.
source-in-picture.html
<picture> <source srcset="hero-mobile.webp" media="(max-width: 600px)" type="image/webp" /> <source srcset="hero-desktop.webp" type="image/webp" /> <img src="hero-desktop.jpg" alt="Team collaborating around a table" /> </picture>
Full Example: Video with Multiple Formats and Sizes
source-full-example.html
<video controls poster="demo-poster.jpg" width="960" height="540">
<source
src="demo-mobile.webm"
media="(max-width: 600px)"
type="video/webm"
/>
<source src="demo.webm" type="video/webm" />
<source src="demo.mp4" type="video/mp4" />
Your browser doesn't support this video format.
<a href="demo.mp4">Download the MP4</a> instead.
</video><source>is self-closing — no closing tag, no children (other than fallback content which lives on the parent, not on the<source>itself).Only used as a direct child of
<audio>,<video>, or<picture>— never standalone.The
typeattribute is optional but recommended; without it, the browser must download part of the file to guess whether it can play it.A missing/broken
<source>is skipped silently — the browser just moves to the next one.
type value with a typo (e.g. video/mp5) causes the browser to skip that source entirely, as if it weren't supported — a subtle bug that only shows up as "the video won't play" with no error message. Double-check MIME types against a reference like the MDN media types list.<source> per format, in preference order, each with an accurate type. Add a media query when different screen sizes should load different files, and always end with a text/link fallback for the rare unsupported browser.