Blog Performance 9 min read

Responsive Images with srcset and Deterministic Fallback URLs

Combine srcset with deterministic placeholder URLs to serve correctly sized fallback images at every breakpoint and avoid layout shift on slow networks.

srcset placeholderresponsive imagesimage fallbackslayout shiftCore Web Vitals
Responsive Images with srcset and Deterministic Fallback URLs

srcset lets the browser pick the best image from a set based on device pixel ratio and viewport width. When you include fallback.pics placeholder URLs in that set, broken or missing images degrade cleanly at every breakpoint instead of collapsing the layout.

Most srcset implementations only define real image sources and omit a fallback strategy. Adding deterministic placeholder URLs for each declared size means the browser always has a correctly-sized image to render, even when the primary sources return 404.

How srcset works

The browser selects from srcset based on viewport and DPR

srcset defines a list of image source candidates with width descriptors (400w, 800w) or pixel density descriptors (1x, 2x). The browser evaluates its current viewport width, the sizes attribute hint, and the device pixel ratio, then selects the most appropriate source.

On a 375px wide Retina display (2x DPR), a browser will prefer a 750px-wide image over a 400px one if both are available. On a 1440px desktop, it picks the largest useful size. The browser makes this decision once per image element — if the chosen source fails, there is no automatic retry from the srcset list.

That last point matters for fallback strategy: srcset is not an error recovery mechanism. If the selected source returns a 404 or fails to load, the browser shows a broken image icon. You still need an onerror handler or a server-side fallback for missing images.

Fallback in srcset

Including placeholder URLs for each srcset width descriptor

One pattern is to serve placeholder URLs as the src fallback while the srcset contains real images. If the browser selects a real source from srcset and it loads, great. If all sources fail, the src fallback provides a same-size placeholder.

A stronger pattern for catalogs with partially populated media is to conditionally include placeholder URLs in the srcset itself when a real image is absent. The placeholder URL can be constructed to match each declared width exactly, so the browser selects a correctly sized placeholder.

Implementation text
<!-- Basic: placeholder as src fallback for a responsive hero -->
<img
  src="https://fallback.pics/api/v1/800x600/7C3AED/FFFFFF?text=Hero"
  srcset="
    /images/hero-400.jpg 400w,
    /images/hero-800.jpg 800w,
    /images/hero-1200.jpg 1200w
  "
  sizes="(max-width: 600px) 100vw, 800px"
  width="800"
  height="600"
  loading="eager"
  fetchpriority="high"
  alt="Hero image"
  onerror="this.srcset=''; this.src='https://fallback.pics/api/v1/800x600/7C3AED/FFFFFF?text=Hero';"
/>

Dimensions matter

Match placeholder dimensions to srcset width descriptors

A placeholder that does not match the space reserved by the aspect-ratio container or explicit width and height attributes will cause layout shift. If you declare width=800 height=600 on the img element, your fallback URL should also produce an 800×600 image.

fallback.pics generates images at exact dimensions from the URL. For a responsive component where you need three sizes, construct three placeholder URLs with matching dimensions. You can also construct the URL dynamically from the same width and height values used in the srcset.

When using JavaScript to generate srcset strings, build the placeholder URLs from the same dimension constants. This keeps the fallback set consistent with the real image set without duplicating numbers across the codebase.

Implementation tsx
// Build srcset with matching placeholder fallbacks
const sizes = [400, 800, 1200] as const;
const aspectRatio = 3 / 4; // portrait product image

function buildSrcset(imageId: string): string {
  return sizes
    .map((w) => {
      const h = Math.round(w * aspectRatio);
      const real = `/cdn/products/${imageId}/${w}x${h}.jpg`;
      return `${real} ${w}w`;
    })
    .join(', ');
}

function buildFallbackSrc(w = 800): string {
  const h = Math.round(w * aspectRatio);
  return `https://fallback.pics/api/v1/${w}x${h}/E4E4E7/71717A?text=Product`;
}

Layout shift prevention

Explicit width and height on every responsive img element

The browser calculates the aspect-ratio box for an image from its width and height attributes before the image loads. If you omit those attributes, the box collapses to zero height and expands when the image loads, shifting the page content. This is Cumulative Layout Shift.

For srcset images, always provide width and height matching the largest declared size (or the intrinsic size of the image). The browser uses the aspect ratio from those attributes, even when it ultimately renders a smaller srcset candidate. Your placeholder URL should match that same aspect ratio.

Alternatively, use an aspect-ratio container in CSS. The container reserves the right amount of space regardless of the image's intrinsic size, and both real images and fallback placeholders fill it without layout shift.

sizes attribute

Correct sizes hints prevent oversized placeholder fetches

Without a sizes attribute, the browser assumes the image fills 100% of the viewport. On a 1440px display, it selects the largest srcset candidate even if the image only occupies a 300px sidebar. This wastes bandwidth on the placeholder just as much as on real images.

Write accurate sizes hints: (max-width: 640px) 100vw, (max-width: 1024px) 50vw, 33vw for a three-column grid. The browser then selects an appropriately sized candidate from both the real images and any placeholders in the srcset.

Implementation text
<!-- Product grid card with accurate sizes hint -->
<img
  src="https://fallback.pics/api/v1/400x400/E4E4E7/71717A?text=Product"
  srcset="
    /products/img-200.jpg 200w,
    /products/img-400.jpg 400w,
    /products/img-800.jpg 800w
  "
  sizes="(max-width: 640px) 50vw, (max-width: 1024px) 33vw, 25vw"
  width="400"
  height="400"
  loading="lazy"
  decoding="async"
  alt="Product image"
/>

Art direction

Use picture element for different crops at different breakpoints

srcset serves the same image composition at different resolutions. When you need different crops at different breakpoints — a wide landscape on desktop, a portrait crop on mobile — use the picture element with multiple source elements.

Each source element in a picture block can carry its own srcset and media condition. Your fallback placeholder can be dimension-matched to each breakpoint's crop by placing a matching placeholder URL in the src attribute of the fallback img element.

Implementation text
<!-- picture element with per-breakpoint fallback dimensions -->
<picture>
  <source
    media="(min-width: 1024px)"
    srcset="/images/hero-1200x500.jpg 1200w, /images/hero-2400x1000.jpg 2400w"
    sizes="100vw"
  />
  <source
    media="(min-width: 640px)"
    srcset="/images/hero-800x600.jpg 800w"
    sizes="100vw"
  />
  <img
    src="https://fallback.pics/api/v1/400x600/7C3AED/FFFFFF?text=Hero"
    width="400"
    height="600"
    loading="eager"
    fetchpriority="high"
    alt="Hero banner"
    onerror="this.src='https://fallback.pics/api/v1/400x600/7C3AED/FFFFFF?text=Hero';"
  />
</picture>

Resources

Further reading on responsive images and fallback patterns

The srcset specification allows browsers to make intelligent choices, but it does not handle errors. A complete responsive image implementation combines srcset for optimization with onerror or server-side fallbacks for reliability.

Test your responsive image setup with DevTools Device Mode at 1x, 2x, and 3x DPR, and verify that fallback URLs appear correctly sized in every scenario.

Implementation text
# API reference
https://fallback.pics/docs/
https://fallback.pics/placeholder-image-api/

# Related posts
https://fallback.pics/blog/fetchpriority-critical-image-fallbacks/
https://fallback.pics/blog/responsive-placeholder-images-cards-banners-grids/

Key takeaways

What to standardize before shipping

  • srcset selects the best source but does not retry on failure — always pair it with an onerror fallback.
  • Match placeholder URL dimensions to each srcset width descriptor to prevent layout shift.
  • Write accurate sizes hints to avoid the browser fetching oversized placeholders.
  • Use explicit width and height on every img element so the browser can reserve the aspect-ratio box before load.
  • For different crops at different breakpoints, use the picture element with per-source media conditions.

Production fallback layer

Use fallback.pics anywhere an image URL is accepted.

Start with one deterministic URL and standardize fallback behavior across your design system.

Read the docs