# Bad value X for attribute “sizes” on element “source”: Expected units (one of “em”, “ex”, “ch”, “rem”, “cap”, “ic”, “vw”, “svw”, “lvw”, “dvw”, “vh”, “svh”, “lvh”, “dvh”, “vi”, “svi”, “lvi”, “dvi”, “vb”, “svb”, “lvb”, “dvb”, “vmin”, “svmin”, “lvmin”, “dvmin”, “vmax”, “svmax”, “lvmax”, “dvmax”, “cm”, “mm”, “q”, “in”, “pc”, “pt”, “px”) but found Y at Z.

> Canonical HTML version: https://rocketvalidator.com/html-validation/bad-value-x-for-attribute-sizes-on-element-source-expected-units-one-of-em-ex-ch-rem-cap-ic-vw-svw-lvw-dvw-vh-svh-lvh-dvh-vi-svi-lvi-dvi-vb-svb-lvb-dvb-vmin-svmin-lvmin-dvmin-vmax-svmax-lvmax-dvmax-cm-mm-q-in-pc-pt-px-but-found-y-at-z
> Attribution: Rocket Validator (https://rocketvalidator.com)
> License: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)

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

1. Find the position indicated in the error message ("at Z") to locate the problematic value.
2. If the value is a bare number, append the correct unit (e.g., change `600` to `600px`).
3. If the value uses `%`, replace it with a viewport-relative unit like `vw`.
4. 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.

```html
<!-- ❌ 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">
```

```html
<!-- ✅ 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.

```html
<!-- ❌ 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">
```

```html
<!-- ✅ 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.

```html
<!-- ❌ 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>
```

```html
<!-- ✅ 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.

```html
<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:

```html
<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.
