About This HTML Issue
The <picture> element exists to give browsers a choice between multiple image sources. The browser evaluates each <source> in order, looking for the first one whose conditions match the current environment. These conditions are expressed through the media attribute (e.g., viewport width or resolution) and the type attribute (e.g., image/webp or image/avif). If a <source> lacks both attributes, it acts as an unconditional match — the browser will always select it, making any subsequent <source> elements or an <img> with srcset unreachable. This defeats the purpose of the <picture> element entirely.
The HTML specification requires these attributes specifically to prevent this situation. When a <source> has a following sibling <source> or a following <img> with srcset, at least one selection criterion (media or type) must be present so the browser can meaningfully choose between the options. A <source> without these attributes is only valid if it’s the last <source> before a plain <img> (one without srcset), since in that case it serves as the final fallback within the <picture>.
This matters for several reasons:
- Standards compliance: The HTML living standard explicitly defines this requirement. Violating it produces a validation error.
- Predictable rendering: Without distinguishing attributes, browsers may silently ignore sources or always pick the first one, leading to inconsistent behavior across browsers.
-
Performance: The
<picture>element is often used to serve smaller images on small viewports or modern formats like WebP and AVIF to browsers that support them. Without propermediaortypeattributes, these optimizations won’t work as intended.
How to fix it
Add a media attribute, a type attribute, or both to each <source> element that is followed by another <source> or an <img> with srcset:
-
Use
typewhen you’re offering the same image in different formats (e.g., AVIF, WebP, JPEG). The browser picks the first format it supports. -
Use
mediawhen you’re serving different images based on viewport conditions (art direction). The browser picks the source whose media query matches. - Use both when you want to combine format negotiation with art direction.
Examples
Incorrect — <source> without media or type
Each <source> below has no selection criterion, so the browser has no way to choose between them:
<picture>
<source srcset="hero.webp">
<source srcset="hero.jpg">
<img src="hero.jpg" srcset="hero-2x.jpg 2x" alt="A mountain landscape">
</picture>
Correct — using type for format negotiation
Adding type lets the browser pick the first format it supports:
<picture>
<source srcset="hero.avif" type="image/avif">
<source srcset="hero.webp" type="image/webp">
<img src="hero.jpg" srcset="hero-2x.jpg 2x" alt="A mountain landscape">
</picture>
Correct — using media for art direction
Adding media lets the browser pick the source that matches the viewport:
<picture>
<source srcset="hero-wide.jpg" media="(min-width: 1024px)">
<source srcset="hero-narrow.jpg" media="(max-width: 1023px)">
<img src="hero-narrow.jpg" srcset="hero-narrow-2x.jpg 2x" alt="A mountain landscape">
</picture>
Correct — combining media and type
You can use both attributes together to serve the right format at the right viewport size:
<picture>
<source srcset="hero-wide.avif" media="(min-width: 1024px)" type="image/avif">
<source srcset="hero-wide.webp" media="(min-width: 1024px)" type="image/webp">
<source srcset="hero-narrow.avif" media="(max-width: 1023px)" type="image/avif">
<source srcset="hero-narrow.webp" media="(max-width: 1023px)" type="image/webp">
<img src="hero-narrow.jpg" alt="A mountain landscape">
</picture>
Correct — single <source> before a plain <img>
When there’s only one <source> and the <img> has no srcset, no media or type is required — but adding type is still recommended for clarity:
<picture>
<source srcset="hero.webp" type="image/webp">
<img src="hero.jpg" alt="A mountain landscape">
</picture>
Find issues like this automatically
Rocket Validator scans thousands of pages in seconds, detecting HTML issues across your entire site.