HTML Guides for sizes
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.
The sizes attribute works together with the srcset attribute to help the browser choose the most appropriate image source for the current viewport and layout. Its value must follow a specific syntax: a comma-separated list where each entry is an optional media condition followed by a CSS length value. The final entry acts as a default and should be a length value without a media condition.
The value "auto" is not recognized as a valid CSS length or source size descriptor by the current HTML specification. While there is a newer sizes="auto" feature being developed for use specifically with loading="lazy" images, it is not yet universally part of the validated standard, and the W3C validator flags it as invalid. When the validator encounters auto, it expects a number (like 100vw or 50px) or a minus sign, but instead finds the letter “a”, producing this error.
Why This Matters
- Standards compliance: Using invalid attribute values means your HTML doesn’t conform to the specification, which could lead to unpredictable behavior across browsers.
- Responsive image loading: When sizes contains an invalid value, browsers may fall back to the default value of 100vw, which can cause them to download unnecessarily large images, hurting performance.
- Accessibility and tooling: Invalid HTML can cause issues with assistive technologies and automated tools that rely on well-formed markup.
How to Fix It
You have several options depending on your use case:
- Specify explicit sizes — Provide a valid source size list that describes how wide the image will be displayed at various viewport widths.
- Use a simple default — Set sizes to a single CSS length like "100vw" if the image always spans the full viewport width.
- Remove sizes entirely — If you don’t use srcset with width descriptors, the sizes attribute is unnecessary and can be removed.
- Use sizes="auto" with loading="lazy" — If you intentionally want the browser to determine sizes automatically for lazy-loaded images, be aware this is a newer feature that the validator may not yet support. You can suppress this specific warning if you’ve confirmed browser support meets your needs.
Examples
❌ Invalid: Using auto as the sizes value
<img
src="photo.jpg"
srcset="photo-400.jpg 400w, photo-800.jpg 800w, photo-1200.jpg 1200w"
sizes="auto"
alt="A scenic mountain view">
This triggers the error because auto is not a valid CSS length or source size descriptor.
✅ Fixed: Using a responsive source size list
<img
src="photo.jpg"
srcset="photo-400.jpg 400w, photo-800.jpg 800w, photo-1200.jpg 1200w"
sizes="(max-width: 600px) 100vw, (max-width: 1000px) 50vw, 33vw"
alt="A scenic mountain view">
This tells the browser: use 100% of the viewport width on screens up to 600px, 50% on screens up to 1000px, and 33% on larger screens. The browser then picks the best image from srcset.
✅ Fixed: Using a simple default size
<img
src="photo.jpg"
srcset="photo-400.jpg 400w, photo-800.jpg 800w, photo-1200.jpg 1200w"
sizes="100vw"
alt="A scenic mountain view">
If the image always fills the full viewport width, 100vw is a straightforward valid value.
✅ Fixed: Removing sizes when srcset is not used
<img src="photo.jpg" alt="A scenic mountain view">
If you’re not using srcset with width descriptors, the sizes attribute serves no purpose and can be safely removed. Without it, the browser defaults to 100vw when interpreting any srcset width descriptors.
✅ Fixed: Using a fixed pixel width
<img
src="photo.jpg"
srcset="photo-400.jpg 400w, photo-800.jpg 800w"
sizes="400px"
alt="A scenic mountain view">
If the image is always displayed at a fixed width regardless of viewport size, you can specify that width directly as a CSS length value.
The sizes attribute works together with the srcset attribute to help the browser choose the most appropriate image source before the page layout is calculated. It describes how wide the image will be displayed under various viewport conditions, allowing the browser to pick an optimally sized image from the candidates listed in srcset. According to the HTML specification, the value of sizes must be a valid source size list — a comma-separated set of media conditions paired with lengths, with a default length at the end. An empty string ("") does not satisfy this requirement and is therefore invalid.
When the browser encounters an empty sizes attribute, it cannot determine the intended display width of the image. This defeats the purpose of responsive images and may cause the browser to fall back to a default behavior (typically assuming 100vw), which could result in downloading an unnecessarily large image. Beyond the functional issue, an empty attribute signals a code quality problem — it often means a template is outputting the attribute even when no value has been configured.
Why this matters
- Standards compliance: The HTML specification explicitly requires sizes to be a non-empty, valid source size list when present. An empty value is a parse error.
- Performance: Without a proper sizes value, the browser cannot make an informed decision about which srcset candidate to download. This can lead to wasted bandwidth and slower page loads, especially on mobile devices.
- Code quality: Empty attributes clutter your markup and suggest missing configuration, making the code harder to maintain.
How to fix it
- Provide a valid sizes value that describes how wide the image will actually render at different viewport widths.
- Remove sizes entirely if you are not using width descriptors (w) in srcset. When srcset uses pixel density descriptors (1x, 2x), the sizes attribute is not needed.
- Remove both sizes and srcset if you don’t need responsive image selection at all.
Examples
❌ Empty sizes attribute
<img
src="photo.jpg"
srcset="photo-small.jpg 480w, photo-large.jpg 1200w"
sizes=""
alt="A mountain landscape">
The empty sizes="" triggers the validation error.
✅ Valid sizes with a single default value
If the image always takes up the full viewport width:
<img
src="photo.jpg"
srcset="photo-small.jpg 480w, photo-large.jpg 1200w"
sizes="100vw"
alt="A mountain landscape">
✅ Valid sizes with media conditions
If the image displays at different widths depending on the viewport:
<img
src="photo.jpg"
srcset="photo-small.jpg 480w, photo-medium.jpg 800w, photo-large.jpg 1200w"
sizes="(max-width: 600px) 100vw, (max-width: 1024px) 50vw, 33vw"
alt="A mountain landscape">
This tells the browser: use 100vw on viewports up to 600px, 50vw up to 1024px, and 33vw otherwise.
✅ Removing sizes when using density descriptors
When srcset uses density descriptors instead of width descriptors, sizes is not applicable and should be omitted:
<img
src="photo.jpg"
srcset="photo.jpg 1x, photo-2x.jpg 2x"
alt="A mountain landscape">
✅ Removing both attributes when not needed
If responsive image selection isn’t required, simply use a standard <img>:
<img src="photo.jpg" alt="A mountain landscape">
Common template fix
If your CMS or templating system conditionally outputs these attributes, ensure the sizes attribute is only rendered when it has a value. For example, in a template:
<!-- Before (always outputs sizes, even when empty) -->
<img src="photo.jpg" srcset="{{srcset}}" sizes="{{sizes}}" alt="{{alt}}">
<!-- After (only outputs sizes when it has a value) -->
<img src="photo.jpg" srcset="{{srcset}}" {{#if sizes}}sizes="{{sizes}}"{{/if}} alt="{{alt}}">
The srcset attribute allows you to provide multiple image sources so the browser can choose the most appropriate one based on the user’s device and viewport. There are two distinct modes for srcset:
- Width descriptor mode — Each candidate specifies the image’s intrinsic width using a w descriptor (e.g., 640w). This mode requires the sizes attribute so the browser knows how much space the image will occupy in the layout, enabling it to pick the best candidate.
- Density descriptor mode — Each candidate specifies a pixel density using an x descriptor (e.g., 2x). This mode does not use the sizes attribute; the browser simply matches candidates to the device’s pixel density.
These two modes are mutually exclusive. You cannot mix w and x descriptors in the same srcset, and you cannot use x descriptors (or bare URLs with no descriptor) when sizes is present. The HTML specification is explicit about this: if sizes is specified, all image candidate strings must include a width descriptor.
Why this matters
- Standards compliance: The WHATWG HTML Living Standard defines strict parsing rules for srcset. When sizes is present, the browser’s source selection algorithm expects width descriptors. Providing density descriptors or bare candidates in this context violates the spec and produces undefined behavior.
- Broken image selection: Browsers rely on the sizes attribute to calculate which w-described image best fits the current layout width. If you provide x descriptors alongside sizes, the browser may ignore the srcset entirely or fall back to the src attribute, defeating the purpose of responsive images.
- Accessibility and performance: Responsive images exist to serve appropriately sized files to different devices. An invalid srcset/sizes combination can result in oversized images being downloaded on small screens (wasting bandwidth) or undersized images on large screens (reducing visual quality).
How to fix it
You have two options:
- Keep sizes and switch to width descriptors — Replace every x descriptor (or missing descriptor) in srcset with the actual intrinsic pixel width of each image file, expressed with a w suffix.
- Remove sizes and keep density descriptors — If you only need to serve different resolutions for high-DPI screens at a fixed layout size, drop the sizes attribute and use x descriptors.
When using width descriptors, the value must match the image file’s actual intrinsic width in pixels. For example, if photo-640.jpg is 640 pixels wide, its descriptor should be 640w.
Examples
Invalid: sizes present with density descriptors
This triggers the error because 1x and 2x are density descriptors, but sizes requires width descriptors.
<img
src="photo-640.jpg"
srcset="photo-640.jpg 1x, photo-1280.jpg 2x"
sizes="(max-width: 600px) 100vw, 600px"
alt="A mountain landscape">
Invalid: sizes present with a bare candidate (no descriptor)
A candidate with no descriptor defaults to 1x, which is a density descriptor — still invalid when sizes is present.
<img
src="photo-640.jpg"
srcset="photo-640.jpg, photo-1280.jpg 2x"
sizes="(max-width: 600px) 100vw, 600px"
alt="A mountain landscape">
Fix: use width descriptors with sizes
Each candidate now specifies the intrinsic width of the image file. The browser uses the sizes value to determine which image to download.
<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="A mountain landscape">
Alternative fix: remove sizes and use density descriptors
If you don’t need the browser to choose images based on layout width — for example, the image always renders at a fixed CSS size — drop sizes and use x descriptors.
<img
src="photo-640.jpg"
srcset="photo-640.jpg 1x, photo-1280.jpg 2x"
alt="A mountain landscape">
Using width descriptors with source inside picture
The same rule applies to source elements inside a picture. If sizes is present, every candidate must use a w descriptor.
<picture>
<source
srcset="hero-480.webp 480w, hero-960.webp 960w, hero-1920.webp 1920w"
sizes="(max-width: 768px) 100vw, 50vw"
type="image/webp">
<img
src="hero-960.jpg"
srcset="hero-480.jpg 480w, hero-960.jpg 960w, hero-1920.jpg 1920w"
sizes="(max-width: 768px) 100vw, 50vw"
alt="A hero banner image">
</picture>
The sizes attribute works together with srcset to help the browser choose the most appropriate image source for the current layout. It accepts a comma-separated list of entries, where each entry is an optional media condition followed by a CSS length value (called a “source size value”). The browser evaluates these entries to determine the intended display width of the image before it downloads it. Valid length values include viewport-relative units like 100vw, absolute units like 472px, or calc() expressions like calc(100vw - 2rem).
The value auto was not part of the original HTML specification for the sizes attribute. However, the sizes="auto" value has been added to the HTML living standard specifically for use with lazy-loaded images (loading="lazy"). When both loading="lazy" and sizes="auto" are present, the browser can defer size calculation until layout time, since the image won’t be fetched immediately anyway. Some validators may not yet recognize this newer addition, or the error may appear because auto is being used without loading="lazy", or combined incorrectly with other size entries like sizes="auto, 100vw".
This validation error matters for several reasons. First, if the browser doesn’t understand the sizes value, it may fall back to a default of 100vw, which could cause it to download a larger image than necessary, hurting performance. Second, malformed attribute values can lead to unpredictable behavior across different browsers. Third, standards compliance ensures your markup works reliably now and in the future.
How to Fix
You have a few options depending on your situation:
-
Replace auto with a valid CSS length. If you know the intended display size of the image, specify it directly. This is the most broadly compatible approach.
-
Use sizes="auto" only with loading="lazy". If you want the browser to automatically determine the size, ensure you also include loading="lazy" and a width attribute on the image. Note that some validators may still flag this until they update their rules.
-
Remove auto from a comma-separated list. If you have something like sizes="auto, (max-width: 600px) 100vw, 50vw", remove the auto entry entirely.
Examples
Incorrect: Using auto without lazy loading
This triggers the validation error because auto is not a valid CSS length in the traditional sizes syntax.
<img
src="image.jpg"
srcset="image-small.jpg 300w, image-medium.jpg 600w, image-large.jpg 1000w"
sizes="auto, 100vw"
alt="A scenic mountain landscape"
>
Fixed: Using a valid CSS length value
Replace auto with a concrete size or a set of media-conditioned sizes.
<img
src="image.jpg"
srcset="image-small.jpg 300w, image-medium.jpg 600w, image-large.jpg 1000w"
sizes="(max-width: 472px) 100vw, 472px"
alt="A scenic mountain landscape"
>
In this example, when the viewport is 472 pixels wide or smaller, the image takes up the full viewport width (100vw). For wider viewports, the browser knows the image will display at 472px wide and selects the best source from srcset accordingly.
Fixed: Using auto with lazy loading
If you want the browser to determine the display size automatically, pair sizes="auto" with loading="lazy" and explicit dimensions.
<img
src="image.jpg"
srcset="image-small.jpg 300w, image-medium.jpg 600w, image-large.jpg 1000w"
sizes="auto"
width="600"
height="400"
loading="lazy"
alt="A scenic mountain landscape"
>
The width and height attributes help the browser reserve the correct space in the layout, and loading="lazy" allows the browser to defer both loading and size calculation until the image is near the viewport.
Fixed: Using calc() for dynamic sizing
If your image sits inside a container with padding, you can use calc() for a precise size hint.
<img
src="image.jpg"
srcset="image-small.jpg 300w, image-medium.jpg 600w, image-large.jpg 1000w"
sizes="calc(100vw - 2rem)"
alt="A scenic mountain landscape"
>
The sizes attribute tells the browser how wide an image will be displayed under different viewport conditions, allowing it to choose the best candidate from srcset before the page layout is calculated. Its value is a comma-separated list where each entry (except optionally the last) pairs a media condition with a CSS length. The final entry can be a bare length that serves as the default fallback. The full syntax looks like this:
(media-condition) length, (media-condition) length, fallback-length
Media conditions use the same grammar as CSS media queries. They must be enclosed in parentheses and can use logical operators like and, or, and not to combine sub-expressions. The slot size (length) that follows each condition must use a valid CSS length unit such as px, em, rem, vw, vh, vmin, vmax, or ch. Percentages are not valid in sizes slot lengths, and unitless numbers (other than 0) are also invalid.
This error matters for several reasons. First, if the browser cannot parse the sizes value, it falls back to a default of 100vw, which may cause it to download an unnecessarily large image — hurting performance and wasting bandwidth. Second, an invalid sizes attribute signals a misunderstanding of responsive image markup that could lead to layout or rendering issues. Third, standards-compliant HTML ensures consistent behavior across all browsers.
Common Parse Errors
Here are the most frequent mistakes that trigger this validation error:
- Missing parentheses around the media condition. Writing min-width: 600px instead of (min-width: 600px).
- Missing slot size after a condition. Each media condition must be followed by a length value, e.g., (min-width: 600px) 50vw. Writing (min-width: 600px), 100vw without a slot size after the condition is invalid — the browser interprets (min-width: 600px) alone as the entry.
- Using percentages as slot sizes. Values like 50% are not allowed; use viewport-relative units like 50vw instead.
- Unitless numbers. A slot size of 300 is invalid; it must be 300px or another valid length.
- Trailing or extra commas. A trailing comma after the last entry or double commas between entries will cause a parse error.
- Mixing up range syntax. Modern media query range syntax like (width >= 600px) is valid, but hybrid forms like (min-width <= 600px) are not. Use either the traditional (min-width: 600px) or the range form (width >= 600px).
- Invalid tokens or typos. Misspelled feature names (e.g., min-widht) or unsupported tokens will break parsing.
How to Fix
- Wrap every media condition in parentheses. Even simple conditions need them: (min-width: 600px).
- Follow each condition with a valid length. For example, (min-width: 600px) 50vw.
- End with a fallback length. The last item should be a bare length with no media condition, like 100vw.
- Use valid CSS length units for slot sizes — px, em, rem, vw, vh, etc. Never use %.
- Ensure your srcset uses w descriptors that match the intrinsic pixel widths of the image files, since sizes only works with width descriptors.
Examples
Incorrect: missing parentheses and missing slot size
The media condition lacks parentheses, and there is no slot size telling the browser how wide the image will be when the condition matches.
<img
src="photo-800.jpg"
srcset="photo-400.jpg 400w, photo-800.jpg 800w"
sizes="min-width: 600px, 100vw"
alt="A mountain landscape">
Correct: parentheses and slot size added
<img
src="photo-800.jpg"
srcset="photo-400.jpg 400w, photo-800.jpg 800w"
sizes="(min-width: 600px) 50vw, 100vw"
alt="A mountain landscape">
Incorrect: percentage used as slot size
<img
src="banner-1200.jpg"
srcset="banner-600.jpg 600w, banner-1200.jpg 1200w"
sizes="(min-width: 768px) 50%, 100%"
alt="Promotional banner">
Correct: viewport units instead of percentages
<img
src="banner-1200.jpg"
srcset="banner-600.jpg 600w, banner-1200.jpg 1200w"
sizes="(min-width: 768px) 50vw, 100vw"
alt="Promotional banner">
Incorrect: trailing comma
<img
src="icon-256.png"
srcset="icon-128.png 128w, icon-256.png 256w"
sizes="(min-width: 1024px) 128px, 64px,"
alt="App icon">
Correct: trailing comma removed
<img
src="icon-256.png"
srcset="icon-128.png 128w, icon-256.png 256w"
sizes="(min-width: 1024px) 128px, 64px"
alt="App icon">
Incorrect: invalid range syntax mixing traditional and modern forms
<img
src="hero-1600.jpg"
srcset="hero-800.jpg 800w, hero-1600.jpg 1600w"
sizes="(min-width <= 600px) 100vw, 50vw"
alt="Hero image">
Correct: using proper range syntax
<img
src="hero-1600.jpg"
srcset="hero-800.jpg 800w, hero-1600.jpg 1600w"
sizes="(width <= 600px) 100vw, 50vw"
alt="Hero image">
Multiple conditions with a fallback
This example shows a fully valid sizes attribute with several breakpoints, combining traditional and modern range syntax across entries.
<img
src="article-1200.jpg"
srcset="article-400.jpg 400w, article-800.jpg 800w, article-1200.jpg 1200w"
sizes="(min-width: 1200px) 33vw, (min-width: 768px) 50vw, 100vw"
alt="Article thumbnail">
Using calc() in slot sizes
You can use calc() for more precise slot sizes. This is fully valid in the sizes attribute.
<img
src="card-800.jpg"
srcset="card-400.jpg 400w, card-800.jpg 800w"
sizes="(min-width: 960px) calc(33.33vw - 2rem), calc(100vw - 2rem)"
alt="Product card">
The sizes attribute works alongside srcset to tell the browser how wide an image will be displayed at various viewport sizes, so the browser can choose the most appropriate image source before the page layout is computed. The attribute value is a comma-separated list where each entry consists of an optional media condition followed by a source size value (a CSS length). The final entry in the list acts as the default size and should not include a media condition.
When the browser parses the sizes attribute and encounters an empty entry — meaning there is nothing meaningful between two commas or after a trailing comma — it cannot resolve that entry to a valid source size. The HTML living standard’s parsing algorithm treats this as an error. While most browsers will silently ignore the empty entry and still render the image, the malformed attribute can lead to unexpected behavior and indicates a code quality issue that should be addressed.
Common causes of this error include:
- A trailing comma at the end of the sizes value (e.g., "100vw, 50vw, ").
- Double commas in the middle of the list (e.g., "100vw, , 50vw").
- Dynamically generated values where a template or CMS outputs a comma even when a size entry is conditionally omitted.
Fixing the issue is straightforward: ensure every comma in the list separates two valid source size entries, and that the list neither begins nor ends with a comma.
Examples
Trailing comma (invalid)
The most common cause — a comma after the last entry creates an empty source size:
<img
src="photo.jpg"
alt="A mountain landscape"
sizes="(min-width: 1200px) 800px, (min-width: 600px) 400px, 100vw, "
srcset="photo-800.jpg 800w, photo-400.jpg 400w, photo-200.jpg 200w">
Trailing comma fixed
Remove the trailing comma so the list ends with a valid entry:
<img
src="photo.jpg"
alt="A mountain landscape"
sizes="(min-width: 1200px) 800px, (min-width: 600px) 400px, 100vw"
srcset="photo-800.jpg 800w, photo-400.jpg 400w, photo-200.jpg 200w">
Double comma in the middle (invalid)
A double comma creates an empty entry between two valid sizes:
<img
src="banner.jpg"
alt="Promotional banner"
sizes="(min-width: 1024px) 960px, , 100vw"
srcset="banner-960.jpg 960w, banner-480.jpg 480w">
Double comma fixed
Remove the extra comma so each entry is separated by exactly one comma:
<img
src="banner.jpg"
alt="Promotional banner"
sizes="(min-width: 1024px) 960px, 100vw"
srcset="banner-960.jpg 960w, banner-480.jpg 480w">
Dynamically generated sizes with an empty entry (invalid)
Templates or CMS platforms sometimes output commas for entries that are conditionally empty:
<img
src="hero.jpg"
alt="Hero image"
sizes="(min-width: 1400px) 1200px, , (min-width: 768px) 700px, 100vw"
srcset="hero-1200.jpg 1200w, hero-700.jpg 700w, hero-350.jpg 350w">
Dynamically generated sizes fixed
Ensure the template logic only outputs a comma when a valid entry follows:
<img
src="hero.jpg"
alt="Hero image"
sizes="(min-width: 1400px) 1200px, (min-width: 768px) 700px, 100vw"
srcset="hero-1200.jpg 1200w, hero-700.jpg 700w, hero-350.jpg 350w">
If your sizes attribute is built dynamically, consider filtering out empty values before joining them with commas, or trimming trailing commas from the final output. A well-formed sizes attribute should always consist of one or more valid entries separated by single commas, with the last entry serving as the default source size (typically something like 100vw).
The sizes and srcset attributes work together to enable responsive images, but they serve distinct roles and use different syntax. The srcset attribute lists available image files along with their intrinsic widths using the w descriptor (e.g., 800w means the image file is 800 pixels wide). The sizes attribute, on the other hand, tells the browser how wide the image will actually be rendered in the layout, using standard CSS length units. The browser combines this information — knowing which files are available and how large the image will appear — to choose the most efficient file to download.
A common mistake is mixing up these two syntaxes, typically by copying a width descriptor like 860w from srcset and placing it into sizes. Since w is not a CSS unit, the validator rejects it. This matters because an invalid sizes value prevents the browser from correctly calculating which image source to use, potentially causing it to download an unnecessarily large image (wasting bandwidth) or a too-small image (resulting in poor quality).
How the sizes attribute works
The sizes attribute accepts a comma-separated list of media conditions paired with CSS lengths, plus an optional default length at the end. Each entry follows the pattern (media-condition) length. The browser evaluates the conditions in order and uses the length from the first matching condition. If none match, it uses the final default value.
Valid CSS length units include px, em, rem, vw, vh, ch, cm, mm, in, pt, pc, and CSS calc() expressions. You can combine units with calc() for more precise sizing — for example, calc(100vw - 2rem).
Examples
❌ Incorrect: using w in sizes
This triggers the validation error because 860w is a srcset width descriptor, not a CSS length:
<img
alt="A landscape photo"
sizes="860w"
srcset="photo-small.jpg 430w, photo-large.jpg 860w"
src="photo-large.jpg">
✅ Correct: using px in sizes
Replace the w value with a CSS length that reflects the image’s actual display size:
<img
alt="A landscape photo"
sizes="860px"
srcset="photo-small.jpg 430w, photo-large.jpg 860w"
src="photo-large.jpg">
✅ Correct: responsive sizes with media conditions
Use media conditions to specify different display sizes at different viewport widths:
<img
alt="A landscape photo"
sizes="(min-width: 1024px) 860px, (min-width: 568px) 430px, 100vw"
srcset="photo-small.jpg 430w, photo-large.jpg 860w"
src="photo-large.jpg">
This tells the browser:
- On viewports 1024px and wider, the image displays at 860px wide.
- On viewports 568px and wider, the image displays at 430px wide.
- On smaller viewports, the image fills the full viewport width (100vw).
✅ Correct: using calc() in sizes
When the image width depends on padding or margins, calc() provides precise sizing:
<img
alt="A landscape photo"
sizes="(min-width: 768px) calc(50vw - 2rem), calc(100vw - 1rem)"
srcset="photo-small.jpg 400w, photo-medium.jpg 800w, photo-large.jpg 1200w"
src="photo-medium.jpg">
Key takeaways
- The w descriptor belongs only in srcset, where it describes the intrinsic width of each image file.
- The sizes attribute uses CSS length units (px, vw, em, calc(), etc.) to describe how wide the image will appear on screen.
- If your image always displays at a fixed width, a simple value like sizes="300px" is sufficient.
- If your image width varies by viewport, use media conditions with appropriate CSS lengths to give the browser the information it needs to select the best source.
How the sizes Attribute Works
The sizes attribute works alongside srcset to enable responsive images. When you provide srcset with width descriptors (e.g., 400w, 800w), the browser needs to know how wide the image slot will actually be on screen so it can pick the best candidate. That’s what sizes provides — a comma-separated list of size descriptors that tell the browser the rendered width of the image under various viewport conditions.
Each entry in the list follows this pattern:
- Optional media condition followed by a CSS length: (max-width: 600px) 100vw
- A final fallback length with no media condition: 33vw
The browser evaluates media conditions from left to right and uses the length from the first matching condition. If no condition matches, the fallback is used.
Why This Error Occurs
The validator checks that every length token in sizes uses one of the recognized CSS absolute or relative length units: em, ex, ch, rem, cap, ic, vw, vh, vmin, vmax, cm, mm, q, in, pc, pt, px, and their small/large/dynamic viewport variants (svw, lvw, dvw, svh, lvh, dvh, svi, lvi, dvi, svb, lvb, dvb, svmin, lvmin, dvmin, svmax, lvmax, dvmax).
Percentages (%) are not allowed. This is a common point of confusion — while % is valid in most CSS contexts, the sizes attribute explicitly forbids it because a percentage would be ambiguous (percentage of what?). The vw unit is typically the correct replacement when you want to express a fraction of the viewport width.
Here are the most common mistakes that trigger this error:
- Missing units: sizes="100" — a bare number has no meaning without a unit.
- Using percentages: sizes="50%" — use 50vw instead.
- Typos in unit names: 100pxx, 100vws, 50 vw (with a space between number and unit).
- Multiple lengths in a single entry: sizes="(min-width: 800px) 50vw 400px" — each entry must contain exactly one length.
- Using calc() incorrectly: While calc() is valid in sizes, the expressions inside it must also use valid units.
Why It Matters
When the sizes value is malformed, browsers fall back to a default of 100vw, which means every image is treated as if it spans the full viewport width. This defeats the purpose of responsive images — the browser may download unnecessarily large files on small screens, wasting bandwidth and slowing page loads. Valid sizes values are essential for proper image optimization.
Additionally, invalid HTML can cause unpredictable behavior across different browsers and versions. Standards-compliant markup ensures consistent rendering and forward compatibility.
How to Fix It
- Find the position indicated in the error message (the “at Z” part) — this tells you exactly where in the sizes string the invalid token was found.
- Check for bare numbers and add the appropriate unit (px, vw, em, etc.).
- Replace % with vw if you intended a percentage of the viewport width.
- Fix any typos in unit names.
- Ensure each comma-separated entry has exactly one length, optionally preceded by a media condition in parentheses.
- Verify there’s no space between the number and its unit — 100vw is correct, 100 vw is not.
Examples
❌ Bare number without a unit
<img
src="photo-400.jpg"
srcset="photo-400.jpg 400w, photo-800.jpg 800w"
sizes="(max-width: 600px) 100, 400"
alt="A landscape photo">
✅ Fixed: add vw and px units
<img
src="photo-400.jpg"
srcset="photo-400.jpg 400w, photo-800.jpg 800w"
sizes="(max-width: 600px) 100vw, 400px"
alt="A landscape photo">
❌ Using invalid percentage
<img
src="banner-800.jpg"
srcset="banner-800.jpg 800w, banner-1600.jpg 1600w"
sizes="(max-width: 700px) 100%, 80%"
alt="Promotional banner">
✅ Fixed: replace % with vw
<img
src="banner-800.jpg"
srcset="banner-800.jpg 800w, banner-1600.jpg 1600w"
sizes="(max-width: 700px) 100vw, 80vw"
alt="Promotional banner">
❌ Multiple lengths in one entry
<img
src="hero-640.jpg"
srcset="hero-640.jpg 640w, hero-1280.jpg 1280w"
sizes="(min-width: 800px) 50vw 400px, 100vw"
alt="Hero image">
✅ Fixed: one length per entry, separated by commas
<img
src="hero-640.jpg"
srcset="hero-640.jpg 640w, hero-1280.jpg 1280w"
sizes="(min-width: 800px) 50vw, 100vw"
alt="Hero image">
❌ Typo in unit name
<img
src="thumb-320.jpg"
srcset="thumb-320.jpg 320w, thumb-640.jpg 640w"
sizes="320pxx"
alt="Thumbnail">
✅ Fixed: correct the unit
<img
src="thumb-320.jpg"
srcset="thumb-320.jpg 320w, thumb-640.jpg 640w"
sizes="320px"
alt="Thumbnail">
✅ Multiple media conditions with a fallback
<img
src="photo-640.jpg"
srcset="photo-640.jpg 640w, photo-960.jpg 960w, photo-1280.jpg 1280w"
sizes="(min-width: 1200px) 800px, (min-width: 800px) 60vw, 90vw"
alt="Landscape photo">
✅ Using calc() with valid units
<img
src="article-img-400.jpg"
srcset="article-img-400.jpg 400w, article-img-800.jpg 800w"
sizes="(min-width: 960px) calc(50vw - 2rem), 100vw"
alt="Article illustration">
The calc() function is valid inside sizes and is useful when the image width depends on a combination of viewport size and fixed spacing like padding or margins. Just make sure every value inside calc() also uses valid units.
The sizes attribute tells the browser how wide an image will be displayed at different viewport sizes, so it can choose the best candidate from srcset. It only applies when srcset uses width descriptors (e.g., 480w, 800w). The value is a comma-separated list where:
- Each entry (except the last) is a media condition in parentheses followed by a CSS length — for example, (min-width: 800px) 50vw.
- The final entry is a fallback length with no media condition — for example, 100vw.
The browser evaluates the media conditions from left to right and uses the length from the first one that matches. If none match, it uses the fallback.
The media condition syntax mirrors CSS media queries but without the @media keyword. You can use logical operators like and, or, and not, and features like min-width, max-width, orientation, etc.
Why This Error Occurs
The validator parses the sizes value according to the HTML living standard and CSS Media Queries specification. A parse error is triggered when the value doesn’t conform to the expected grammar. Common causes include:
- Missing parentheses around the media condition: min-width: 600px 50vw instead of (min-width: 600px) 50vw.
- Missing length after a media condition: (min-width: 800px) with no length following it.
- Invalid or missing units on the length: 50 instead of 50vw, 50px, or 50rem.
- Trailing commas or extra separators: (min-width: 600px) 50vw, , 100vw.
- Invalid media feature syntax: typos like (minwidth: 600px) or using unsupported tokens.
- Using sizes with pixel-density descriptors: when srcset uses 1x, 2x instead of width descriptors, the sizes attribute is meaningless and can confuse validators.
Why It Matters
- Browser image selection: Browsers rely on a correctly parsed sizes value to pick the optimal image from srcset. A malformed value causes the browser to fall back to a default size (typically 100vw), which can result in downloading unnecessarily large images on small screens or blurry images on large screens.
- Standards compliance: Invalid sizes values violate the HTML specification and may behave unpredictably across different browsers.
- Performance: Correct sizes values are essential for responsive image optimization. Without them, you lose the bandwidth savings that srcset with width descriptors is designed to provide.
How to Fix It
- Wrap every media condition in parentheses: (min-width: 600px), not min-width: 600px.
- Always include a valid CSS length after each condition: (min-width: 600px) 50vw, not just (min-width: 600px).
- End with a fallback length that has no condition: 100vw.
- Use valid CSS length units: vw, px, em, rem, or calc() expressions.
- Remove trailing or duplicate commas.
- Omit sizes entirely if your srcset uses pixel-density descriptors (1x, 2x).
Examples
Incorrect: missing parentheses around the media condition
<img
src="photo-800.jpg"
srcset="photo-400.jpg 400w, photo-800.jpg 800w"
sizes="min-width: 600px 50vw, 100vw"
alt="A landscape photo">
Correct: parentheses added
<img
src="photo-800.jpg"
srcset="photo-400.jpg 400w, photo-800.jpg 800w"
sizes="(min-width: 600px) 50vw, 100vw"
alt="A landscape photo">
Incorrect: missing length after the media condition
<img
src="banner-800.jpg"
srcset="banner-400.jpg 400w, banner-800.jpg 800w"
sizes="(min-width: 700px), 100vw"
alt="A promotional banner">
The first entry (min-width: 700px) has no length value — the comma makes it look like a separate entry, but it’s incomplete.
Correct: length added after the condition
<img
src="banner-800.jpg"
srcset="banner-400.jpg 400w, banner-800.jpg 800w"
sizes="(min-width: 700px) 60vw, 100vw"
alt="A promotional banner">
Incorrect: using sizes with pixel-density descriptors
<img
src="avatar.jpg"
srcset="avatar@1x.jpg 1x, avatar@2x.jpg 2x"
sizes="(min-width: 600px) 80px, 40px"
alt="User avatar">
The sizes attribute is only meaningful with width descriptors (w). When srcset uses density descriptors (1x, 2x), omit sizes.
Correct: sizes removed for density descriptors
<img
src="avatar.jpg"
srcset="avatar@1x.jpg 1x, avatar@2x.jpg 2x"
alt="User avatar">
Incorrect: trailing comma
<img
src="hero-800.jpg"
srcset="hero-400.jpg 400w, hero-800.jpg 800w"
sizes="(min-width: 800px) 800px, 100vw,"
alt="Hero image">
Correct: trailing comma removed
<img
src="hero-800.jpg"
srcset="hero-400.jpg 400w, hero-800.jpg 800w"
sizes="(min-width: 800px) 800px, 100vw"
alt="Hero image">
Using sizes on a <source> inside <picture>
<picture>
<source
type="image/webp"
srcset="hero-480.webp 480w, hero-800.webp 800w, hero-1200.webp 1200w"
sizes="(min-width: 1200px) 1200px, (min-width: 800px) 800px, 100vw">
<img
src="hero-800.jpg"
srcset="hero-480.jpg 480w, hero-800.jpg 800w, hero-1200.jpg 1200w"
sizes="(min-width: 1200px) 1200px, (min-width: 800px) 800px, 100vw"
alt="Hero image">
</picture>
Using compound media conditions
You can combine conditions with and:
<img
src="photo-800.jpg"
srcset="photo-400.jpg 400w, photo-800.jpg 800w, photo-1200.jpg 1200w"
sizes="(min-width: 900px) and (orientation: landscape) 50vw, 100vw"
alt="A sample photo">
Full valid document
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Responsive Image Example</title>
</head>
<body>
<img
src="pic-800.jpg"
srcset="pic-400.jpg 400w, pic-800.jpg 800w"
sizes="(min-width: 600px) 50vw, 100vw"
alt="A picture demonstrating valid sizes usage">
</body>
</html>
The sizes attribute tells the browser how wide an image will be displayed at various viewport sizes, so it can choose the best candidate from srcset before the CSS has loaded. Each entry in the sizes list is either a media condition paired with a CSS length, or a bare fallback length at the end. The HTML specification requires these lengths to be valid CSS <length> values, which means a number followed by a recognized unit. The full list of accepted units includes px, em, ex, ch, rem, vw, vh, vmin, vmax, cm, mm, in, pt, pc, and newer viewport units like svw, lvw, dvw, svh, lvh, dvh, and others.
The calc() function is also permitted, which lets you combine units — for example, calc(100vw - 2rem).
Why this matters
The sizes attribute is parsed before layout occurs, meaning the browser relies on it being syntactically correct to make smart download decisions. An invalid value forces the browser to fall back to a default size (typically 100vw), which can lead to downloading images that are far too large or too small. Beyond performance, an invalid sizes value violates the HTML specification, and some browsers may handle the malformed input inconsistently, leading to unpredictable behavior across devices.
Common mistakes
- Missing unit entirely: Writing 800 instead of 800px. Bare numbers without units are not valid CSS lengths (the only exception in CSS is 0, but even 0 should have a unit in sizes for clarity).
- Using percentages: Writing 50% instead of 50vw. Percentages are not allowed in sizes because the browser hasn’t performed layout yet and doesn’t know what the percentage would be relative to. Use viewport units like vw instead.
- Typos or extra characters: A stray character, misplaced comma, or missing whitespace can shift the parser’s position and cause it to find unexpected tokens where it expects a unit.
- Using auto on <source>: The auto keyword for sizes is only valid on <img> elements (and requires the loading="lazy" attribute). Using it on <source> will trigger a validation error.
How to fix it
- Find the position indicated in the error message (“at Z”) to locate the problematic value.
- If the value is a bare number, append the correct unit (e.g., change 600 to 600px).
- If the value uses %, replace it with a viewport-relative unit like vw.
- Ensure commas separate each media-condition/length pair, and that the list ends with a fallback length.
Examples
Adding a missing unit
The value 800 in the sizes attribute is not a valid CSS length because it has no unit.
<!-- ❌ Invalid: "800" is missing a unit -->
<img
src="hero-800.jpg"
srcset="hero-800.jpg 800w, hero-1200.jpg 1200w"
sizes="(min-width: 900px) 800, 100vw"
alt="Hero image">
<!-- ✅ Valid: "800px" has a proper unit -->
<img
src="hero-800.jpg"
srcset="hero-800.jpg 800w, hero-1200.jpg 1200w"
sizes="(min-width: 900px) 800px, 100vw"
alt="Hero image">
Replacing a percentage with a viewport unit
Percentages are not permitted in sizes. Use vw to express a width relative to the viewport.
<!-- ❌ Invalid: "50%" is not an allowed unit in sizes -->
<img
src="card-600.jpg"
srcset="card-600.jpg 600w, card-900.jpg 900w"
sizes="50%"
alt="Product card">
<!-- ✅ Valid: "50vw" means 50% of the viewport width -->
<img
src="card-600.jpg"
srcset="card-600.jpg 600w, card-900.jpg 900w"
sizes="50vw"
alt="Product card">
Fixing the issue on a <source> element
The same rules apply to <source> elements inside <picture>. Every length value needs a valid unit.
<!-- ❌ Invalid: "600" on <source> is missing a unit -->
<picture>
<source
type="image/webp"
srcset="hero-600.webp 600w, hero-1200.webp 1200w"
sizes="(min-width: 768px) 600, 100vw">
<img
src="hero-600.jpg"
srcset="hero-600.jpg 600w, hero-1200.jpg 1200w"
sizes="(min-width: 768px) 600px, 100vw"
alt="Hero image">
</picture>
<!-- ✅ Valid: both <source> and <img> use proper units -->
<picture>
<source
type="image/webp"
srcset="hero-600.webp 600w, hero-1200.webp 1200w"
sizes="(min-width: 768px) 600px, 100vw">
<img
src="hero-600.jpg"
srcset="hero-600.jpg 600w, hero-1200.jpg 1200w"
sizes="(min-width: 768px) 600px, 100vw"
alt="Hero image">
</picture>
Using calc() for mixed-unit sizes
You can use calc() to combine different units, which is especially useful when accounting for padding or margins.
<img
src="article-800.jpg"
srcset="article-800.jpg 800w, article-1200.jpg 1200w"
sizes="(min-width: 1024px) calc(100vw - 4rem), 100vw"
alt="Article image">
Multiple slots with different conditions
A well-formed sizes attribute with several media conditions, ending with a unitless-condition fallback length:
<picture>
<source
type="image/avif"
srcset="banner-480.avif 480w, banner-960.avif 960w, banner-1440.avif 1440w"
sizes="(min-width: 1200px) 960px, (min-width: 600px) 80vw, 100vw">
<img
src="banner-480.jpg"
srcset="banner-480.jpg 480w, banner-960.jpg 960w, banner-1440.jpg 1440w"
sizes="(min-width: 1200px) 960px, (min-width: 600px) 80vw, 100vw"
alt="Responsive banner">
</picture>
The general pattern is: sizes="(condition) length, (condition) length, fallback-length". Every length in that list — including the fallback — must be a valid CSS length with a unit or a calc() expression. If the validator error points to a specific character position, inspect that exact spot for a missing unit, a stray %, or malformed whitespace and replace it with one of the recognized units.
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.
The srcset attribute lets you provide multiple image sources so the browser can select the most appropriate one. There are two types of descriptors you can use in srcset: pixel density descriptors (e.g., 1x, 2x) and width descriptors (e.g., 400w, 800w). When you use pixel density descriptors, the browser already knows the relationship between each source — it simply picks the one matching the device’s pixel ratio. But width descriptors work differently. They tell the browser the intrinsic pixel width of each image file, and the browser then needs to know how wide the image will actually be rendered on screen to calculate which file is the best fit. That’s exactly what the sizes attribute provides.
The sizes attribute accepts a comma-separated list of media conditions paired with length values, plus a default length. For example, sizes="(max-width: 600px) 100vw, 50vw" tells the browser: “If the viewport is 600px wide or less, this image will occupy 100% of the viewport width; otherwise, it will occupy 50%.” Armed with this information and the width descriptors in srcset, the browser can do the math and download only the most suitable image — before CSS or layout has even been calculated.
Why this matters
- Standards compliance: The HTML specification requires sizes whenever srcset uses width descriptors. Omitting it produces invalid HTML.
- Correct image selection: Without sizes, browsers fall back to assuming the image will be 100vw wide, which often leads to downloading unnecessarily large images on desktop layouts where the image is much smaller than the full viewport.
- Performance: Serving oversized images wastes bandwidth and slows page load. A proper sizes attribute ensures the browser downloads the smallest sufficient image.
- Predictable behavior: Relying on the browser’s fallback assumption (100vw) makes your responsive images behave inconsistently and defeats the purpose of providing multiple candidates.
How to fix it
- Identify every img (or source) element that uses width descriptors in srcset.
- Determine how wide the image will be displayed at different viewport sizes. You can inspect this with your browser’s developer tools or by reviewing your CSS.
- Add a sizes attribute that describes those widths using media conditions and CSS length values like px, vw, em, or calc() expressions.
Examples
Incorrect — missing sizes with width descriptors
<img
src="photo-400.jpg"
srcset="photo-400.jpg 400w, photo-800.jpg 800w, photo-1200.jpg 1200w"
alt="A mountain landscape">
This triggers the validation error because the browser sees width descriptors (400w, 800w, 1200w) but has no sizes attribute to determine the image’s rendered width.
Correct — sizes attribute added
<img
src="photo-400.jpg"
srcset="photo-400.jpg 400w, photo-800.jpg 800w, photo-1200.jpg 1200w"
sizes="(max-width: 600px) 100vw, (max-width: 1000px) 50vw, 600px"
alt="A mountain landscape">
Here, the sizes attribute tells the browser:
- On viewports up to 600px wide, the image fills 100% of the viewport.
- On viewports between 601px and 1000px, the image fills 50% of the viewport.
- On larger viewports, the image is displayed at a fixed 600px width.
Correct — pixel density descriptors (no sizes needed)
<img
src="logo-1x.png"
srcset="logo-1x.png 1x, logo-2x.png 2x"
alt="Company logo">
When using pixel density descriptors (1x, 2x) instead of width descriptors, the sizes attribute is not required. The browser simply matches the descriptor to the device’s pixel ratio.
Correct — using sizes with a <picture> element
<picture>
<source
srcset="hero-400.webp 400w, hero-800.webp 800w"
sizes="(max-width: 800px) 100vw, 800px"
type="image/webp">
<img
src="hero-800.jpg"
srcset="hero-400.jpg 400w, hero-800.jpg 800w"
sizes="(max-width: 800px) 100vw, 800px"
alt="Hero banner">
</picture>
The sizes attribute is required on both the source and img elements when either uses width descriptors in its srcset.
Ready to validate your sites?
Start your free trial today.