ADVANCED 12 MIN READ

Responsive Images Guide

Learn how to implement responsive images using srcset, sizes, and picture elements for optimal performance across all devices.

Last updated: January 11, 2025

What are Responsive Images?

Responsive images are images that adapt to different screen sizes, resolutions, and device capabilities. They ensure users download appropriately sized images rather than oversized files that waste bandwidth and slow page load times.

The goal is simple: serve the right image to the right device at the right time. A mobile phone doesn't need a 4K desktop wallpaper, and a retina display MacBook Pro shouldn't receive a low-resolution thumbnail.

Modern HTML provides three powerful attributes and elements for responsive images:

  • srcset - Specifies multiple image sources at different resolutions
  • sizes - Tells the browser how much space the image will occupy
  • <picture> - Provides complete control over which image displays in different scenarios

The srcset Attribute

The srcset attribute lets you define multiple versions of an image, and the browser automatically selects the most appropriate one based on the device's screen density and viewport size.

Resolution Switching with Width Descriptors

The most common use case involves providing the same image at different resolutions:

<img src="image-800.jpg"
     srcset="image-400.jpg 400w,
             image-800.jpg 800w,
             image-1200.jpg 1200w,
             image-1600.jpg 1600w"
     sizes="(max-width: 600px) 100vw,
            (max-width: 1200px) 50vw,
            800px"
     alt="Description">

The w descriptor tells the browser the actual width of each image file in pixels. The browser then uses this information along with the sizes attribute to select the optimal image.

Pixel Density Descriptors

For fixed-size images like logos or icons, you can use pixel density descriptors (x):

<img src="logo.png"
     srcset="logo.png 1x,
             logo-2x.png 2x,
             logo-3x.png 3x"
     alt="Company Logo">

This approach is perfect when the image always displays at the same size regardless of viewport width, but you want high-DPI screens to receive crisper versions.

The sizes Attribute

The sizes attribute works together with srcset to tell the browser how much space the image will occupy in the layout. This is crucial because the browser needs this information before downloading any images.

Syntax: A comma-separated list of media conditions and slot widths.

sizes="(max-width: 600px) 100vw,
       (max-width: 900px) 50vw,
       33.3vw"

This tells the browser:

  • On screens 600px or narrower, the image takes up 100% of viewport width
  • On screens 601-900px wide, the image takes up 50% of viewport width
  • On larger screens, the image takes up 33.3% of viewport width

Important: The browser evaluates these conditions in order and uses the first one that matches. Always put more specific conditions first.

Common sizes Patterns

Full-width image:

sizes="100vw"

Sidebar layout:

sizes="(min-width: 1200px) 800px,
       (min-width: 768px) 66vw,
       100vw"

Grid layout:

sizes="(min-width: 1024px) 25vw,
       (min-width: 768px) 33vw,
       (min-width: 480px) 50vw,
       100vw"

The Picture Element

The <picture> element provides the ultimate control over responsive images. Unlike srcset which gives the browser decision-making power, <picture> lets you dictate exactly which image loads under specific conditions.

<picture>
  <source media="(min-width: 1200px)" srcset="large.jpg">
  <source media="(min-width: 768px)" srcset="medium.jpg">
  <source media="(min-width: 480px)" srcset="small.jpg">
  <img src="fallback.jpg" alt="Description">
</picture>

The browser evaluates <source> elements in order and uses the first one that matches. The <img> element is required and serves as the fallback for older browsers.

Modern Format Support

Use <picture> to serve modern formats like WebP or AVIF with fallbacks:

<picture>
  <source type="image/avif" srcset="image.avif">
  <source type="image/webp" srcset="image.webp">
  <img src="image.jpg" alt="Description">
</picture>

Browsers that support AVIF will use that version, WebP-compatible browsers get the WebP version, and everyone else gets JPEG. This can reduce file sizes by 50-80% for modern browsers.

Art Direction

Art direction means serving completely different images (not just different sizes) based on the viewing context. This is perfect when the composition needs to change for different screen sizes.

For example, a wide landscape photo might work on desktop, but on mobile you want a cropped portrait version that focuses on the subject:

<picture>
  <source media="(min-width: 768px)" srcset="landscape-wide.jpg">
  <source media="(min-width: 480px)" srcset="landscape-narrow.jpg">
  <img src="portrait.jpg" alt="Description">
</picture>

Common art direction scenarios:

  • Crop focus: Wide shot on desktop, tight crop on mobile
  • Orientation: Landscape on desktop, portrait on mobile
  • Complexity: Detailed image on large screens, simplified version on small screens
  • Text readability: Larger text overlays on mobile versions

Resolution Switching vs Art Direction

Understanding when to use each technique is crucial:

Use Resolution Switching When:

  • The image composition works at all sizes
  • You're just scaling the same image up or down
  • The aspect ratio remains consistent
  • The subject is clear at any size

Tool: srcset with width descriptors and sizes

Use Art Direction When:

  • The composition needs to change
  • Different crops work better at different sizes
  • You're changing aspect ratios
  • Small details get lost on mobile
  • You need to serve different formats

Tool: <picture> element

Browser Support and Compatibility

Responsive image techniques have excellent browser support:

  • srcset and sizes: Supported in all modern browsers since 2015 (Chrome 38+, Firefox 38+, Safari 9+, Edge 13+)
  • <picture> element: Supported in all modern browsers since 2015
  • AVIF format: Chrome 85+, Firefox 93+, Safari 16+ (limited support)
  • WebP format: Universal support in modern browsers

The beauty of responsive images is built-in fallback support. Older browsers that don't understand srcset simply ignore it and use the src attribute. The <img> inside <picture> serves as a universal fallback.

Implementation Examples

Example 1: Blog Post Hero Image

<img src="hero-800.jpg"
     srcset="hero-400.jpg 400w,
             hero-800.jpg 800w,
             hero-1200.jpg 1200w,
             hero-1600.jpg 1600w,
             hero-2400.jpg 2400w"
     sizes="100vw"
     alt="Blog post hero image">

Example 2: Product Grid

<img src="product-400.jpg"
     srcset="product-400.jpg 400w,
             product-600.jpg 600w,
             product-800.jpg 800w"
     sizes="(min-width: 1024px) 25vw,
            (min-width: 768px) 33vw,
            (min-width: 480px) 50vw,
            100vw"
     alt="Product name">

Example 3: Banner with Art Direction

<picture>
  <source media="(min-width: 1024px)"
          srcset="banner-desktop.jpg 1x,
                  banner-desktop-2x.jpg 2x">
  <source media="(min-width: 768px)"
          srcset="banner-tablet.jpg 1x,
                  banner-tablet-2x.jpg 2x">
  <img src="banner-mobile.jpg"
       srcset="banner-mobile-2x.jpg 2x"
       alt="Promotional banner">
</picture>

Performance Benefits

Implementing responsive images correctly delivers significant performance improvements:

  • Reduced Bandwidth: Mobile users download appropriately sized images, saving 60-80% of data
  • Faster Page Load: Smaller images load faster, improving Core Web Vitals scores
  • Better User Experience: Pages feel snappier, especially on slower connections
  • Lower Bounce Rates: Fast-loading images keep users engaged
  • SEO Benefits: Google rewards fast-loading, mobile-optimized sites
  • Cost Savings: Reduced CDN and bandwidth costs for high-traffic sites

Real-world example: A full-width hero image on desktop might be 2400px × 1350px (800KB). On mobile, the same image at 800px × 450px is only 120KB. That's an 85% reduction in file size.

Common Patterns and Recipes

Pattern 1: Full-Width Responsive Image

Image spans full viewport width on all devices:

<img src="image.jpg"
     srcset="image-480.jpg 480w,
             image-800.jpg 800w,
             image-1200.jpg 1200w,
             image-1600.jpg 1600w"
     sizes="100vw"
     alt="Description">

Pattern 2: Contained Content Width

Image is contained within a max-width container (e.g., 1200px):

<img src="image.jpg"
     srcset="image-480.jpg 480w,
             image-800.jpg 800w,
             image-1200.jpg 1200w"
     sizes="(min-width: 1200px) 1200px,
            100vw"
     alt="Description">

Pattern 3: Two-Column Layout

Image is half-width on desktop, full-width on mobile:

<img src="image.jpg"
     srcset="image-400.jpg 400w,
             image-800.jpg 800w,
             image-1200.jpg 1200w"
     sizes="(min-width: 768px) 50vw,
            100vw"
     alt="Description">

Pattern 4: Modern Formats with Fallback

Serve AVIF and WebP to modern browsers, JPEG to others:

<picture>
  <source type="image/avif"
          srcset="image-480.avif 480w,
                  image-800.avif 800w,
                  image-1200.avif 1200w"
          sizes="100vw">
  <source type="image/webp"
          srcset="image-480.webp 480w,
                  image-800.webp 800w,
                  image-1200.webp 1200w"
          sizes="100vw">
  <img src="image-800.jpg"
       srcset="image-480.jpg 480w,
               image-800.jpg 800w,
               image-1200.jpg 1200w"
       sizes="100vw"
       alt="Description">
</picture>

Best Practices

  • Always include src: The src attribute is required for fallback and should point to a sensible default size
  • Always include alt: Accessibility requires descriptive alt text for all images
  • Match aspect ratios: All srcset images should have the same aspect ratio to prevent layout shift
  • Use width descriptors: Use w descriptors (not x) for most responsive images
  • Provide enough options: Include 4-6 image sizes covering common breakpoints (400px, 800px, 1200px, 1600px, 2400px)
  • Optimize all variants: Compress every image size appropriately for web
  • Test on real devices: Verify which images load on different devices using browser dev tools
  • Set width and height: Include width and height attributes to prevent layout shift
  • Use lazy loading: Add loading="lazy" for below-the-fold images
  • Consider format support: Use WebP at minimum, AVIF for cutting-edge optimization
  • Monitor file sizes: Keep mobile images under 150KB, desktop under 500KB when possible
  • Use automation: Implement build tools or CDN features to generate responsive image sets automatically

Common Mistakes to Avoid

  • Incorrect sizes values: The sizes attribute must accurately reflect the image's display size, not the viewport size
  • Forgetting pixel density: On 2x displays, the browser needs 2× the CSS pixels in actual image pixels
  • Too few variants: Providing only 2-3 image sizes doesn't give enough granularity
  • Inconsistent aspect ratios: Different crops in srcset cause layout shift when images load
  • Missing fallback: Always include a src attribute even when using srcset
  • Over-optimizing: Excessively compressed images look poor on large, high-quality displays
  • Ignoring WebP/AVIF: Modern formats offer 30-50% smaller files with equal quality
  • Not testing: Check your implementation across multiple devices and connection speeds

Testing Your Implementation

To verify your responsive images are working correctly:

  1. Chrome DevTools: Open Network tab, filter by images, resize viewport to see which images load
  2. Device Emulation: Use Chrome DevTools device emulation to test different screen sizes and pixel densities
  3. Throttling: Enable network throttling to simulate slow connections and verify appropriate images load
  4. Real Device Testing: Test on actual mobile devices and tablets
  5. Lighthouse: Run Lighthouse audits to check for properly sized images
  6. PageSpeed Insights: Google's tool will flag images that aren't optimized

Tools and Resources

  • Responsive Image Breakpoints Generator: Cloudinary's free tool analyzes images and suggests optimal breakpoints
  • Squoosh: Web-based image compression tool supporting WebP and AVIF
  • Sharp: Node.js library for automated responsive image generation
  • Cloudinary / Imgix: Image CDNs that generate responsive images automatically
  • Picture element polyfill: For older browser support (rarely needed now)

Related Resources