Serve WebP With the HTML picture Element and Fallbacks
Use the HTML picture element to serve WebP images with automatic JPEG/PNG fallbacks for browsers that don’t support WebP — no JavaScript required.
The <picture> element is the recommended way to serve WebP images in HTML with automatic fallbacks. Browsers that support WebP use the WebP source, while older browsers transparently fall back to JPEG or PNG — all without any JavaScript or server-side logic required.
Basic Pattern #
Wrap a <source> element pointing to your WebP file around a standard <img> fallback. The browser picks the first format it understands.
<picture>
<source srcset="image.webp" type="image/webp">
<img src="image.jpg" alt="Description of image">
</picture>
How It Works #
The browser evaluates <source> elements in document order and uses the first one it supports. If it recognises type="image/webp", it fetches the .webp file and ignores everything else. If it doesn’t recognise WebP — or if the <source> element is missing — it falls through to the <img> element, which acts as the mandatory fallback. The <img> tag is always required; the <picture> wrapper alone does nothing without it.
The <img> fallback is mandatory. Always include it as the last child of <picture> with a meaningful alt attribute. Screen readers and search engines rely on alt text regardless of which image format is ultimately delivered.
Responsive Images With srcset and sizes #
Combine <picture> with srcset and sizes to serve the correct resolution for each viewport while still providing WebP where supported.
<picture>
<source
type="image/webp"
srcset="small.webp 480w, medium.webp 800w, large.webp 1200w"
sizes="(max-width: 600px) 480px, (max-width: 1000px) 800px, 1200px">
<img
src="large.jpg"
srcset="small.jpg 480w, medium.jpg 800w, large.jpg 1200w"
sizes="(max-width: 600px) 480px, (max-width: 1000px) 800px, 1200px"
alt="Description of image"
loading="lazy"
width="1200"
height="800">
</picture>
Keep the sizes attribute identical on both <source> and <img> so the browser applies the same layout-width hints regardless of which format it selects. The width and height attributes on <img> are discussed in the section below.
Animated Images: WebP vs GIF #
WebP supports animation with significantly smaller file sizes than GIF. Use the same <picture> pattern to serve animated WebP to modern browsers and fall back to GIF for older ones.
<picture>
<source srcset="animation.webp" type="image/webp">
<img src="animation.gif" alt="Description of animation">
</picture>
Animated WebP files are typically 50–80% smaller than equivalent GIFs, making this swap one of the highest-impact optimisations available for pages that include animations.
If you only have an animated WebP file and need a GIF fallback for older browsers, convert WebP to GIF with our free converter before wiring up the <picture> pattern above.
Loading Strategies #
Choose a loading strategy based on where the image appears in the page:
Below the Fold #
Add loading="lazy" to the <img> element. The browser defers fetching the image until it approaches the viewport, reducing initial page weight.
Above the Fold (LCP Candidate) #
Omit loading="lazy" and add fetchpriority="high" to signal that this image is critical to rendering. Never lazy-load your Largest Contentful Paint image.
<!-- Below the fold -->
<picture>
<source srcset="photo.webp" type="image/webp">
<img src="photo.jpg" alt="A landscape photo" loading="lazy" width="800" height="600">
</picture>
<!-- Hero / LCP image -->
<picture>
<source srcset="hero.webp" type="image/webp">
<img src="hero.jpg" alt="Hero banner" fetchpriority="high" width="1200" height="600">
</picture>
Add fetchpriority="high" to the <img> element of your hero or banner image. This hints to the browser to begin fetching the image earlier in the network queue, which directly improves your Largest Contentful Paint (LCP) score.
Always Include Width and Height #
Setting explicit width and height attributes on the <img> element to the intrinsic dimensions of the image allows the browser to reserve the correct amount of space in the layout before the image loads. This eliminates Cumulative Layout Shift (CLS) — one of the Core Web Vitals metrics.
<picture>
<source srcset="product.webp" type="image/webp">
<img
src="product.jpg"
alt="Product image"
width="600"
height="400"
loading="lazy">
</picture>
Use the actual pixel dimensions of the largest source image. CSS can still scale the image fluidly; the width and height attributes only establish the aspect ratio used for layout reservation.
Browser Support Summary #
- <picture> element — Chrome 38+, Firefox 38+, Safari 9.1+, Edge 13+.
- WebP format — Chrome 23+, Firefox 65+, Safari 14+, Edge 18+.
- loading="lazy" — Chrome 77+, Firefox 75+, Safari 15.4+, Edge 79+.
- fetchpriority — Chrome 102+, Firefox 132+, Safari 17.2+, Edge 102+.
All modern browser releases fully support the patterns described on this page. The <img> fallback handles any remaining edge cases.
