Responsive images ensure users download only the image size appropriate for their device, saving bandwidth and improving load times. Despite being a W3C standard since 2014, many sites still serve one-size-fits-all images.
The Problem with Fixed Images
Serving a single 2000px image to all devices means mobile users download 4x more data than necessary, while users on 4K displays see blurry, upscaled images.
Responsive images solve this by providing multiple versions of each image and letting the browser choose the optimal one.
srcset: Resolution Switching
The srcset attribute lets you specify multiple image sources with width descriptors:
<img src="image-800.jpg"
srcset="image-400.jpg 400w,
image-800.jpg 800w,
image-1200.jpg 1200w,
image-1600.jpg 1600w"
alt="Description">
The 'w' descriptor tells the browser each image's width in pixels. The browser selects the smallest image that's still larger than the display area.
sizes: Telling the Browser Display Dimensions
The sizes attribute specifies how wide the image will be displayed at different viewport widths:
<img srcset="small.jpg 400w, medium.jpg 800w, large.jpg 1200w"
sizes="(max-width: 600px) 400px,
(max-width: 900px) 800px,
1200px"
src="medium.jpg"
alt="Description">
This tells the browser: "On screens 600px or narrower, the image displays at 400px. On screens 600-900px, it displays at 800px. Otherwise, 1200px."
The picture Element: Art Direction
Sometimes you need different images at different sizes (not just scaled versions). Use picture for art direction:
<picture>
<source media="(max-width: 600px)"
srcset="mobile-crop.jpg">
<source media="(max-width: 1200px)"
srcset="tablet-crop.jpg">
<img src="desktop.jpg" alt="Description">
</picture>
This serves completely different images (different crops or compositions) based on viewport size.
Format Switching with picture
Use picture to serve modern formats with fallbacks:
<picture>
<source srcset="image.avif" type="image/avif">
<source srcset="image.webp" type="image/webp">
<img src="image.jpg" alt="Description">
</picture>
Browsers that support AVIF get the smallest file. Others fall back through WebP to JPEG.
Combining Techniques
You can combine srcset, sizes, and format switching:
<picture>
<source type="image/webp"
srcset="small.webp 400w, medium.webp 800w"
sizes="(max-width: 600px) 400px, 800px">
<img src="medium.jpg"
srcset="small.jpg 400w, medium.jpg 800w"
sizes="(max-width: 600px) 400px, 800px"
alt="Description">
</picture>
Pixel Density Descriptors
For fixed-size images (logos, icons), use pixel density descriptors:
<img src="logo.png"
srcset="logo.png 1x,
logo@2x.png 2x,
logo@3x.png 3x"
alt="Logo">
The browser selects based on device pixel ratio. Retina displays get 2x or 3x versions.
Generating Responsive Images
Creating multiple versions of each image manually is tedious. Use build tools or services:
Sharp (Node.js):
const sharp = require('sharp');
const sizes = [400, 800, 1200, 1600];
sizes.forEach(width => {
sharp('original.jpg')
.resize(width)
.toFile(`image-${width}.jpg`);
});
Cloud services like Cloudinary or Imgix: Automatically generate responsive images on-the-fly.
Calculating Optimal Sizes
How many versions should you create? A good rule of thumb:
- Mobile: 400-600px
- Tablet: 800-1000px
- Desktop: 1200-1600px
- Large desktop: 2000-2400px
Four versions cover most use cases without excessive complexity.
Testing Responsive Images
Use Chrome DevTools Network tab to verify the correct image is loaded:
- Open DevTools and resize the viewport
- Reload the page
- Check which image file was downloaded
The file should match the viewport size, not always the largest version.
Common Mistakes
Not including src: Always provide a fallback src for older browsers.
Wrong sizes values: Sizes should match actual display dimensions, not viewport width.
Too many versions: 4-5 versions is sufficient. More adds complexity with diminishing returns.
Performance Impact
Properly implemented responsive images typically reduce image payload by 40-60% for mobile users and 20-30% for desktop users.
This translates to faster load times, lower bounce rates, and better SEO rankings.