Clean Markup

Responsive Images Done Right with Picture and Srcset

Responsive Images Done Right with Picture and Srcset

Serving a single large JPEG image to both 27-inch desktop monitors and mobile devices on cellular connections wastes megabytes of bandwidth. Modern HTML gives us two native mechanisms to solve this directly in markup:

  1. srcset and sizes on <img> for resolution switching (letting the browser pick the right pixel width for the screen size and device pixel ratio).
  2. The <picture> element for modern image format delivery (serving lightweight .webp files to supporting browsers with automatic fallback to .jpg).

Example

<picture>
  <source type="image/webp" srcset="/img/posts/cover.webp" />
  <img src="/img/posts/cover.jpg" alt="Clean Markup cover" />
</picture>

Input : Multiple image resolutions (400w, 800w, 1200w) in .webp and .jpg formats
Output : Responsive <picture> markup that serves WebP and matches the viewport width.

Implementation

<figure class="article-hero">
  <picture>
    <!-- 1. Prefer WebP in browsers that support it -->
    <source
      type="image/webp"
      srcset="
        /img/posts/hero-400.webp   400w,
        /img/posts/hero-800.webp   800w,
        /img/posts/hero-1200.webp 1200w
      "
      sizes="(max-width: 768px) 100vw, 800px"
    />

    <!-- 2. Fallback to JPEG with the same resolution choices -->
    <img
      src="/img/posts/hero-800.jpg"
      srcset="
        /img/posts/hero-400.jpg   400w,
        /img/posts/hero-800.jpg   800w,
        /img/posts/hero-1200.jpg 1200w
      "
      sizes="(max-width: 768px) 100vw, 800px"
      alt="Responsive image architecture diagram"
    />
  </picture>
  <figcaption>
    The browser selects the best format and width before downloading a single byte.
  </figcaption>
</figure>

Main Point: The <img> tag inside <picture> is mandatory—it acts as the actual rendered element and the fallback for browsers that do not support <picture> or image/webp.

Credits

Photo by Christopher Gower

← Home