HTML Responsive Images
Responsive images look sharp and load fast on every screen, from a small phone to a large monitor.
The Problem
A 2000-pixel-wide photo looks great on a laptop. On a phone it is shown at 400 pixels, but the phone still downloads the whole big file. That wastes mobile data and makes the page slow.
Responsive images fix this: the browser picks the right file for each screen.
Fit the Screen with CSS
The first step is simple. Stop an image from becoming wider than its container:
Example
<!DOCTYPE html>
<html>
<head>
<style>
img { max-width: 100%; height: auto; }
</style>
</head>
<body>
<h2>Resize the window</h2>
<img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1200' height='400'%3E%3Crect width='1200' height='400' fill='%23e34c26'/%3E%3Ctext x='600' y='220' font-size='60' text-anchor='middle' fill='white'%3E1200 x 400%3C/text%3E%3C/svg%3E" alt="A wide orange banner" width="1200" height="400">
</body>
</html>Try it Yourself »The image shrinks on small screens and never grows bigger than its real size. Keep width and height in the HTML so the browser saves the right space before the image loads.
srcset: Different Sizes of One Image
srcset lists the same picture in several widths. The w after each number is the real width of that file in pixels.
Example
<img src="shop-800.jpg"
srcset="shop-400.jpg 400w, shop-800.jpg 800w, shop-1600.jpg 1600w"
sizes="(max-width: 600px) 100vw, 50vw"
alt="Inside Ali's computer shop"
width="800" height="533">| Part | Meaning |
|---|---|
srcset | The files you have and their widths |
sizes | How wide the image will be shown: full screen width (100vw) on screens up to 600px, half the width (50vw) on larger screens |
src | The fallback for very old browsers |
The browser does the maths. A phone 400 pixels wide picks shop-400.jpg (or shop-800.jpg if it has a sharp high-density screen). A desktop picks a bigger one.
srcset for Sharp Screens
For an image that is always shown at the same size, like a logo, list files by pixel density with x:
Example
<img src="logo.png" srcset="logo.png 1x, logo@2x.png 2x" alt="Workownix logo" width="150" height="50">Phones with sharp "retina" screens take the 2x file. Others take the normal one.
The picture Element
<picture> gives you full control. It holds several <source> tags and one <img>. The browser uses the first source that matches, and the <img> is the fallback.
Use 1: Modern Formats
WebP and AVIF files are much smaller than JPEG at the same quality. Offer them first, and keep JPEG for older browsers:
Example
<picture>
<source srcset="biryani.avif" type="image/avif">
<source srcset="biryani.webp" type="image/webp">
<img src="biryani.jpg" alt="A plate of chicken biryani" width="600" height="400">
</picture>Use 2: A Different Picture for Small Screens
On a phone, a wide group photo becomes tiny. You can show a closer, cropped photo instead. This is called "art direction".
Example
<!DOCTYPE html>
<html>
<body>
<p>Make the window narrower than 600 pixels and watch the picture change.</p>
<picture>
<source media="(max-width: 600px)"
srcset="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20width='300'%20height='300'%3E%3Crect%20width='300'%20height='300'%20fill='%232a7ae2'/%3E%3Ctext%20x='150'%20y='160'%20font-size='30'%20text-anchor='middle'%20fill='white'%3EPhone%3C/text%3E%3C/svg%3E">
<img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='800' height='300'%3E%3Crect width='800' height='300' fill='%23e34c26'/%3E%3Ctext x='400' y='160' font-size='40' text-anchor='middle' fill='white'%3EDesktop%3C/text%3E%3C/svg%3E"
alt="Course banner" style="max-width:100%; height:auto;">
</picture>
</body>
</html>Try it Yourself »The alt text always goes on the <img> inside <picture>. The <source> tags never have alt.
Lazy Loading
Images far down the page do not need to load until the visitor scrolls to them. Add loading="lazy":
Example
<img src="gallery-12.jpg" alt="Students in the computer lab" loading="lazy" width="400" height="300">| Value | Behaviour |
|---|---|
eager | Load at once (the default) |
lazy | Load when the image comes near the screen |
Do not lazy-load the main image at the top of the page. It should appear as fast as possible. For that one, you can even add fetchpriority="high".
Quick Checklist
- Add
max-width: 100%; height: auto;in your CSS. - Always give
width,heightandalt. - Use
srcsetandsizesfor big photos. - Use
<picture>for WebP/AVIF or for a different crop on phones. - Use
loading="lazy"for images below the first screen.
Exercise
Exercise
Which attribute stops an image from downloading until the user scrolls near it?
