---
title: "What does it do?"
manual: "Imaginator"
version: "1.0"
permalink: "https://docs.typo3.org/permalink/schliesser/imaginator:introduction-what@1.0"
source: "Introduction/WhatDoesItDo.rst"
rendered: "2026-10-13T11:21:40+00:00"
---

# What does it do? {#introduction-what}

Imaginator renders responsive images without any per-image configuration. At
page-render time it emits a real `<picture>` / `<img>` carrying a
quantized **width-ladder** `srcset` plus `sizes="auto"`, so the
browser's preload scanner picks the correctly-sized candidate in one
round-trip. The `width` and `height` attributes are always emitted
from the largest ladder rung, so there is zero layout shift (CLS).

## How it works {#how-it-works}

**The width ladder.** Instead of generating a derivative for every width a
layout could ever request, Imaginator works from a fixed, configurable list of
rung widths. The default [ladder](https://docs.typo3.org/permalink/schliesser/imaginator:confval-conf-ladder@1.0) (
`320,420,560,740,980,1300,1720,2000,2560,3200,3840`) covers everything from
small phones to 4K (UHD) displays out of the box. Every rung becomes one
`srcset` candidate; its height follows from the aspect ratio. Rungs larger
than the source image (or [maxDimension](https://docs.typo3.org/permalink/schliesser/imaginator:confval-conf-maxdimension@1.0)) are
capped and deduplicated, so a small source never gets upscaled. Because any
requested width is quantized **up** to the nearest rung, at most one ladder of
derivatives ever exists per image and ratio, no matter how many different
layout widths the site renders it at.

The [\<i:image> ViewHelper](https://docs.typo3.org/permalink/schliesser/imaginator:usage-viewhelper@1.0) optionally takes either a
single aspect ratio or a **per-breakpoint ratio map** and turns it into the
markup. A single ratio renders an `<img>` with the full ladder; a map
renders a `<picture>` with one `<source>` per breakpoint, each its
own ladder — true **art direction** with no hand-written `media` queries.
Editors set that map per content element in the [aspect-ratio field](https://docs.typo3.org/permalink/schliesser/imaginator:editor@1.0), and the chosen [crop & focus area](https://docs.typo3.org/permalink/schliesser/imaginator:image-endpoint-crop@1.0) is
honoured server-side, so the subject stays in frame at every size.

**Pluggable processing.** The URLs in `srcset` come from a
[processor](https://docs.typo3.org/permalink/schliesser/imaginator:configuration-processors@1.0); the render layer is identical
whoever produces the pixels. You choose where the work happens:

-   **Async** (the default): a cold derivative is processed on first request via
    a signed endpoint, then served as a static file; the render itself stays
    cheap and processing is spread over real traffic.
-   **Sync**: derivatives are materialized at render time and written straight
    into `srcset` as static files (no PHP hop per image, higher cold-render
    cost).
-   **External** (e.g. imgproxy): `srcset` points straight at the provider, so
    the webserver never touches pixels. The lightest load on your TYPO3 server.

**Bounded and safe.** Every requested width is quantized **up** to a fixed
ladder rung. That bounds the set of processed files, and on the signed async
endpoint means only rung sizes ever verify, so an attacker cannot request
arbitrary dimensions.

## Why `sizes="auto"` is the new cool way {#introduction-sizes-auto}

A responsive `<img srcset="…">` only picks the right candidate if it also
knows **how wide it will be laid out**. Traditionally that meant hand-writing a
`sizes` attribute — a list of media-query/width pairs that *re-describes*
your CSS layout in the markup:

**The old way — a sizes list that duplicates the layout**

```html
<img srcset="img-320.jpg 320w, img-640.jpg 640w, img-1280.jpg 1280w"
     sizes="(min-width: 1200px) 760px, (min-width: 768px) 50vw, 100vw"
     alt="…">
```

That is brittle. The numbers are a guess, they have to be repeated for every
image, and the moment the CSS changes — a new grid, a wider container, a sidebar
that collapses — the `sizes` list is silently wrong and the browser
downloads the wrong size (usually too big). It is exactly the kind of
per-image configuration Imaginator exists to remove.

`sizes="auto"` flips this around. The browser already knows the final
laid-out width of the image from your CSS — so it just **uses it**, picking the
matching `srcset` candidate with no hand-written numbers at all:

**The new way — the browser reads the real layout width**

```html
<img srcset="img-320.jpg 320w, … img-3840.jpg 3840w"
     sizes="auto" loading="lazy" width="3840" height="2160" alt="…">
```

This is why it pairs perfectly with the width ladder: Imaginator emits the
candidates and lets the browser — which is the only party that actually knows
the rendered width — choose. No layout duplication, no drift when the design
changes, correct on every viewport and container. Because the value is resolved
during the browser's preload scan, the right image is fetched in the **first**
round-trip.

> [!NOTE]
> `sizes="auto"` is supported natively in Chrome/Edge (126+) and Firefox,
> and in Safari / iOS Safari from **version 27**. Older Safari/iOS treat the
> unknown value as `100vw` and fetch an oversized — but still sharp —
> candidate. To close that gap Imaginator ships a tiny vendored
> [Shopify/autosizes](https://github.com/Shopify/autosizes) polyfill that
> writes a concrete pixel `sizes` on those browsers. It is **never
> load-bearing** — sharpness comes from the server-rendered ladder, so the page
> works fully with JavaScript disabled. The polyfill is the *only* JavaScript
> the extension uses; see its [CSP note](https://docs.typo3.org/permalink/schliesser/imaginator:configuration-csp@1.0).
>
> `sizes="auto"` is spec-valid only on `loading="lazy"` images,
> which is exactly where Imaginator emits it — [priority/LCP images](https://docs.typo3.org/permalink/schliesser/imaginator:usage-priority@1.0) get an explicit `sizes="100vw"` instead.
