How to Do Art Direction with the picture Element Without Hurting LCP
This guide builds on Responsive Images with srcset and sizes, within Image & Media Optimization. srcset and sizes let the browser choose among resolutions of the same image. Art direction is a different need: showing a different image — usually a different crop — at different breakpoints. A wide landscape hero on desktop becomes unreadable when scaled to a phone; a tighter portrait crop focused on the subject works better. The <picture> element with <source media="…"> children expresses exactly that.
Done right, art direction improves both design and performance: phones download a smaller, purpose-cropped image rather than a scaled-down desktop file. Done wrong, it causes double downloads (when CSS hides one image and shows another), preloads of the wrong file, and layout shift when crops have different aspect ratios but the layout does not reserve the right space.
Rapid Diagnosis
- Check how mobile and desktop heroes differ today. Are they separate
<img>elements toggled with CSSdisplay: none? That downloads both in many cases. - Inspect
<picture>sources formediaandsrcset, and the fallback<img>forwidth/height. - Check the preload. If the hero is preloaded, does the preload match the source each breakpoint chooses?
- Check CLS on resize and load. Different aspect ratios need matching reserved space per breakpoint.
Root Cause Analysis
1. CSS-toggled duplicate images. Two <img> elements, one hidden per breakpoint — both may be downloaded, and the preload scanner fetches both.
2. Preload mismatch. A single preload for the desktop file makes mobile download it too, then the correct mobile crop.
3. Aspect-ratio mismatch. The <img> width/height describe one crop; at other breakpoints the actual image has a different ratio, so the reserved box is wrong.
4. No srcset within sources. Art-directed sources without srcset serve one resolution to all densities.
Step-by-Step Resolution
1. Express crops with picture and media queries
<picture>
<source media="(max-width: 699px)" type="image/avif"
srcset="/img/hero-portrait-480.avif 480w, /img/hero-portrait-800.avif 800w" sizes="100vw"
width="800" height="1000">
<source media="(min-width: 700px)" type="image/avif"
srcset="/img/hero-wide-1200.avif 1200w, /img/hero-wide-2000.avif 2000w" sizes="100vw"
width="2000" height="1125">
<img src="/img/hero-wide-1200.jpg" width="2000" height="1125" alt="Hiker on a ridge at sunrise"
fetchpriority="high">
</picture>
<!-- trade-off: width/height on <source> (supported in modern browsers) lets each
crop reserve its own aspect ratio; older browsers fall back to the img's
dimensions, so CSS aspect-ratio per breakpoint is a useful backup. -->
2. Preload per breakpoint with matching media
<link rel="preload" as="image" fetchpriority="high" media="(max-width: 699px)"
imagesrcset="/img/hero-portrait-480.avif 480w, /img/hero-portrait-800.avif 800w" imagesizes="100vw">
<link rel="preload" as="image" fetchpriority="high" media="(min-width: 700px)"
imagesrcset="/img/hero-wide-1200.avif 1200w, /img/hero-wide-2000.avif 2000w" imagesizes="100vw">
<!-- trade-off: the preload media queries must match the <source> media exactly,
or the browser preloads one file and renders another. Generate both from one
configuration. -->
Expected outcome: each device downloads exactly one crop at the right resolution, early.
3. Reserve the right box per breakpoint
.hero img { width: 100%; height: auto; }
@media (max-width: 699px) { .hero img { aspect-ratio: 4 / 5; } }
@media (min-width: 700px) { .hero img { aspect-ratio: 16 / 9; } }
/* trade-off: hard-coded ratios must change when designers change crops; keep
them next to the image configuration. */
4. Remove CSS-toggled duplicates
Replace any pair of hidden/shown images with a single <picture>.
Verification
At mobile and desktop widths, the Network panel should show a single hero request each, for the expected crop and resolution, initiated by the preload or parser at High priority. Layout Shift Regions should show no shifts when the image loads. LCP on mobile should improve if mobile previously downloaded desktop or duplicate files.
Worked Example: A Fashion Campaign Page
A campaign page used two <img> elements — a landscape desktop hero and a portrait mobile hero — hiding one with CSS. Mobile devices downloaded both (the preload scanner fetched both before CSS applied), 520KB in total, and LCP p75 on mobile was 3.3s. Replacing them with one <picture>, adding media-matched preloads and per-breakpoint aspect ratios cut mobile hero bytes to 95KB and LCP p75 to 2.2s, with a single layout-stable image at every width.
When Not to Art-Direct
Art direction adds assets to produce and maintain, so use it where composition genuinely fails at small sizes: wide scenes with small subjects, images with embedded text, banners with important details at the edges. For most product and article images, a single crop with srcset and object-position focal points is enough. Image CDNs with automatic smart cropping can also generate breakpoint crops from one master on request, which reduces manual work when art direction is needed at scale.
Testing Art-Directed Images Across Breakpoints
Art direction multiplies the states you must check. Automate it: a Playwright script that loads the page at each breakpoint you define (and one pixel either side of each media query boundary), records the hero request URL, the currentSrc, the rendered box and any layout shifts, and fails if a viewport downloads more than one hero file or if the rendered aspect ratio differs from the declared one. Boundary widths are where mismatches between preload media and source media most often hide — a preload for max-width: 699px and a source for max-width: 700px disagree at exactly 700 pixels, and someone's tablet will be that width.
Common Mistakes
- Forgetting
typeon sources. Without it, browsers may pick formats they cannot decode. - Ordering sources wrong. The first matching source wins; put the most specific media queries first.
- Preloading without media. Forces every device to download one crop.
- Changing crops without changing dimensions. Reserved space no longer matches.
Edge Cases
Combining format and art direction. Each crop needs its own sources per format (AVIF, WebP), multiplying entries; order by media first, then type.
Container-based layouts. media queries respond to the viewport, not the container; for components whose size depends on their container, sizes (and future container-aware features) are the only lever.
Dark mode crops. <source media="(prefers-color-scheme: dark)"> can serve dark-optimised images, with the same preload caveats.
Print. media="print" sources let you serve print-friendly images without affecting screen performance.
FAQ
Does picture slow down image discovery?
No — the preload scanner understands <picture> and evaluates media and type to pick a source during HTML parsing, just as with <img srcset>.
Can I use sizes inside each source?
Yes, and you should: each <source> can have its own srcset and sizes, so the browser picks the right resolution within the selected crop.
Is width/height on source elements supported?
Modern browsers support width and height on <source> within <picture> to describe each candidate's aspect ratio. For older browsers, CSS aspect-ratio per breakpoint provides the same protection.
Should the fallback img be the mobile or desktop crop?
The fallback is used when no source matches or <picture> is unsupported. Make it the most broadly appropriate crop (often desktop, in JPEG) and ensure its dimensions match.
How do I preload an art-directed hero in Next.js or Nuxt?
Framework image components may not handle art direction preloads automatically; add media-matched preload links in the document head yourself, generated from the same configuration as the <picture> sources.
Does art direction affect CLS on resize?
Resizing across a breakpoint swaps crops and may change layout, but CLS only counts unexpected shifts during normal page use, and window resizes are user-initiated. The important case is reserving the right box at load.
Related
- Fixing blurry images on high-DPI displays — resolution choices within each crop.
- CSS background images as LCP elements — moving heroes into picture.
- Using fetchpriority to prioritize the LCP image — prioritising the chosen crop.