Skip to content

Responsive Images: Providing Optimal Images for Different Devices

In a coffee shop, you'll notice the same coffee comes in different cup sizes—small, medium, large. Customers can choose the portion size that suits their needs, avoiding waste or shortage. Responsive images follow a similar philosophy: provide different versions of images for different devices and screens, ensuring both display quality and avoiding bandwidth waste.

Why Do We Need Responsive Images?

In early responsive design, developers would typically use one high-resolution large image and then scale it with CSS for different sizes. This approach seems simple but has serious problems:

Suppose you have a 2400×1600 pixel, 500KB high-definition image. When users access with a mobile phone (screen width only 375px), the browser still downloads the complete 500KB image and then scales it down. This means:

  1. Wasted bandwidth: Mobile users download far more data than they actually need
  2. Slow loading: Large images significantly slow down page loading on mobile networks
  3. Battery consumption: Downloading and processing large images consumes more power

Responsive image technology allows browsers to intelligently choose the most appropriate image version—loading small images on phones and large, high-definition images on high-definition large screens—achieving "on-demand supply."

srcset Attribute: Resolution Switching

srcset is the most fundamental tool for implementing responsive images, allowing you to provide multiple image sources for browsers to choose the most appropriate one based on device characteristics.

Pixel Density-based Selection

The first use case is providing different image versions for different pixel densities:

html
<img
  src="hero-1x.jpg"
  srcset="hero-1x.jpg 1x, hero-2x.jpg 2x, hero-3x.jpg 3x"
  alt="Hero banner image"
/>

The meaning of this code is:

  • src="hero-1x.jpg": This is the fallback solution, used when browsers don't support srcset
  • hero-1x.jpg 1x: Standard screen (1x pixel density) uses this version
  • hero-2x.jpg 2x: High-definition screen (2x pixel density, like iPhone Retina) uses this version
  • hero-3x.jpg 3x: Ultra-high-definition screen (3x pixel density, like some Android flagship phones) uses this version

When users access with an iPhone 13 (2x screen), the browser will automatically select hero-2x.jpg. If they're using a regular laptop (1x screen), it will load hero-1x.jpg. This ensures each device sees clear images while avoiding unnecessary bandwidth waste.

Actual Width-based Selection

A more common scenario is providing different versions based on the actual display width of the image:

html
<img
  src="photo-800.jpg"
  srcset="
    photo-400.jpg   400w,
    photo-800.jpg   800w,
    photo-1200.jpg 1200w,
    photo-1600.jpg 1600w
  "
  alt="Beautiful landscape"
/>

Here w represents the actual width of the image (in pixels):

  • photo-400.jpg 400w: This image is 400 pixels wide
  • photo-800.jpg 800w: This image is 800 pixels wide
  • photo-1200.jpg 1200w: This image is 1200 pixels wide
  • photo-1600.jpg 1600w: This image is 1600 pixels wide

The browser makes a comprehensive decision based on viewport size, the image's display size on the page, and device pixel ratio to select the most appropriate image. For example:

  • On a 375px wide phone, it might load the 400w or 800w version
  • On a 1920px wide desktop monitor, it might load the 1600w version
  • On a 2x Retina screen iPad, it will choose a larger version to ensure clarity

sizes Attribute: Telling the Browser Display Size

When using srcset alone, browsers only know the actual widths of each image but not how much space the image will occupy on the page. The sizes attribute tells the browser the display size of the image under different viewport widths.

Basic Usage

html
<img
  src="product-800.jpg"
  srcset="product-400.jpg 400w, product-800.jpg 800w, product-1200.jpg 1200w"
  sizes="(max-width: 600px) 100vw,
         (max-width: 1200px) 50vw,
         400px"
  alt="Product showcase"
/>

The value of the sizes attribute is a series of media conditions and corresponding display widths:

  1. (max-width: 600px) 100vw: When viewport width ≤ 600px, image occupies 100% viewport width
  2. (max-width: 1200px) 50vw: When viewport width ≤ 1200px, image occupies 50% viewport width
  3. 400px: In other cases (viewport width > 1200px), image displays at 400px width

Let's look at a practical example:

Assume a user accesses with a 1440px wide, 2x pixel density MacBook Pro. According to the sizes rules, the image will display at 400px wide. Since the screen is 2x density, the browser actually needs an 800px wide image resource (400 × 2 = 800). Therefore, the browser will select product-800.jpg from the srcset.

If using a 375px wide, 3x pixel density iPhone, according to the first rule, the image will occupy 100vw, which is 375px. Since it's a 3x screen, the browser needs a 1125px wide image (375 × 3 = 1125), so it will select product-1200.jpg.

Complex Layout Example

In responsive grid layouts, the sizes attribute is particularly useful:

html
<img
  src="gallery-800.jpg"
  srcset="
    gallery-400.jpg   400w,
    gallery-800.jpg   800w,
    gallery-1200.jpg 1200w,
    gallery-1600.jpg 1600w
  "
  sizes="(max-width: 599px) 100vw,
         (max-width: 899px) 50vw,
         (max-width: 1199px) 33.33vw,
         25vw"
  alt="Gallery image"
/>

This configuration applies to responsive image galleries:

  • Mobile (< 600px): 1 column layout, each image takes 100% width
  • Tablet portrait (600-899px): 2 column layout, each image takes 50% width
  • Tablet landscape (900-1199px): 3 column layout, each image takes 33.33% width
  • Desktop (≥ 1200px): 4 column layout, each image takes 25% width

The browser will precisely calculate the required image size based on this information and select the optimal resource.

picture Element: Art Direction

Sometimes, just scaling image sizes isn't enough. On different devices, you might want to use completely different image compositions—this is "Art Direction." The <picture> element is specifically designed to solve this problem.

Art Direction Basics

html
<picture>
  <source media="(max-width: 599px)" srcset="banner-mobile.jpg" />
  <source media="(min-width: 600px)" srcset="banner-desktop.jpg" />
  <img src="banner-desktop.jpg" alt="Company banner" />
</picture>

In this example:

  • Mobile (< 600px) loads banner-mobile.jpg, possibly a portrait crop or more compact composition
  • Desktop (≥ 600px) loads banner-desktop.jpg, possibly a landscape composition with more background elements
  • The <img> tag is required, serving both as fallback and defining alt text

This is not just a size change, but a completely different image. For example, the desktop banner might show the entire team in a wide scene, while the mobile version might focus on a single person's close-up for better clarity and impact on small screens.

Combining srcset for Complete Solution

<picture> can be combined with srcset to handle both art direction and resolution switching:

html
<picture>
  <!-- Mobile: portrait composition + multiple resolutions -->
  <source
    media="(max-width: 599px)"
    srcset="hero-mobile-400.jpg 400w, hero-mobile-800.jpg 800w"
    sizes="100vw"
  />

  <!-- Tablet: square composition + multiple resolutions -->
  <source
    media="(min-width: 600px) and (max-width: 1199px)"
    srcset="hero-tablet-800.jpg 800w, hero-tablet-1200.jpg 1200w"
    sizes="100vw"
  />

  <!-- Desktop: landscape composition + multiple resolutions -->
  <source
    media="(min-width: 1200px)"
    srcset="
      hero-desktop-1200.jpg 1200w,
      hero-desktop-1600.jpg 1600w,
      hero-desktop-2400.jpg 2400w
    "
    sizes="100vw"
  />

  <!-- Fallback -->
  <img src="hero-desktop-1200.jpg" alt="Hero image" />
</picture>

The browser will check each <source>'s media condition in order and use the first matching one, then select a specific image file based on that <source>'s srcset and sizes. This achieves:

  • Different compositions for different screen sizes
  • Optimal image selection for the same composition
  • Perfect balance between display quality and performance

Modern Image Format Support

The <picture> element can also be used to provide modern image formats while maintaining backward compatibility:

html
<picture>
  <!-- Prioritize AVIF format (smallest file size) -->
  <source srcset="photo.avif" type="image/avif" />

  <!-- If AVIF not supported, try WebP -->
  <source srcset="photo.webp" type="image/webp" />

  <!-- Fallback: traditional JPEG -->
  <img src="photo.jpg" alt="Beautiful photo" />
</picture>

The browser will check in order:

  1. Does it support AVIF? If yes, use photo.avif (possibly only 50KB)
  2. Doesn't support AVIF, does it support WebP? If yes, use photo.webp (possibly 80KB)
  3. Neither supported, use traditional JPEG photo.jpg (possibly 150KB)

Modern browsers (like Chrome, Firefox) will load AVIF or WebP for smaller file sizes and faster loading. Old browsers (like IE11) will fall back to JPEG, ensuring compatibility.

Combining Formats and Resolutions

You can also combine format selection with resolution switching:

html
<picture>
  <!-- WebP format + multiple resolutions -->
  <source
    type="image/webp"
    srcset="photo-400.webp 400w, photo-800.webp 800w, photo-1200.webp 1200w"
    sizes="(max-width: 600px) 100vw, 800px"
  />

  <!-- JPEG fallback + multiple resolutions -->
  <source
    srcset="photo-400.jpg 400w, photo-800.jpg 800w, photo-1200.jpg 1200w"
    sizes="(max-width: 600px) 100vw, 800px"
  />

  <img src="photo-800.jpg" alt="Photo description" />
</picture>

Responsive Images in CSS

Although HTML provides powerful responsive image functionality, sometimes you need to handle background images in CSS. You can use media queries to achieve similar effects:

css
.hero {
  background-image: url("hero-mobile.jpg");
  background-size: cover;
  background-position: center;
}

/* Tablet */
@media (min-width: 600px) {
  .hero {
    background-image: url("hero-tablet.jpg");
  }
}

/* Desktop */
@media (min-width: 1200px) {
  .hero {
    background-image: url("hero-desktop.jpg");
  }
}

/* High-definition screen */
@media (min-width: 1200px) and (min-resolution: 2dppx) {
  .hero {
    background-image: url("hero-desktop-2x.jpg");
  }
}

A more modern approach is to use the image-set() function:

css
.hero {
  background-image: image-set(
    url("hero.jpg") 1x,
    url("hero-2x.jpg") 2x,
    url("hero.webp") 1x type("image/webp"),
    url("hero-2x.webp") 2x type("image/webp")
  );
}

The browser will automatically select the most appropriate image format and resolution version.

Practical Application Scenarios

Product List Page

In e-commerce website product lists, responsive images are crucial:

html
<!-- Product thumbnails -->
<picture>
  <source
    media="(max-width: 599px)"
    srcset="product-thumb-300.webp 1x, product-thumb-600.webp 2x"
    type="image/webp"
  />
  <source
    media="(max-width: 599px)"
    srcset="product-thumb-300.jpg 1x, product-thumb-600.jpg 2x"
  />

  <source
    srcset="product-thumb-400.webp 1x, product-thumb-800.webp 2x"
    type="image/webp"
  />
  <source srcset="product-thumb-400.jpg 1x, product-thumb-800.jpg 2x" />

  <img src="product-thumb-400.jpg" alt="Wireless headphones" />
</picture>

On mobile, load 300px wide small images (or 2x screen uses 600px), while on desktop load 400px images, prioritizing WebP format to save bandwidth.

Article Header Image

Blog article header images often need art direction:

html
<picture>
  <!-- Mobile: 1:1 crop -->
  <source
    media="(max-width: 767px)"
    srcset="article-hero-square-400.jpg 400w, article-hero-square-800.jpg 800w"
    sizes="100vw"
  />

  <!-- Desktop: 16:9 crop -->
  <source
    media="(min-width: 768px)"
    srcset="
      article-hero-wide-800.jpg   800w,
      article-hero-wide-1200.jpg 1200w,
      article-hero-wide-1600.jpg 1600w
    "
    sizes="100vw"
  />

  <img
    src="article-hero-wide-1200.jpg"
    alt="Understanding responsive images"
    loading="lazy"
  />
</picture>

Note the addition of loading="lazy", which is the browser's native lazy loading feature for further performance optimization.

Performance Optimization Tips

1. Lazy Loading

For images outside the first screen, use lazy loading to significantly improve initial loading speed:

html
<img
  src="photo.jpg"
  srcset="photo-400.jpg 400w, photo-800.jpg 800w"
  sizes="(max-width: 600px) 100vw, 50vw"
  loading="lazy"
  alt="Gallery photo"
/>

The browser will delay loading this image until the user scrolls close to its position.

2. Preload Critical Images

For critical first-screen images (like hero banners), you can use preload to prompt the browser to load them early:

html
<link
  rel="preload"
  as="image"
  href="hero-1200.jpg"
  imagesrcset="hero-400.jpg 400w, hero-800.jpg 800w, hero-1200.jpg 1200w"
  imagesizes="100vw"
/>

This will make the browser start downloading images early, improving first-screen rendering speed.

3. Define Aspect Ratios to Avoid Layout Shift

Setting aspect ratios for images prevents layout jumping during loading (CLS):

html
<img
  src="photo.jpg"
  srcset="photo-400.jpg 400w, photo-800.jpg 800w"
  sizes="(max-width: 600px) 100vw, 800px"
  width="800"
  height="600"
  alt="Photo"
/>

Even before the image loads, the browser will reserve the correct space based on width and height.

Or use CSS:

css
.image-container {
  aspect-ratio: 16 / 9; /* Modern method */
}

/* Fallback for older browsers */
.image-container {
  position: relative;
  padding-bottom: 56.25%; /* 9/16 = 0.5625 */
}

.image-container img {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

Common Problems and Best Practices

Problem 1: Too many image versions are troublesome to prepare

Indeed, manually creating multiple versions is tedious. In actual development, automated tools are typically used:

  • Build tools: Use Webpack, Vite's image processing plugins to automatically generate multiple sizes
  • Image CDNs: Use services like Cloudinary, imgix to dynamically generate different versions via URL parameters
  • CMS systems: WordPress, Next.js and other frameworks have built-in image optimization features

For example, using imgix, you only need to upload one high-definition original:

html
<img
  src="https://example.imgix.net/photo.jpg?w=800"
  srcset="
    https://example.imgix.net/photo.jpg?w=400   400w,
    https://example.imgix.net/photo.jpg?w=800   800w,
    https://example.imgix.net/photo.jpg?w=1200 1200w
  "
  sizes="(max-width: 600px) 100vw, 800px"
  alt="Photo"
/>

The CDN will generate the required sizes in real-time, greatly simplifying the workflow.

Problem 2: How to determine which sizes are needed?

Analyze your website traffic and common devices:

Common breakpoints and corresponding image widths:
- Mobile (320-599px): 320w, 480w
- Tablet (600-1199px): 600w, 800w, 1024w
- Desktop (1200px+): 1200w, 1600w, 1920w

Usually preparing 3-5 sizes is enough to cover most scenarios. Too many options increase complexity instead.

Problem 3: Browser support situation

Modern responsive image features have excellent browser support:

  • srcset and sizes: Supported by all modern browsers (except IE)
  • <picture> element: Chrome 38+, Firefox 38+, Safari 9.1+, Edge 13+
  • For unsupported browsers, they fall back to the <img> tag's src attribute

If you need to support IE, ensure appropriate src fallback solutions.

Best Practice Summary

  1. Always provide alt text: This is important for both accessibility and SEO

  2. Mobile-first image preparation: First ensure mobile experience is good, then enhance desktop

  3. Use modern formats: WebP or AVIF are typically 25-50% smaller than JPEG

  4. Use lazy loading appropriately: Images outside the first screen should be lazy loaded

  5. Monitor actual performance: Use Chrome DevTools' Network panel to check actual downloaded image sizes

  6. Define sizes to avoid layout shift: Use width/height attributes or CSS aspect-ratio

Summary

Responsive images are an essential skill in modern web development. By properly using srcset, sizes, and <picture> elements, you can:

  • Improve performance: Users only download the image sizes they actually need
  • Save bandwidth: Especially important in mobile network environments
  • Enhance experience: See clear, appropriate images on any device
  • Optimize SEO: Faster loading speeds directly impact search rankings

Remember the key points:

  • Use srcset to provide multiple resolution versions
  • Use sizes to tell the browser the image's display size
  • Use <picture> to implement art direction and format selection
  • Combine lazy loading and modern image formats for further optimization

Mastering responsive image technology will elevate your website to new levels in both performance and visual quality.