Media Element
HTML5
The source element specifies multiple media resources for <picture>, <audio>, and <video> elements. It enables format fallbacks, responsive images, and cross-browser compatibility by letting browsers choose the most appropriate resource.
Interactive code playground requires JavaScript. Here's the code:
<picture>
<source srcset="image.avif" type="image/avif">
<source srcset="image.webp" type="image/webp">
<img src="image.jpg" alt="Image with format fallbacks">
</picture>
<audio controls>
<source src="audio.opus" type="audio/opus">
<source src="audio.mp3" type="audio/mpeg">
Your browser doesn't support audio.
</audio>
< source src = " media.mp4 " type = " video/mp4 " >
< source srcset = " image.webp " type = " image/webp " >
The <source> element is void (self-closing) and must be a child of <picture>, <audio>, or <video>.
When used in <picture>, source uses srcset instead of src:
Attribute Description Example srcsetImage URL(s) and descriptors srcset="image.webp" or srcset="img-400.jpg 400w, img-800.jpg 800w"typeMIME type of the image type="image/webp", type="image/avif"mediaMedia query for art direction media="(min-width: 800px)"sizesImage sizes for different viewports sizes="(max-width: 600px) 100vw, 50vw"widthIntrinsic width (new) width="800"heightIntrinsic height (new) height="600"
When used in <audio> or <video>, source uses src:
Attribute Description Example srcURL of the media file src="video.mp4"typeMIME type of the media type="video/mp4", type="audio/mpeg"
Serve modern image formats with automatic fallbacks:
Interactive code playground requires JavaScript. Here's the code:
<picture>
<!-- Best compression: AVIF -->
<source srcset="https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=600&fm=avif&q=80"
type="image/avif">
<!-- Good compression: WebP -->
<source srcset="https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=600&fm=webp&q=80"
type="image/webp">
<!-- Universal fallback: JPEG -->
<img src="https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=600&fm=jpg&q=80"
alt="Mountain landscape"
width="600"
height="400"
style="width: 100%; height: auto;">
</picture>
<p>Browser automatically picks best supported format</p>
Different images for different viewport sizes:
Interactive code playground requires JavaScript. Here's the code:
<picture>
<!-- Desktop: wide landscape -->
<source media="(min-width: 1000px)"
srcset="https://picsum.photos/1200/400">
<!-- Tablet: medium -->
<source media="(min-width: 600px)"
srcset="https://picsum.photos/800/500">
<!-- Mobile: square crop -->
<img src="https://picsum.photos/600/600"
alt="Responsive art direction"
style="width: 100%; height: auto;">
</picture>
Provide multiple resolutions for different pixel densities:
Interactive code playground requires JavaScript. Here's the code:
<picture>
<source media="(min-width: 800px)"
srcset="https://picsum.photos/800/400 1x,
https://picsum.photos/1600/800 2x,
https://picsum.photos/2400/1200 3x">
<img src="https://picsum.photos/400/300"
srcset="https://picsum.photos/400/300 1x,
https://picsum.photos/800/600 2x"
alt="High DPI images"
style="width: 100%; height: auto;">
</picture>
Let the browser choose based on viewport width:
Interactive code playground requires JavaScript. Here's the code:
<picture>
<source srcset="https://picsum.photos/400/300 400w,
https://picsum.photos/800/600 800w,
https://picsum.photos/1200/900 1200w,
https://picsum.photos/1600/1200 1600w"
sizes="(max-width: 600px) 100vw,
(max-width: 1000px) 80vw,
1200px">
<img src="https://picsum.photos/800/600"
alt="Width descriptor example"
style="width: 100%; max-width: 1200px; height: auto;">
</picture>
Use both media queries and format fallbacks:
Interactive code playground requires JavaScript. Here's the code:
<picture>
<!-- Desktop AVIF -->
<source media="(min-width: 800px)"
srcset="https://images.unsplash.com/photo-1469474968028-56623f02e42e?w=1200&h=400&fit=crop&fm=avif&q=80"
type="image/avif">
<!-- Desktop WebP -->
<source media="(min-width: 800px)"
srcset="https://images.unsplash.com/photo-1469474968028-56623f02e42e?w=1200&h=400&fit=crop&fm=webp&q=80"
type="image/webp">
<!-- Mobile WebP -->
<source srcset="https://images.unsplash.com/photo-1469474968028-56623f02e42e?w=600&h=600&fit=crop&fm=webp&q=80"
type="image/webp">
<!-- Universal fallback -->
<img src="https://images.unsplash.com/photo-1469474968028-56623f02e42e?w=600&h=600&fit=crop&fm=jpg&q=80"
alt="Complex source configuration"
style="width: 100%; height: auto;">
</picture>
Provide multiple video formats for browser compatibility:
Interactive code playground requires JavaScript. Here's the code:
<video controls width="640" height="360">
<!-- Modern: AV1 (best compression) -->
<source src="https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerBlazes.mp4"
type="video/mp4; codecs=av01.0.05M.08">
<!-- Modern: H.265/HEVC -->
<source src="https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerBlazes.mp4"
type="video/mp4; codecs=hvc1">
<!-- Standard: H.264 -->
<source src="https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerBlazes.mp4"
type="video/mp4">
<!-- Fallback: WebM -->
<source src="https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerBlazes.mp4"
type="video/webm">
Your browser doesn't support HTML5 video.
</video>
Specify exact codec information for better browser selection:
Interactive code playground requires JavaScript. Here's the code:
<video controls width="640" height="360">
<!-- MP4 with H.264 video and AAC audio -->
<source src="https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4"
type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"'>
<!-- WebM with VP9 video and Opus audio -->
<source src="https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4"
type='video/webm; codecs="vp9, opus"'>
Your browser doesn't support video playback.
</video>
Provide multiple audio formats:
Interactive code playground requires JavaScript. Here's the code:
<audio controls>
<!-- Modern: Opus (best quality/compression) -->
<source src="https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3"
type="audio/opus">
<!-- Good: Ogg Vorbis -->
<source src="https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3"
type="audio/ogg; codecs=vorbis">
<!-- Universal: MP3 -->
<source src="https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3"
type="audio/mpeg">
Your browser doesn't support audio playback.
</audio>
Interactive code playground requires JavaScript. Here's the code:
<audio controls>
<!-- AAC in MP4 container -->
<source src="https://www.soundhelix.com/examples/mp3/SoundHelix-Song-2.mp3"
type='audio/mp4; codecs="mp4a.40.2"'>
<!-- MP3 -->
<source src="https://www.soundhelix.com/examples/mp3/SoundHelix-Song-2.mp3"
type="audio/mpeg">
Audio not supported.
</audio>
Format MIME Type Browser Support AVIF image/avifChrome 85+, Firefox 93+, Safari 16+ WebP image/webpChrome 23+, Firefox 65+, Safari 14+ JPEG image/jpegUniversal PNG image/pngUniversal GIF image/gifUniversal SVG image/svg+xmlUniversal (modern browsers)
Format MIME Type Codecs Support MP4 (H.264) video/mp4avc1.42E01E, mp4a.40.2Universal WebM (VP9) video/webmvp9, opusChrome, Firefox, Edge WebM (VP8) video/webmvp8, vorbisChrome, Firefox, Edge Ogg (Theora) video/oggtheora, vorbisFirefox, Chrome
Format MIME Type Codecs Support MP3 audio/mpeg- Universal AAC audio/mp4mp4a.40.2Universal Opus audio/opus- Chrome, Firefox, Edge Ogg Vorbis audio/oggvorbisFirefox, Chrome WAV audio/wav- Universal
< source media = " (min-width: 1200px) " srcset = " xlarge.jpg " >
< source media = " (min-width: 800px) " srcset = " large.jpg " >
< source media = " (min-width: 400px) " srcset = " medium.jpg " >
< img src = " small.jpg " alt = " Responsive image " >
< source media = " (orientation: landscape) " srcset = " landscape.jpg " >
< source media = " (orientation: portrait) " srcset = " portrait.jpg " >
< img src = " landscape.jpg " alt = " Orientation-aware " >
< source media = " (min-resolution: 3dppx) " srcset = " ultra-high.jpg " >
< source media = " (min-resolution: 2dppx) " srcset = " high.jpg " >
< img src = " standard.jpg " alt = " DPI-aware " >
< source media = " (prefers-color-scheme: dark) " srcset = " dark.jpg " >
< source media = " (prefers-color-scheme: light) " srcset = " light.jpg " >
< img src = " light.jpg " alt = " Theme-aware " >
Interactive code playground requires JavaScript. Here's the code:
<picture>
<!-- Large landscape screens -->
<source media="(min-width: 1000px) and (orientation: landscape)"
srcset="https://picsum.photos/1600/600">
<!-- Portrait tablets -->
<source media="(min-width: 600px) and (orientation: portrait)"
srcset="https://picsum.photos/800/1200">
<!-- Small screens -->
<img src="https://picsum.photos/400/600"
alt="Complex media query example"
style="width: 100%; height: auto;">
</picture>
The browser processes <source> elements in this order:
Check media query - If media attribute exists, must match
Check format support - If type attribute exists, must be supported
Check srcset - Evaluate srcset and pick best resolution
Use first match - Stop processing after first match
Interactive code playground requires JavaScript. Here's the code:
<picture>
<!-- 1. Try AVIF on wide screens -->
<source media="(min-width: 1000px)"
srcset="https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=1200&fm=avif&q=80"
type="image/avif">
<!-- 2. Try WebP on wide screens -->
<source media="(min-width: 1000px)"
srcset="https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=1200&fm=webp&q=80"
type="image/webp">
<!-- 3. Try AVIF on narrow screens -->
<source srcset="https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=600&fm=avif&q=80"
type="image/avif">
<!-- 4. Try WebP on narrow screens -->
<source srcset="https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=600&fm=webp&q=80"
type="image/webp">
<!-- 5. Final fallback: JPEG -->
<img src="https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=600&fm=jpg&q=80"
alt="Comprehensive fallback chain"
style="width: 100%; height: auto;">
</picture>
<!-- Order: specific to general -->
< source media = " (min-width: 1200px) " srcset = " large.avif " type = " image/avif " >
< source media = " (min-width: 1200px) " srcset = " large.webp " type = " image/webp " >
< source media = " (min-width: 800px) " srcset = " medium.avif " type = " image/avif " >
< source media = " (min-width: 800px) " srcset = " medium.webp " type = " image/webp " >
< img src = " small.jpg " alt = " Description " width = " 400 " height = " 300 " >
<!-- Modern formats first -->
< source srcset = " photo.avif " type = " image/avif " >
< source srcset = " photo.webp " type = " image/webp " >
< img src = " photo.jpg " alt = " Photo " >
<!-- Wrong: img not last -->
< img src = " photo.jpg " alt = " Photo " >
< source srcset = " photo.webp " type = " image/webp " >
<!-- Wrong: general to specific -->
< source media = " (min-width: 400px) " srcset = " small.jpg " >
< source media = " (min-width: 1200px) " srcset = " large.jpg " >
< img src = " tiny.jpg " alt = " Photo " >
<!-- Wrong: using src instead of srcset -->
< source src = " photo.webp " type = " image/webp " >
< img src = " photo.jpg " alt = " Photo " >
<!-- Best formats first -->
< source src = " video.mp4 " type = ' video/mp4; codecs="avc1.42E01E" ' >
< source src = " video.webm " type = ' video/webm; codecs="vp9" ' >
Fallback text for unsupported browsers.
< source src = " audio.opus " type = " audio/opus " >
< source src = " audio.mp3 " type = " audio/mpeg " >
<!-- Wrong: using srcset for video -->
< source srcset = " video.mp4 " type = " video/mp4 " >
< img src = " poster.jpg " alt = " Poster " >
<!-- Wrong: missing fallback text -->
< source src = " audio.mp3 " type = " audio/mpeg " >
<!-- Wrong: outdated formats first -->
< source src = " video.ogv " type = " video/ogg " >
< source src = " video.mp4 " type = " video/mp4 " >
Interactive code playground requires JavaScript. Here's the code:
<picture>
<!-- Desktop: ultra-wide -->
<source media="(min-width: 1400px)"
srcset="https://picsum.photos/2000/600">
<!-- Laptop: wide -->
<source media="(min-width: 1000px)"
srcset="https://picsum.photos/1400/500">
<!-- Tablet: medium -->
<source media="(min-width: 600px)"
srcset="https://picsum.photos/1000/600">
<!-- Mobile: square -->
<img src="https://picsum.photos/600/600"
alt="Hero image adapting to all screen sizes"
style="width: 100%; height: auto; display: block;">
</picture>
Interactive code playground requires JavaScript. Here's the code:
<picture>
<source srcset="https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=800&fm=avif&q=80"
type="image/avif">
<source srcset="https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=800&fm=webp&q=80"
type="image/webp">
<img src="https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=800&fm=jpg&q=80"
alt="Simple format fallback"
width="800"
height="600"
style="width: 100%; height: auto;">
</picture>
The <source> element itself has no accessibility attributes. All accessibility features come from the parent <img>, <audio>, or <video> element:
<!-- Alt text on img, not source -->
< source srcset = " image.webp " type = " image/webp " >
< img src = " image.jpg " alt = " Descriptive alt text " >
<!-- Captions on video, not source -->
< source src = " video.mp4 " type = " video/mp4 " >
< track kind = " captions " src = " captions.vtt " srclang = " en " label = " English " >
Feature Chrome Firefox Safari Edge <source> in <picture>38+ 38+ 9.1+ 13+ <source> in <video>3+ 3.5+ 4+ 12+ <source> in <audio>3+ 3.5+ 4+ 12+ media attribute38+ 38+ 9.1+ 13+ type attribute3+ 3.5+ 4+ 12+ srcset attribute38+ 38+ 9.1+ 13+ sizes attribute38+ 38+ 9.1+ 13+
Container for source elements providing image alternatives.
Learn more →
Displays the selected image from picture sources.
Learn more →
Video player using source for format fallbacks.
Learn more →
Audio player using source for format fallbacks.
Learn more →