HTML Guides for srcset
Learn how to identify and fix common HTML validation errors flagged by the W3C Validator — so your pages are standards-compliant and render correctly across every browser. Also check our Accessibility Guides.
A <source> element inside a <picture> that is followed by another <source> or an <img> with srcset must include a media and/or type attribute.
The <source> element is used inside <picture> for responsive images, allowing different resources to be loaded based on conditions such as viewport width (media) or image format (type). According to the HTML standard, when multiple <source> elements are present (or a following <img> with srcset), each <source> must provide a media and/or type attribute so the browser can choose the appropriate resource based on those hints.
Without media or type, the browser cannot distinguish when to use each source, which can lead to validation errors and unexpected rendering behavior.
Incorrect example (causes the validator error):
<picture>
<source srcset="image1.webp">
<source srcset="image2.jpg">
<img alt="" src="fallback.jpg" srcset="fallback2x.jpg 2x">
</picture>
Correct examples (fixing the error):
<picture>
<source srcset="image1.webp" type="image/webp">
<source srcset="image2.jpg" type="image/jpeg">
<img alt="" src="fallback.jpg" srcset="fallback2x.jpg 2x">
</picture>
or
<picture>
<source srcset="image-small.jpg" media="(max-width: 600px)">
<source srcset="image-large.jpg" media="(min-width: 601px)">
<img alt="" src="fallback.jpg" srcset="fallback2x.jpg 2x">
</picture>
By specifying the media and/or type attributes for each <source>, you satisfy the HTML standard and resolve the W3C validator issue.
Replace square brackets in srcset URLs or percent-encode them.
The img element’s srcset expects valid URLs for each image candidate. According to the URL Standard, unescaped square brackets are not allowed in the path or query of an HTTP(S) URL used in HTML attributes like srcset. They must be either removed, replaced, or percent-encoded.
- Use safe characters in query parameters (e.g., hyphens or underscores instead of brackets).
- If brackets must remain for backend reasons, percent-encode them: [ -> %5B, ] -> %5D.
- Ensure each image candidate follows the URL [whitespace] descriptor pattern (e.g., 2x, 300w) with commas separating candidates.
HTML examples
Example causing the error
<img
src="image.jpg"
srcset="image.jpg?size=[small] 1x, image@2x.jpg?size=[large] 2x"
alt="Sample">
Corrected example (encode brackets)
<img
src="image.jpg"
srcset="image.jpg?size=%5Bsmall%5D 1x, image@2x.jpg?size=%5Blarge%5D 2x"
alt="Sample">
Corrected example (avoid brackets)
<img
src="image.jpg"
srcset="image.jpg?size=small 1x, image@2x.jpg?size=large 2x"
alt="Sample">
srcset contains candidates without a width descriptor while sizes is present, so each candidate must use a width (w) descriptor.
When an img has sizes, every srcset candidate must include a width descriptor like 320w, not a pixel density descriptor like 1x. Mixed descriptors are not allowed in the same srcset. Use either:
- Width descriptors with sizes (e.g., 320w, 640w, 1024w)
- Density descriptors without sizes (e.g., 1x, 2x)
The browser uses sizes to map CSS layout width to the best w candidate. Without sizes, density (x) can be used, but not together with sizes.
HTML examples
Reproduce the issue (invalid: sizes + x descriptors)
<img
src="photo-640.jpg"
srcset="photo-640.jpg 1x, photo-1280.jpg 2x"
sizes="(max-width: 600px) 100vw, 600px"
alt="Sample photo">
Fix using width descriptors with sizes (valid)
<img
src="photo-640.jpg"
srcset="photo-320.jpg 320w, photo-640.jpg 640w, photo-1280.jpg 1280w"
sizes="(max-width: 600px) 100vw, 600px"
alt="Sample photo">
Alternative fix: remove sizes and use density descriptors (valid)
<img
src="photo-640.jpg"
srcset="photo-640.jpg 1x, photo-1280.jpg 2x"
alt="Sample photo">
The srcset attribute supports two types of descriptors: width descriptors (like 480w) and pixel density descriptors (like 2x). However, these two types cannot be mixed, and the sizes attribute is only compatible with width descriptors. The sizes attribute tells the browser how wide the image will be displayed at various viewport sizes, and the browser uses this information along with the width descriptors in srcset to choose the most appropriate image file. If sizes is present but an image candidate lacks a width descriptor, the browser cannot perform this calculation correctly.
This matters for several reasons. First, it violates the WHATWG HTML specification, which explicitly requires that when sizes is present, all image candidates must use width descriptors. Second, browsers may ignore malformed srcset values or fall back to unexpected behavior, resulting in the wrong image being loaded — potentially hurting performance by downloading unnecessarily large files or degrading visual quality by selecting a too-small image. Third, standards-compliant markup ensures consistent, predictable behavior across all browsers and devices.
A common mistake is specifying a plain URL without any descriptor, or mixing density descriptors (1x, 2x) with the sizes attribute. An image candidate string without any descriptor defaults to 1x, which is a density descriptor — and that conflicts with the presence of sizes.
Examples
❌ Incorrect: Missing width descriptor with sizes present
<picture>
<source
srcset="image-small.jpg, image-large.jpg 1024w"
sizes="(max-width: 600px) 480px, 800px">
<img src="image-fallback.jpg" alt="A scenic landscape">
</picture>
Here, image-small.jpg has no width descriptor. Since sizes is present, this triggers the validation error.
❌ Incorrect: Using density descriptors with sizes
<img
srcset="image-1x.jpg 1x, image-2x.jpg 2x"
sizes="(max-width: 600px) 480px, 800px"
src="image-fallback.jpg"
alt="A scenic landscape">
Density descriptors (1x, 2x) are incompatible with the sizes attribute.
✅ Correct: All candidates have width descriptors
<picture>
<source
srcset="image-small.jpg 480w, image-large.jpg 1024w"
sizes="(max-width: 600px) 480px, 800px">
<img src="image-fallback.jpg" alt="A scenic landscape">
</picture>
Every image candidate now includes a width descriptor, which pairs correctly with the sizes attribute.
✅ Correct: Using density descriptors without sizes
If you want to use density descriptors instead of width descriptors, simply remove the sizes attribute:
<img
srcset="image-1x.jpg 1x, image-2x.jpg 2x"
src="image-fallback.jpg"
alt="A scenic landscape">
This is valid because density descriptors don’t require (and shouldn’t be used with) the sizes attribute.
✅ Correct: Width descriptors on <img> with sizes
<img
srcset="photo-320.jpg 320w, photo-640.jpg 640w, photo-1280.jpg 1280w"
sizes="(max-width: 400px) 320px, (max-width: 800px) 640px, 1280px"
src="photo-640.jpg"
alt="A close-up of a flower">
Each entry in srcset specifies its intrinsic width, and sizes tells the browser which display width to expect at each breakpoint. The browser then selects the best-fitting image automatically.
All values in the srcset attribute must include a width descriptor (such as 300w) when the sizes attribute is present.
The srcset attribute is used to provide multiple image sources for responsive images. Each image candidate string in srcset must specify the image’s width (e.g., 600w) or pixel density (e.g., 2x). When you use a sizes attribute, all srcset candidates must use width descriptors (w).
Example of incorrect usage:
<img
src="/img/pic1.jpg"
srcset="/img/pic1.jpg"
sizes="(max-width: 600px) 100vw, 600px"
alt=""
>
This example is invalid because the srcset value does not include a width descriptor.
Corrected usage with width descriptors:
<img
src="/img/pic1.jpg"
srcset="/img/pic1.jpg 600w"
sizes="(max-width: 600px) 100vw, 600px"
alt=""
>
If you have multiple image sizes, include each with its corresponding width:
<img
src="/img/pic1.jpg"
srcset="
/img/pic1_small.jpg 300w,
/img/pic1.jpg 600w
"
sizes="(max-width: 600px) 100vw, 600px"
alt=""
>
Always match each image URL in srcset with a width (w) or pixel density (x) descriptor if appropriate for your layout.
The srcset attribute allows you to specify multiple image sources so the browser can choose the most appropriate one based on the user’s device characteristics, such as screen resolution or viewport width. When you include a srcset attribute on an <img> element, the HTML specification requires it to contain one or more comma-separated image candidate strings. Each string consists of a URL followed by an optional descriptor — either a width descriptor (e.g., 200w) or a pixel density descriptor (e.g., 2x).
This validation error typically appears when:
- The srcset attribute is empty (srcset="")
- The srcset attribute contains only whitespace (srcset=" ")
- The value contains syntax errors such as missing URLs, invalid descriptors, or incorrect formatting
- A templating engine or CMS outputs the attribute with no value
This matters because browsers rely on the srcset value to select the best image to load. An empty or malformed srcset means the browser must fall back entirely to the src attribute, making the srcset attribute pointless. Additionally, invalid markup can cause unexpected behavior across different browsers and undermines standards compliance.
How to fix it
- Provide valid image candidate strings. Each entry needs a URL and optionally a width or pixel density descriptor, with entries separated by commas.
- Remove the attribute entirely if you don’t have multiple image sources to offer. A plain src attribute is perfectly fine on its own.
- Check dynamic output. If a CMS or templating system generates the srcset, ensure it conditionally omits the attribute when no responsive image candidates are available, rather than outputting an empty attribute.
Examples
❌ Empty srcset attribute
<img src="/img/photo.jpg" alt="A sunset over the ocean" srcset="">
This triggers the error because srcset is present but contains no image candidate strings.
❌ Malformed srcset value
<img src="/img/photo.jpg" alt="A sunset over the ocean" srcset="1x, 2x">
This is invalid because each candidate string must include a URL. Descriptors alone are not valid entries.
✅ Using pixel density descriptors
<img
src="/img/photo-400.jpg"
alt="A sunset over the ocean"
srcset="
/img/photo-400.jpg 1x,
/img/photo-800.jpg 2x
">
Each candidate string contains a URL followed by a pixel density descriptor (1x, 2x). The browser picks the best match for the user’s display.
✅ Using width descriptors with sizes
<img
src="/img/photo-400.jpg"
alt="A sunset over the ocean"
srcset="
/img/photo-400.jpg 400w,
/img/photo-800.jpg 800w,
/img/photo-1200.jpg 1200w
"
sizes="(max-width: 600px) 400px, (max-width: 1000px) 800px, 1200px">
Width descriptors (e.g., 400w) tell the browser the intrinsic width of each image. The sizes attribute then tells the browser how large the image will be displayed at various viewport sizes, allowing it to calculate the best source to download.
✅ Removing srcset when not needed
<img src="/img/photo.jpg" alt="A sunset over the ocean">
If you only have a single image source, simply omit srcset altogether. The src attribute alone is valid and sufficient.
✅ Single candidate in srcset
<img
src="/img/photo.jpg"
alt="A sunset over the ocean"
srcset="/img/photo-highres.jpg 2x">
Even a single image candidate string is valid. Here, the browser will use the high-resolution image on 2x displays and fall back to src otherwise.
The srcset attribute allows you to provide multiple image sources so the browser can choose the most appropriate one based on the user’s viewport size or screen density. There are two distinct modes for srcset:
- Width descriptor mode — each candidate specifies its intrinsic width using a w descriptor (e.g., 400w). This mode requires the sizes attribute so the browser knows how much space the image will occupy in the layout and can calculate which source to download.
- Pixel density descriptor mode — each candidate specifies a pixel density using an x descriptor (e.g., 2x). This mode must not include a sizes attribute.
When you include a sizes attribute but forget to add width descriptors to one or more srcset entries, the browser has incomplete information. The HTML specification explicitly states that if sizes is present, all image candidate strings must use width descriptors. An entry without a descriptor defaults to 1x (a pixel density descriptor), which conflicts with the width descriptor mode triggered by sizes. This mismatch causes the W3C validator to report the error.
Beyond validation, this matters for real-world performance. Responsive images are one of the most effective tools for reducing page weight on smaller screens. If the descriptors are missing or mismatched, browsers may download an image that is too large or too small, hurting both performance and visual quality.
How to fix it
You have two options depending on your use case:
Option 1: Add width descriptors to all srcset candidates
If you need the browser to select images based on viewport size (the most common responsive images pattern), keep the sizes attribute and ensure every srcset entry has a w descriptor that matches the image’s intrinsic pixel width.
Option 2: Remove sizes and use pixel density descriptors
If you only need to serve higher-resolution images for high-DPI screens (e.g., Retina displays) and the image always renders at the same CSS size, remove the sizes attribute and use x descriptors instead.
Examples
❌ Incorrect: sizes present but srcset entry has no width descriptor
<img
src="photo-800.jpg"
srcset="photo-400.jpg, photo-800.jpg"
sizes="(min-width: 600px) 800px, 100vw"
alt="A mountain landscape">
Both srcset entries lack a width descriptor. Because sizes is present, the validator reports an error for each candidate.
✅ Correct: sizes present with width descriptors on every candidate
<img
src="photo-800.jpg"
srcset="photo-400.jpg 400w, photo-800.jpg 800w"
sizes="(min-width: 600px) 800px, 100vw"
alt="A mountain landscape">
Each candidate now specifies its intrinsic width (400w and 800w), which tells the browser the actual pixel width of each source file. The browser combines this with the sizes value to pick the best match.
❌ Incorrect: mixing width descriptors and bare entries
<img
src="photo-800.jpg"
srcset="photo-400.jpg 400w, photo-800.jpg"
sizes="(min-width: 600px) 800px, 100vw"
alt="A mountain landscape">
The second candidate (photo-800.jpg) is missing its width descriptor. All candidates must have one when sizes is present — not just some of them.
✅ Correct: pixel density descriptors without sizes
<img
src="photo-800.jpg"
srcset="photo-800.jpg 1x, photo-1600.jpg 2x"
alt="A mountain landscape">
Here the sizes attribute is removed, and each srcset entry uses a pixel density descriptor (1x, 2x). This is valid and appropriate when the image always occupies the same CSS dimensions regardless of viewport width.
❌ Incorrect: using sizes with pixel density descriptors
<img
src="photo-800.jpg"
srcset="photo-800.jpg 1x, photo-1600.jpg 2x"
sizes="(min-width: 600px) 800px, 100vw"
alt="A mountain landscape">
The sizes attribute and x descriptors cannot be combined. Either switch to w descriptors or remove sizes.
Quick reference
| Pattern | srcset descriptor | sizes required? |
|---|---|---|
| Viewport-based selection | Width (w) | Yes |
| Density-based selection | Pixel density (x) | No — must be omitted |
Remember that the w value in srcset refers to the image file’s intrinsic pixel width (e.g., an 800-pixel-wide image gets 800w), while values in sizes use CSS length units like px, vw, or em to describe how wide the image will render in the layout.
The srcset attribute lets browsers intelligently choose which image to load based on the viewport size and device pixel ratio. Each entry in a srcset consists of a URL followed by either a width descriptor (like 300w) or a pixel density descriptor (like 2x). When using width descriptors, the value represents the intrinsic pixel width of the image file — that is, the actual width of the image as stored on disk.
A width descriptor of 0w violates the HTML specification, which requires width descriptors to be integers greater than zero. A zero-width image cannot meaningfully participate in the browser’s source selection process. The browser uses these width values in combination with the sizes attribute to calculate which image best fits the current layout — a value of zero would break this calculation entirely.
This issue commonly occurs when:
- Image dimensions are dynamically generated and a fallback of 0 is used for missing data.
- A placeholder or empty state is accidentally included in the srcset.
- A CMS or build tool outputs a 0w descriptor for images whose dimensions weren’t computed.
Why it matters
- Standards compliance: The HTML specification explicitly requires width descriptors to be positive integers. Validators will flag 0w as an error.
- Browser behavior: While browsers may silently ignore the invalid entry, you can’t rely on consistent handling across all browsers and versions. The image selection algorithm may behave unpredictably.
- Performance: A well-formed srcset is key to responsive image loading. Invalid descriptors can prevent browsers from selecting the optimal image, leading to unnecessarily large downloads or poor image quality.
How to fix it
- Open the image file associated with the 0w descriptor and check its actual pixel width using an image editor or the command line.
- Replace 0w with the correct width (e.g., 150w for a 150-pixel-wide image).
- If the image is truly zero-width or a placeholder, remove that entry from the srcset entirely.
- Ensure every remaining entry has a unique, positive width descriptor.
Examples
❌ Invalid: width descriptor of 0w
<picture>
<source
srcset="/images/icon_placeholder.png 0w,
/images/icon_large.png 600w"
media="(max-width: 600px)">
<img src="/images/icon_fallback.png" alt="App logo">
</picture>
The 0w descriptor triggers the validation error because zero is not a valid width.
✅ Fixed: all width descriptors are positive
<picture>
<source
srcset="/images/icon_small.png 300w,
/images/icon_large.png 600w"
media="(max-width: 600px)">
<img src="/images/icon_fallback.png" alt="App logo">
</picture>
Each entry now has a meaningful width descriptor (300w and 600w) that reflects the actual pixel width of the corresponding image.
❌ Invalid: 0w on an <img> element
<img
srcset="/images/hero_tiny.jpg 0w,
/images/hero_medium.jpg 800w,
/images/hero_large.jpg 1200w"
sizes="100vw"
src="/images/hero_medium.jpg"
alt="Mountain landscape">
✅ Fixed: placeholder entry removed or corrected
If the tiny image is 400 pixels wide, use 400w:
<img
srcset="/images/hero_tiny.jpg 400w,
/images/hero_medium.jpg 800w,
/images/hero_large.jpg 1200w"
sizes="100vw"
src="/images/hero_medium.jpg"
alt="Mountain landscape">
Alternatively, if the image doesn’t belong in the set at all, simply remove it:
<img
srcset="/images/hero_medium.jpg 800w,
/images/hero_large.jpg 1200w"
sizes="100vw"
src="/images/hero_medium.jpg"
alt="Mountain landscape">
When using a build tool or CMS that generates srcset values dynamically, add a check to filter out any entries where the computed width is zero or missing before rendering the attribute. This prevents the invalid markup from reaching production.
The <source> element is used inside <picture>, <audio>, or <video> elements to specify alternative media resources. When used inside a <picture> element, the srcset attribute is required and must contain one or more comma-separated image candidate strings. Each image candidate string consists of a URL and an optional descriptor — either a width descriptor like 400w or a pixel density descriptor like 2x.
This validation error typically occurs when:
- The srcset attribute is present but empty (srcset="").
- The attribute value contains only whitespace.
- The value is malformed or contains syntax errors (e.g., missing URLs, invalid descriptors).
- A dynamic templating system or CMS outputs the attribute with no value.
Why this matters
Browsers rely on the srcset attribute to select the most appropriate image to display based on the user’s device capabilities, viewport size, and network conditions. An empty or invalid srcset means the browser cannot perform this selection, potentially resulting in no image being displayed at all. This degrades the user experience, harms accessibility (screen readers and assistive technologies may encounter unexpected behavior), and violates the HTML specification as defined by the WHATWG living standard.
How to fix it
- Provide at least one valid image URL in the srcset attribute.
- Optionally add descriptors — use width descriptors (w) when combined with the sizes attribute, or pixel density descriptors (x) for fixed-size images.
- If you have no image to provide, remove the <source> element entirely rather than leaving srcset empty.
- Check dynamic output — if a CMS or templating engine generates the srcset value, add a conditional check to omit the <source> element when no images are available.
Examples
❌ Empty srcset attribute
<picture>
<source srcset="" type="image/webp">
<img src="photo.jpg" alt="A sunset over the ocean">
</picture>
This triggers the error because srcset is present but contains no image candidate strings.
❌ Invalid descriptor syntax
<picture>
<source srcset="photo.webp 400" type="image/webp">
<img src="photo.jpg" alt="A sunset over the ocean">
</picture>
This is invalid because 400 is not a recognized descriptor — it must be 400w or a density descriptor like 2x.
✅ Single image candidate
<picture>
<source srcset="photo.webp" type="image/webp">
<img src="photo.jpg" alt="A sunset over the ocean">
</picture>
A single URL without a descriptor is valid and serves as the default 1x candidate.
✅ Multiple candidates with width descriptors
<picture>
<source
srcset="photo-small.webp 400w, photo-medium.webp 800w, photo-large.webp 1200w"
sizes="(max-width: 600px) 400px, (max-width: 1000px) 800px, 1200px"
type="image/webp">
<img src="photo.jpg" alt="A sunset over the ocean">
</picture>
This provides three image candidates with width descriptors, allowing the browser to choose the best match based on the viewport and display density.
✅ Multiple candidates with pixel density descriptors
<picture>
<source srcset="photo.webp 1x, photo-2x.webp 2x" type="image/webp">
<img src="photo.jpg" alt="A sunset over the ocean">
</picture>
Pixel density descriptors tell the browser which image to use based on the device’s pixel ratio — 1x for standard displays and 2x for high-DPI (Retina) screens.
✅ Removing the source element when no image is available
If your application dynamically generates the srcset value and sometimes has no image to provide, omit the <source> element entirely:
<picture>
<img src="photo.jpg" alt="A sunset over the ocean">
</picture>
This is valid because the <img> element inside <picture> serves as the required fallback and can stand alone.
The srcset attribute supports two types of descriptors: width descriptors (e.g., 480w) and pixel density descriptors (e.g., 2x). These two types cannot be mixed, and the sizes attribute is specifically designed to work with width descriptors. The sizes attribute tells the browser how wide the image will be displayed at various viewport sizes, so the browser can then pick the best image from srcset based on the widths you’ve provided. If any candidate in srcset lacks a width descriptor — or uses a density descriptor instead — the browser can’t perform this calculation, and the HTML is invalid.
This matters for several reasons. First, browsers rely on the combination of sizes and width descriptors to make intelligent decisions about which image to download before the layout is computed. An invalid srcset can lead to the browser ignoring the entire attribute or selecting a suboptimal image, wasting bandwidth or displaying a blurry result. Second, standards compliance ensures consistent behavior across all browsers and devices.
A common mistake is specifying sizes while using density descriptors (1x, 2x) or providing bare URLs without any descriptor in srcset. If you want to use density descriptors, simply remove the sizes attribute. If you want responsive image selection based on viewport width, use width descriptors for every candidate.
Examples
Incorrect: Using density descriptors with sizes
<picture>
<source
srcset="image-small.jpg 1x, image-large.jpg 2x"
sizes="(max-width: 600px) 100vw, 50vw">
<img src="image-small.jpg" alt="A landscape photo">
</picture>
This triggers the error because 1x and 2x are density descriptors, but the sizes attribute requires width descriptors.
Incorrect: Missing descriptor on one candidate
<picture>
<source
srcset="image-small.jpg, image-large.jpg 800w"
sizes="(max-width: 600px) 100vw, 50vw">
<img src="image-small.jpg" alt="A landscape photo">
</picture>
Here, image-small.jpg has no descriptor at all. When sizes is present, every candidate must have a width descriptor.
Correct: All candidates use width descriptors with sizes
<picture>
<source
srcset="image-small.jpg 400w, image-large.jpg 800w"
sizes="(max-width: 600px) 100vw, 50vw">
<img src="image-small.jpg" alt="A landscape photo">
</picture>
Each image candidate now specifies a width descriptor (400w, 800w), which matches the requirement imposed by the sizes attribute.
Correct: Using density descriptors without sizes
If you only need density-based selection (e.g., for retina displays) and don’t need viewport-based sizing, remove the sizes attribute entirely:
<picture>
<source srcset="image-small.jpg 1x, image-large.jpg 2x">
<img src="image-small.jpg" alt="A landscape photo">
</picture>
Correct: Using srcset with width descriptors on <img>
The same rules apply when using srcset directly on an <img> element:
<img
srcset="photo-320.jpg 320w, photo-640.jpg 640w, photo-1024.jpg 1024w"
sizes="(max-width: 600px) 100vw, (max-width: 1200px) 50vw, 33vw"
src="photo-640.jpg"
alt="A mountain landscape">
Every candidate in srcset includes a width descriptor, making this fully valid alongside the sizes attribute. The src attribute serves as the fallback for browsers that don’t support srcset.
The sizes attribute and the srcset attribute work together as a system for responsive images. The srcset attribute provides the browser with a list of image candidates (typically at different widths or pixel densities), while the sizes attribute tells the browser how much space the image will occupy in the layout. The browser uses both pieces of information together to pick the most appropriate image file to download.
When you specify sizes without srcset, the attribute has no purpose. There’s only one image source (the src attribute), so the browser has nothing to choose from, and the layout hints provided by sizes are meaningless. The HTML specification explicitly states that the sizes attribute must not be present unless srcset is also specified with width descriptors (w). This isn’t just a stylistic concern — it signals to validators and other tools that the markup is incomplete or incorrect, which could indicate a copy-paste error or a missing attribute.
This issue commonly occurs when:
- The srcset attribute is accidentally removed during refactoring, leaving sizes orphaned.
- A developer adds sizes in preparation for responsive images but forgets to add srcset.
- Code is copied from a template and partially modified.
Examples
❌ Invalid: sizes without srcset
<img
src="photo.jpg"
sizes="(max-width: 600px) 100vw, 50vw"
alt="A landscape photo">
The sizes attribute is present, but there is no srcset to provide multiple image candidates. The browser has no use for the sizing information.
✅ Fix: Add a matching srcset attribute
<img
src="photo.jpg"
srcset="photo-400.jpg 400w, photo-800.jpg 800w, photo-1200.jpg 1200w"
sizes="(max-width: 600px) 100vw, 50vw"
alt="A landscape photo">
Now sizes tells the browser: “Below 600px viewports, the image fills 100% of the viewport width; otherwise it fills 50%.” The browser combines this with the width descriptors in srcset to select the best image.
✅ Fix: Remove sizes if you don’t need responsive images
<img
src="photo.jpg"
alt="A landscape photo">
If you only have a single image source and don’t need responsive behavior, simply remove the sizes attribute.
✅ Using sizes with <source> inside <picture>
The same rule applies to <source> elements inside a <picture> block:
<picture>
<source
srcset="photo-dark-400.jpg 400w, photo-dark-800.jpg 800w"
sizes="(max-width: 600px) 100vw, 50vw"
media="(prefers-color-scheme: dark)">
<img
src="photo.jpg"
srcset="photo-400.jpg 400w, photo-800.jpg 800w"
sizes="(max-width: 600px) 100vw, 50vw"
alt="A landscape photo">
</picture>
Each element that uses sizes also includes a corresponding srcset with width descriptors.
A note on srcset with pixel density descriptors
The sizes attribute is specifically designed for use with width descriptors (w) in srcset. If you’re using pixel density descriptors (x) instead, sizes is not needed:
<img
src="photo.jpg"
srcset="photo-2x.jpg 2x, photo-3x.jpg 3x"
alt="A landscape photo">
In this case, the browser selects based on device pixel ratio rather than viewport size, so sizes would be unnecessary.
The sizes attribute and the srcset attribute are designed to work as a pair for responsive image delivery. The srcset attribute provides the browser with a list of image files and their intrinsic widths (e.g., 480w, 800w), while the sizes attribute tells the browser how much space the image will occupy in the layout at different viewport sizes. The browser combines this information to select the most appropriate image file to download.
When sizes appears without srcset, it serves no purpose. The browser has only the single image specified in the src attribute, so there’s no decision to make about which image to load. The HTML specification explicitly requires that sizes must not be present unless srcset is also specified with width descriptors.
This error commonly occurs when a CMS or templating system outputs the sizes attribute by default, when srcset is accidentally removed during refactoring, or when developers copy markup snippets without including all the necessary attributes.
Beyond standards compliance, leaving orphaned sizes attributes creates confusing, harder-to-maintain code. Other developers (or your future self) may assume responsive images are configured when they aren’t, leading to wasted debugging time.
How to fix it
You have two options:
- Add a srcset attribute if you want the browser to choose from multiple image sizes based on viewport width. The srcset must use width descriptors (w) for sizes to be meaningful.
- Remove the sizes attribute if you don’t need responsive images and a single src is sufficient.
Note that sizes is also valid on <source> elements inside a <picture> element — the same rule applies there. Every <source> with a sizes attribute must also have a srcset attribute.
Examples
❌ Incorrect: sizes without srcset
<img
src="image.jpg"
sizes="(max-width: 600px) 480px, 800px"
alt="A mountain landscape">
The sizes attribute is present but there’s no srcset, so the browser has no alternative images to pick from.
✅ Correct: sizes paired with srcset
<img
src="image-800w.jpg"
srcset="image-480w.jpg 480w, image-800w.jpg 800w"
sizes="(max-width: 600px) 480px, 800px"
alt="A mountain landscape">
Here, srcset provides two images with their intrinsic widths. The sizes attribute tells the browser: “If the viewport is 600px or narrower, the image will display at 480px wide; otherwise, it will display at 800px wide.” The browser uses this information to download the most efficient file.
✅ Correct: removing sizes when responsive images aren’t needed
<img src="image.jpg" alt="A mountain landscape">
If a single image is sufficient, simply drop the sizes attribute.
❌ Incorrect: sizes on a <source> without srcset
<picture>
<source
media="(min-width: 800px)"
sizes="50vw">
<img src="fallback.jpg" alt="A sunset over the ocean">
</picture>
✅ Correct: sizes on a <source> with srcset
<picture>
<source
media="(min-width: 800px)"
srcset="wide-480w.jpg 480w, wide-960w.jpg 960w"
sizes="50vw">
<img src="fallback.jpg" alt="A sunset over the ocean">
</picture>
The <source> element now includes a srcset with width descriptors, giving the browser the candidate images it needs to make use of sizes.
A srcset attribute with width descriptors requires a sizes attribute on the img element.
When you use width descriptors (e.g., 400w, 800w) in the srcset attribute, the browser needs the sizes attribute to correctly select the appropriate image source based on the layout size in the viewport. Without sizes, the HTML is invalid, and the browser cannot resolve how large the image will be displayed.
Explanation
The srcset attribute allows you to provide multiple image sources for different screen conditions. There are two types of descriptors in srcset: width descriptors (e.g., 400w) and pixel density descriptors (e.g., 2x). When using width descriptors, you must include a sizes attribute to describe the expected display width of the image in CSS pixels. This helps browsers pick the best matching source.
Correct Usage Example
<img
src="image-400.jpg"
srcset="image-400.jpg 400w, image-800.jpg 800w"
sizes="(max-width: 600px) 100vw, 600px"
alt="Responsive example">
Incorrect Usage Example
<img
src="image-400.jpg"
srcset="image-400.jpg 400w, image-800.jpg 800w"
alt="Responsive example">
(Missing sizes attribute)
Explanation of the correct example:
- The srcset attribute lists two images with their respective pixel widths.
- The sizes attribute tells the browser to use 100vw (100% of the viewport width) if the viewport is 600px wide or less, and otherwise use 600px as the display width.
Ready to validate your sites?
Start your free trial today.