Using srcset

Master the srcset attribute for responsive images. Learn how browsers select the optimal image size and how to use the sizes attribute effectively.

What is srcset?

The srcset attribute allows you to provide multiple image sources at different sizes. The browser automatically selects the most appropriate image based on the device's screen size, pixel density, and other factors.

<img
  src="image-768.webp"
  srcset="
    image-320.webp 320w,
    image-640.webp 640w,
    image-768.webp 768w,
    image-1024.webp 1024w,
    image-1280.webp 1280w
  "
  sizes="100vw"
  alt="Responsive image"
/>

Key benefit: Users on mobile devices download smaller images, saving bandwidth and loading faster. Users on high-resolution displays get crisp images without serving unnecessarily large files to everyone.

How Browsers Choose Images

The browser uses a combination of factors to select the best image:

  1. Viewport width: The current width of the browser window
  2. Device pixel ratio (DPR): How many physical pixels represent one CSS pixel (e.g., 2x for Retina displays)
  3. sizes attribute: Your hint about how wide the image will be displayed
  4. Available sources: The images listed in srcset with their widths

Selection Example

Consider an image with sizes="100vw" on a 375px wide phone with 2x DPR:

  • Viewport: 375px
  • DPR: 2x
  • Required pixels: 375 × 2 = 750px
  • Browser selects: 768w image (closest match ≥ 750px)

The browser intelligently picks the smallest image that satisfies the display requirements, balancing quality against download size.

The sizes Attribute

The sizes attribute tells the browser how wide the image will be displayed at different viewport widths. This is crucial for correct image selection.

Syntax

sizes="(media-condition) width, (media-condition) width, default-width"

Common Examples

Full-width image

sizes="100vw"

Image spans the entire viewport width.

Responsive grid (1-3 columns)

sizes="(max-width: 640px) 100vw, (max-width: 1024px) 50vw, 33vw"

Full width on mobile, half on tablet, third on desktop.

Fixed-width container

sizes="(max-width: 768px) 100vw, 768px"

Full width on small screens, max 768px on larger screens.

Sidebar layout

sizes="(max-width: 768px) 100vw, calc(100vw - 300px)"

Full width on mobile, viewport minus 300px sidebar on desktop.

Important: An incorrect sizes attribute can cause the browser to download the wrong image size. Always match sizes to your actual CSS layout.

OPTIMAGE srcset

OPTIMAGE generates 11 optimized sizes for each image, giving browsers plenty of options:

WidthBest For
320wSmall mobile, thumbnails
384wMobile landscape
448wLarge mobile
512wSmall tablet
576wTablet portrait
672wTablet landscape
768wSmall desktop, 2x mobile
896wDesktop
1024wLarge desktop, 2x tablet
1152wWide desktop
1280wFull HD, 2x desktop

Complete OPTIMAGE srcset

<img
  src="https://cdn.optimage.com/col_abc123/768/hero.webp"
  srcset="
    https://cdn.optimage.com/col_abc123/320/hero.webp 320w,
    https://cdn.optimage.com/col_abc123/384/hero.webp 384w,
    https://cdn.optimage.com/col_abc123/448/hero.webp 448w,
    https://cdn.optimage.com/col_abc123/512/hero.webp 512w,
    https://cdn.optimage.com/col_abc123/576/hero.webp 576w,
    https://cdn.optimage.com/col_abc123/672/hero.webp 672w,
    https://cdn.optimage.com/col_abc123/768/hero.webp 768w,
    https://cdn.optimage.com/col_abc123/896/hero.webp 896w,
    https://cdn.optimage.com/col_abc123/1024/hero.webp 1024w,
    https://cdn.optimage.com/col_abc123/1152/hero.webp 1152w,
    https://cdn.optimage.com/col_abc123/1280/hero.webp 1280w
  "
  sizes="100vw"
  alt="Hero image"
/>

Practical Examples

Hero Banner

Full-width hero image that spans the viewport:

<img
  src="https://cdn.optimage.com/col_hero/768/banner.webp"
  srcset="..."
  sizes="100vw"
  alt="Welcome to our site"
  loading="eager"
  fetchpriority="high"
/>

Product Grid (3 columns on desktop)

Images in a responsive grid layout:

<!-- CSS: grid-cols-1 md:grid-cols-2 lg:grid-cols-3 -->
<img
  src="https://cdn.optimage.com/col_products/768/product.webp"
  srcset="..."
  sizes="(max-width: 768px) 100vw, (max-width: 1024px) 50vw, 33vw"
  alt="Product name"
  loading="lazy"
/>

Thumbnail Gallery

Small thumbnails with fixed max size:

<!-- CSS: w-24 h-24 (96px) -->
<img
  src="https://cdn.optimage.com/col_gallery/320/thumb.webp"
  srcset="
    https://cdn.optimage.com/col_gallery/320/thumb.webp 320w,
    https://cdn.optimage.com/col_gallery/384/thumb.webp 384w
  "
  sizes="96px"
  alt="Thumbnail"
  loading="lazy"
/>

Blog Post with Max Width

Content image in a max-width container:

<!-- CSS: max-w-prose (65ch ≈ 700px) -->
<img
  src="https://cdn.optimage.com/col_blog/768/article-image.webp"
  srcset="..."
  sizes="(max-width: 700px) 100vw, 700px"
  alt="Article illustration"
  loading="lazy"
/>

Common Mistakes

Missing sizes attribute

<!-- Wrong: No sizes -->
<img srcset="..." alt="Image" />

Without sizes, the browser assumes 100vw and may download larger images than needed.

sizes doesn't match layout

<!-- Wrong: sizes says 100vw but image is in a 3-column grid -->
<img srcset="..." sizes="100vw" class="w-1/3" alt="Image" />

The browser will download images 3x larger than needed.

Using srcset with x descriptors for responsive images

<!-- Less flexible: x descriptors -->
<img srcset="image.webp 1x, image-2x.webp 2x" alt="Image" />

For responsive images, use width descriptors (w) with sizes. The x syntax is for fixed-size images only.

Testing srcset

Verify your srcset implementation using browser developer tools:

  1. Network tab: Check which image size was actually downloaded
  2. Responsive mode: Resize the viewport and reload to see different sizes selected
  3. Device emulation: Test with different DPR settings (1x, 2x, 3x)
  4. Elements panel: Inspect the img element to see currentSrc

Tip: In Chrome DevTools, you can use $0.currentSrc in the Console to see which image was selected for the currently inspected img element.