skip to content

picture and Art Direction

picture is for choosing a different image, not just a different size: cropping per breakpoint, or offering AVIF and WebP with a fallback. The standard question is picture versus srcset, and the answer turns on art direction versus resolution switching.

part ofHTMLoverview, primer and where to startread it →
on this pageshow

questions

5

In an HTML <picture> element, which child actually renders the image, and where do attributes like alt, width, height and class belong?

level: juniorimportance: must knowfreq 58%

answer

  1. the wrapper paints nothing
  2. sources are offers, one element renders
  3. fallback belongs at the end of the walk
  4. one image, therefore one alt
  5. delete it and the page shows nothing

basics

~20 s

The img renders; picture and source only offer candidates to it. So alt, width, height, class and loading all belong on the img, which must be the last child. A picture with no img displays nothing at all.

solid answer

~40 s

`<picture>` is a wrapper that carries no rendering of its own — think of it as a decision layer. The `<source>` elements are candidate offers, and the `<img>` is the element the browser actually paints, so it must be the last child and it is where every image attribute lives: `alt`, `width`, `height`, `class`, `loading`, `decoding`. When a `<source>` matches, the browser swaps the *file* the `<img>` displays; it does not swap the element. That is why a `<picture>` with sources but no `<img>` renders nothing — there is no image element to render — and why styling and accessibility work on the `<img>` rather than on the wrapper. The `<source>` elements do accept `width` and `height` so an art-directed crop can reserve its own aspect ratio, but they never take `alt`.

go deeper

for a junior

Know the shape by heart: sources first, one img last, alt on the img. Be able to say out loud that removing the img makes the whole thing render nothing.

for a middle

Explain why the ordering follows from first-match selection, and place each attribute correctly — srcset (not src) on source, loading and decoding on img, width and height on both when crops differ in shape.

for a senior

Point out the accessibility consequence: one alt covers every candidate, so crops that carry different information are a content problem no markup fixes. Watch for wrappers that get the class the image needed.

for a principal

Set the component contract so this cannot be got wrong — a single image component that always emits the img, forbids alt on the wrapper, and requires dimensions per candidate, rather than leaving the content model to each author.

## picture is a decision layer, not an image The most useful mental model for `<picture>` is that it renders nothing itself. It is a small container whose only job is to let the browser choose which *file* the `<img>` inside it will display. Everything about the image as a thing on the page — its accessible name, its intrinsic dimensions, its classes, its loading behaviour — belongs to the `<img>`. ```html <picture> <source type="image/avif" srcset="chart.avif"> <source type="image/webp" srcset="chart.webp"> <img src="chart.png" alt="Revenue rose from 2m to 9m between 2019 and 2024" width="800" height="450" class="report-figure" loading="lazy"> </picture> ``` The browser evaluates the `<source>` children in order, and if one matches it points the `<img>` at that file. The DOM element that ends up in the layout, in the accessibility tree, and in your stylesheet's reach is the `<img>` in every case. ## The last-child rule The content model of `<picture>` is: zero or more `<source>` elements, then exactly one `<img>`, last. This is not stylistic. Source selection is a first-match walk that stops when it reaches a match or runs out of sources, and the `<img>` is the terminal fallback in that walk. Putting the `<img>` first would mean the fallback is evaluated before the preferred candidates, which is exactly backwards. Omitting the `<img>` entirely is the failure mode people hit in practice, usually while refactoring. Nothing appears — not a broken-image icon, not the first source, nothing — because there is no image element to render and no `alt` text to expose. Assistive technology sees an empty container. ## Where each attribute goes **On the `<img>`:** `src` (the universal fallback file), `alt`, `width`, `height`, `class`, `id`, `loading`, `decoding`, `fetchpriority`, and its own `srcset`/`sizes` if you also want resolution switching in the fallback case. **On each `<source>`:** `srcset` (never `src` — that spelling belongs to `<source>` inside `<video>` and `<audio>`), plus optional `sizes`, `media`, `type`, `width` and `height`. **On `<picture>`:** essentially nothing image-specific. It takes global attributes, but there is no `alt`, no `src`, no `srcset` on the wrapper. The `alt` placement follows directly from the model: there is exactly one image being described, and which file was selected does not change what the image *means*. One `alt` on the `<img>` covers every candidate — which is also a design constraint worth noticing. If your desktop crop and your mobile crop convey materially different information, one `alt` string cannot honestly describe both, and that is a signal the art direction has gone too far. ## width and height on source A subtlety: when your art-directed crops have different aspect ratios, a single `width`/`height` pair on the `<img>` describes only the fallback. `<source>` accepts `width` and `height` for exactly this reason, so each candidate can declare its own intrinsic dimensions and the browser can reserve the right box before the bytes arrive. ## Styling and scripting reach the img Because the `<img>` is the rendered element, a CSS selector, a class, or a script that queries the image should target the `<img>`, not the `<picture>`. A common bug is attaching a class to `<picture>` and wondering why rules meant for the image do not apply the way they would on a bare `<img>` — the wrapper is a different element with its own default display behaviour. ## How to say it in an interview "`<picture>` and `<source>` decide *which file*; the `<img>` is the image. So the `<img>` is mandatory, it goes last, and every image attribute — starting with `alt` — lives on it." That single sentence covers the content model, the failure mode, and the accessibility consequence.

  • What actually happens if you leave the img out of a picture element?
    Nothing renders. The `<source>` elements are candidate declarations, not renderable content, so with no `<img>` there is no image element to paint and no alternative text to expose. Assistive technology encounters an empty container, and there is no broken-image indicator to make the mistake visible during a quick visual check.
  • You art-direct a hero into a 16:9 desktop crop and a 1:1 mobile crop. How do you keep the layout from shifting?
    Give each `<source>` its own `width` and `height` so every candidate declares its intrinsic aspect ratio, and keep `width`/`height` on the `<img>` describing the fallback file. Without per-source dimensions the browser reserves the fallback's box and then reflows when a differently-shaped crop arrives.
  • If the desktop and mobile crops show different subjects, what does that mean for alt?
    It means the art direction has gone too far. There is one `alt` for the whole `<picture>`, so if the crops convey different information no single string is honest for both. Either tighten the crops so they describe the same content, or accept that these are genuinely two different images serving two different purposes.

saying these in an interview costs you the question

  • put alt on the picture element itself
  • the matching source element is what renders
  • img is only needed for old browsers
  • source uses src like a video source
  • picture can hold several img elements as fallbacks

context

open as a page

When should you reach for HTML's <picture> element instead of putting srcset on a plain <img>?

level: middleimportance: must knowfreq 72%

basics

~20 s

Use picture when the image itself must change: a different crop per breakpoint, or an alternative file format the browser may not decode. Use srcset on a plain img when the same image only needs different pixel sizes and the browser should choose.

open as a page

What does the type attribute on a <source> inside an HTML <picture> do, and why does the order of the source elements matter when offering AVIF, WebP and JPEG?

level: middleimportance: should knowfreq 56%

basics

~20 s

type declares a candidate's MIME type, so a browser that cannot decode that format skips the source without downloading it. Selection stops at the first supported source, so sources must be listed best-format first, with the universally supported file on the trailing img.

open as a page

A page uses an HTML <picture> with several art-directed <source> elements, and the narrow mobile crop keeps appearing on wide desktop screens. Given how the browser selects a source, what are the likely causes?

level: seniorimportance: should knowfreq 42%

basics

~20 s

Almost always source order or overlapping media conditions: the walk stops at the first matching source, so a broad condition listed above a narrow one wins everywhere. Other causes are a source with no matching media at all, srcset misspelled as src, and markup order not matching the intended priority.

open as a page

Art direction with HTML's <picture> means shipping a separate crop per breakpoint. Across a large site, how do you decide which images earn that, and how do you keep the markup from becoming unmaintainable?

level: principalimportance: nice to knowfreq 30%

basics

~20 s

Reserve art direction for a small set of images where a single crop genuinely fails — heroes with an off-centre subject, images carrying text. Everything else gets one well-composed file with srcset. Generate the markup from a component so crops, formats and breakpoints come from one source.

open as a page