Responsive Images
A visitor on a ₹9,000 phone with a slow connection and a visitor on a large laptop screen should not download the same image. The phone needs a smaller file that loads quickly; the laptop needs a bigger, sharper one. Responsive images are the HTML features that let each device get a suitable image.
This lesson builds on HTML Images. You will learn to make images shrink to fit, to offer several sizes of one image with srcset and sizes, and to use <picture> to change the crop or the file format.
Step 1: let images shrink with CSS
By default an image is shown at its real size. An 800-pixel-wide image on a 360-pixel phone screen spills off the side and forces sideways scrolling. One CSS rule fixes this for every image on your site:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Flexible image</title>
<style>
img { max-width: 100%; height: auto; }
.card { width: 300px; border: 1px solid #ccc; padding: 8px; }
</style>
</head>
<body>
<div class="card">
<img src="https://course.ethicscomputer.in/assets/samples/landscape.svg" alt="Hills and a river at sunrise" width="800" height="500">
<p>The image is 800 pixels wide, but it fits this 300-pixel card.</p>
</div>
</body>
</html>max-width: 100% stops the image from growing wider than its container, and height: auto keeps its shape. Because the width and height attributes are still there, the browser still reserves the right space while loading.
This makes the image look right on a phone, but the phone still downloads the full 800-pixel file. The next step fixes that.
Step 2: offer several sizes with srcset and sizes
The srcset attribute lists several files of the same picture at different widths. The sizes attribute tells the browser how wide the image will be shown on the page. The browser then picks the smallest file that will still look sharp.
<img
src="https://course.ethicscomputer.in/assets/samples/landscape.svg"
srcset="https://course.ethicscomputer.in/assets/samples/landscape-400.svg 400w,
https://course.ethicscomputer.in/assets/samples/landscape.svg 800w"
sizes="(max-width: 600px) 100vw, 50vw"
alt="Hills and a river at sunrise"
width="800" height="500">Read it like this:
srcset: "There is a 400-pixel-wide file and an 800-pixel-wide file." Thewafter each number is a width descriptor: the real width of that file in pixels.sizes: "On screens up to 600 pixels wide, the image fills the whole viewport width (100vw). On bigger screens, it fills half (50vw)." The browser uses the first condition that matches.src: the fallback file for very old browsers.
The browser also considers the pixel density of the screen. Many phones pack two or three device pixels into each CSS pixel to make text crisp. A 360-pixel-wide phone with a density of 3 needs about 1,080 real pixels to look sharp, so it may choose the larger file even though the screen is small. That is the browser doing its job; you only describe the options.
This example shows which file your browser picked. Try it on a phone and on a laptop:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>srcset and sizes</title>
<style>
img { max-width: 100%; height: auto; }
</style>
</head>
<body>
<img id="photo"
src="https://course.ethicscomputer.in/assets/samples/landscape.svg"
srcset="https://course.ethicscomputer.in/assets/samples/landscape-400.svg 400w, https://course.ethicscomputer.in/assets/samples/landscape.svg 800w"
sizes="(max-width: 600px) 100vw, 50vw"
alt="Hills and a river at sunrise"
width="800" height="500">
<p id="report">Loading...</p>
<script>
const photo = document.querySelector("#photo");
const report = document.querySelector("#report");
function showFile() {
report.textContent = `Your browser chose: ${photo.currentSrc.split("/").pop()}`;
}
if (photo.complete) {
showFile();
} else {
photo.addEventListener("load", showFile);
}
</script>
</body>
</html>currentSrc holds the address of the file the browser actually chose. Note that once a browser has the larger file, it may keep using it when the window gets narrower, because it already has a sharp image.
Fixed-size images and x descriptors
Some images are always shown at the same size, such as a logo in the header. For these, you only care about pixel density. Use x descriptors instead of w, and leave out sizes:
<img
src="https://course.ethicscomputer.in/assets/samples/landscape-400.svg"
srcset="https://course.ethicscomputer.in/assets/samples/landscape-400.svg 1x, https://course.ethicscomputer.in/assets/samples/landscape.svg 2x"
alt="Hills and a river at sunrise"
width="400" height="250">Here the image is always 400 CSS pixels wide. Normal screens get the 400-pixel file (1x) and high-density screens get the 800-pixel file (2x).
Step 3: change the crop with picture
Sometimes a smaller version of the same image is not enough. A wide landscape photo becomes a thin strip on a phone, and the important part is too small to see. A taller crop would work better. Choosing a different crop for different screens is called art direction, and it needs the <picture> element.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Art direction</title>
<style>
img { max-width: 100%; height: auto; }
</style>
</head>
<body>
<h1>Visit Jodhpur</h1>
<picture>
<source media="(max-width: 500px)" srcset="https://course.ethicscomputer.in/assets/samples/portrait.svg" width="400" height="600">
<img src="https://course.ethicscomputer.in/assets/samples/landscape.svg" alt="Jodhpur at sunrise, with the old clock tower and the hills around the city" width="800" height="500">
</picture>
<p>Make the preview narrower than 500 pixels to see the tall version.</p>
</body>
</html>How <picture> works:
- It contains zero or more
<source>elements and one<img>at the end. The<img>is required: it is the element that is actually shown, and it holds thealttext. - The browser checks the
<source>elements in order and uses the first one whosemediacondition matches. If none match, it uses the<img>. - Each
<source>can have its ownwidthandheight, because each crop has its own shape.
Unlike srcset alone, a media condition is a rule, not a hint. The browser must follow it, so the image changes when you resize the window.
Offering modern formats
<picture> is also how you offer newer, smaller formats such as AVIF and WebP while keeping a safe fallback. The type attribute tells the browser the format, and it skips any it cannot display without downloading them:
<picture>
<source type="image/avif" srcset="images/town-hall.avif">
<source type="image/webp" srcset="images/town-hall.webp">
<img src="images/town-hall.jpg" alt="The old town hall in Lucknow at sunset" width="1200" height="800">
</picture>All current browsers can show AVIF and WebP, but this pattern still matters for older devices, and it costs nothing.
Which tool to use
| Situation | Use |
|---|---|
| Every image, always | CSS max-width: 100% and height: auto |
| Same picture, shown at different widths | srcset with w descriptors and sizes |
| Same picture, always the same size | srcset with x descriptors |
| Different crop on small screens | <picture> with <source media> |
| Newer formats with a fallback | <picture> with <source type> |
Common mistakes
- Using
wdescriptors withoutsizes. The browser then assumes the image fills the full viewport width and often downloads a bigger file than needed. - Putting
alton<source>. Only the<img>hasalt, and it is used whichever file is chosen. - Forgetting the
<img>inside<picture>. Without it, nothing is shown. - Putting the general
<source>first. The first match wins, so list the most specific conditions first. - Listing a file with the wrong width. The number before
wmust be the file's real pixel width.
Key points
- Start with CSS
max-width: 100%andheight: autoso images fit any container. srcsetwithwdescriptors lists sizes of one picture;sizessays how wide it will be shown.- The browser picks a file based on display width and pixel density; you only describe the options.
- Use
xdescriptors for images that are always the same size. <picture>with<source media>changes the crop;<source type>offers AVIF and WebP with a fallback.- The
<img>inside<picture>is required and carries thealttext.
Exercise
Write the HTML for a hero image on a travel page. On screens up to 500 pixels wide, show {{samples}}/portrait.svg (400 by 600). On wider screens, show the landscape image, offering both {{samples}}/landscape-400.svg (400 pixels wide) and {{samples}}/landscape.svg (800 pixels wide), and tell the browser the image fills the full viewport width. Write good alt text and set the sizes.
Show solution
<picture>
<source media="(max-width: 500px)" srcset="https://course.ethicscomputer.in/assets/samples/portrait.svg" width="400" height="600">
<img
src="https://course.ethicscomputer.in/assets/samples/landscape.svg"
srcset="https://course.ethicscomputer.in/assets/samples/landscape-400.svg 400w, https://course.ethicscomputer.in/assets/samples/landscape.svg 800w"
sizes="100vw"
alt="Jodhpur at sunrise, with the old clock tower and the hills around the city"
width="800" height="500">
</picture>The <source> handles the narrow-screen crop. On wider screens the <img> itself uses srcset and sizes, so the browser can still choose between the two landscape files. The alt text sits on the <img>.
Quick Quiz
1. What does 800w mean in a srcset?
A w descriptor gives the real pixel width of the file so the browser can choose.
2. Which element must always be inside <picture>?
The <img> is what is actually shown and it carries the alt text.
3. You want a taller crop of a photo on phones. What do you use?
Changing the crop is art direction, which needs <picture> and a media condition.
4. Why might a small phone download the larger image from a srcset?
The browser multiplies the display width by the screen's pixel density when choosing a file.
Learn HTML with a mentor
Free lessons get you started. Our Full Stack Web Development training adds real projects and code reviews from working developers.
- Project-based learning
- Mentor code reviews
- Free counselling call
