The problem of images on different screens
The same photo has to look good on a 360 px phone and on a 2560 px monitor. Always serving the giant version makes the phone download megabytes it doesn't need; serving the small one looks blurry as a faded memory on the monitor. You want the best of both worlds, and that is exactly what responsive images give you.
srcset and sizes: the browser picks the file
With srcset you offer several versions of the same image at different
resolutions, and the browser chooses the most suitable one based on the screen and the available
width.
<img
src="photo-800.jpg"
srcset="photo-400.jpg 400w, photo-800.jpg 800w, photo-1600.jpg 1600w"
sizes="(max-width: 600px) 100vw, 50vw"
alt="Sunset over the sea"
/>
srcset: list offile realWidth w. The400wmeans "this file is 400 pixels wide".sizes: tells the browser what width the image will take in the layout based on the viewport. Here: on a narrow screen it takes up 100% of the width; otherwise, 50%.src: stays as a fallback for old browsers.
With both pieces of data (available widths + display width), the browser does the math and downloads exactly the right file. You hand over the options; it picks for you.
<picture>: change the image, not just its size
srcset works when it is the same image at different scales. When you want to
serve different images (different crops, another format, dark mode)
you use <picture> with several <source>:
<picture>
<source srcset="banner.avif" type="image/avif" />
<source srcset="banner.webp" type="image/webp" />
<img src="banner.jpg" alt="Campaign banner" />
</picture>
The browser evaluates the <source> elements in order and keeps the first one it supports. The
final <img> isn't optional: it is required, it is the fallback, and it is the one
that carries the alt. Drop it and you're left without a safety net.
Remember:
<source>also acceptsmedia(media="(min-width: 800px)") to choose based on screen size, ideal for art direction (a wide crop on desktop and a square one on mobile).
Audio
<audio> plays sound. The controls attribute shows the
playback buttons. Inside it you can offer several formats with <source>:
<audio controls>
<source src="podcast.mp3" type="audio/mpeg" />
<source src="podcast.ogg" type="audio/ogg" />
Your browser does not support audio.
</audio>
The loose text at the end is shown only if the browser does not understand
<audio>.
Video
<video> works the same way. Useful attributes: controls (control bar),
width/height, poster (preview image) and muted/autoplay/loop.
<video controls width="640" poster="cover.jpg">
<source src="clip.mp4" type="video/mp4" />
<source src="clip.webm" type="video/webm" />
Your browser does not support video.
</video>
Good practice: use
autoplayonly together withmuted(browsers block autoplay with sound, and rightly so) and always offercontrolsso the person can pause.
⚠️ Classic trap: forgetting the
alton your images. Withoutalt, a screen reader user just hears "image" and never learns what it shows. Thealtisn't decoration: it's the picture told in words.