HTMLMedia Sources & Codecs (<source>)

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

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/mp4, video/webm, video/ogg

Video with codec detail

video/mp4; codecs="avc1.42E01E, mp4a.40.2"

Audio

audio/mpeg (MP3), audio/ogg, audio/aac, audio/wav

Audio with codec detail

audio/ogg; codecs=opus

source-codecs.html

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

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

HTML
<video controls>
  <source src="hero-vertical.mp4" media="(max-width: 600px)" type="video/mp4" />
  <source src="hero-widescreen.mp4" type="video/mp4" />
</video>
Not a substitute for adaptive streaming
This technique picks one fixed file per condition at load time — it is not the same as adaptive bitrate streaming (HLS/DASH), which switches quality dynamically as bandwidth changes during playback. For serious video delivery at scale, a streaming protocol plus a dedicated player library is the more robust choice.
<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

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

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 type attribute 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.

Test your type strings
A 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.
Quick recap
Use one <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.