# Bad value X for attribute “sizes” on element “img”: 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-img-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/)

## 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

1. **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.
2. **Check for bare numbers** and add the appropriate unit (`px`, `vw`, `em`, etc.).
3. **Replace `%` with `vw`** if you intended a percentage of the viewport width.
4. **Fix any typos** in unit names.
5. **Ensure each comma-separated entry has exactly one length**, optionally preceded by a media condition in parentheses.
6. **Verify there's no space** between the number and its unit — `100vw` is correct, `100 vw` is not.

## Examples

### ❌ Bare number without a unit

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

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

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

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

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

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

```html
<img
  src="thumb-320.jpg"
  srcset="thumb-320.jpg 320w, thumb-640.jpg 640w"
  sizes="320pxx"
  alt="Thumbnail">
```

### ✅ Fixed: correct the unit

```html
<img
  src="thumb-320.jpg"
  srcset="thumb-320.jpg 320w, thumb-640.jpg 640w"
  sizes="320px"
  alt="Thumbnail">
```

### ✅ Multiple media conditions with a fallback

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

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