Come le immagini e i media causano il Layout Shift (e come risolverlo)

La guida completa per prevenire il CLS da immagini, video, iframe, immagini responsive e media embed

Arjen Karel Core Web Vitals Consultant
Arjen Karel - linkedin
Last update: 2026-04-08

Come le immagini e i media causano il Layout Shift (e come risolverlo)

Il Web Almanac 2025 quantifica ciò che continuo a vedere sul campo: il 62% delle pagine mobile ha almeno un'immagine senza larghezza e altezza esplicite. Questo rende i media senza dimensioni la causa numero uno del Cumulative Layout Shift sul web. E ognuno di questi shift è prevenibile con tecniche che esistono dal 2019.

Ultima revisione a cura di Arjen Karel nel marzo 2026

Il browser non sa quanto è grande la tua immagine

Ogni layout shift causato da un'immagine si riduce a una cosa. Il browser non sa quanto spazio riservare prima che l'immagine si carichi.

Quando il browser incontra un tag <img> senza dimensioni, non si ferma finché non conosce le dimensioni dell'immagine. No, semplicemente riserva uno spazio di 0x0 pixel. Poi l'immagine viene scaricata, il browser ricalcola il layout e tutto ciò che si trova sotto l'immagine salta verso il basso. Quel salto è il tuo CLS.

Come width e height prevengono il layout shift

L'unica soluzione per un layout shift è riservare lo spazio corretto. Il modo più semplice per farlo è semplicemente impostare la giusta larghezza e altezza (intrinseca) dell'immagine. Nel 2019 e nel 2020 tutti i principali browser hanno introdotto una funzionalità che ha cambiato il modo in cui funzionano gli attributi width e height. I browser ora li usano per calcolare un aspect ratio prima che l'immagine venga scaricata.

Quando scrivi questo:

<img src="hero.jpg" width="800" height="450" alt="Description">

Il browser genera internamente questo:

img[Attributes Style] {
    aspect-ratio: auto 800 / 450;
}

Per le immagini responsive, aggiungi questo CSS:

img {
    height: auto;
    max-width: 100%;
}

I browser non hanno bisogno di scaricare l'intero file dell'immagine per calcolare le dimensioni. Il browser conosce il rapporto e riserva lo spazio verticale. Il CSS si occupa della parte finale: il contenimento. height: auto calcola l'altezza dal rapporto. max-width: 100% impedisce all'immagine di superare il suo contenitore.

Cose che annullano la correzione

Gli attributi width e height sono tutto ciò che ti serve per evitare che le immagini causino layout shift. Ma ci sono ancora alcuni pattern comuni che annullano il lavoro e fanno sì che le immagini causino layout shift anche con dimensioni e CSS.

width:auto nel CSS

Questo è quello che vedo più spesso e quello che fa sprecare più tempo nel debugging. Lo sviluppatore imposta width e height su ogni immagine, fa tutto correttamente nell'HTML, ma da qualche parte nel file CSS c'è un width:auto extra per le immagini.

img {
    width: auto;
    height: auto;
    max-width: 100%;
}

Il problema è width: auto. Poiché il rapporto interno del browser ha la priorità CSS più bassa, qualsiasi regola lo sovrascrive. width: auto rimuove la larghezza che il browser stava usando per calcolare l'altezza. Entrambe le dimensioni diventano sconosciute. L'immagine viene renderizzata a 0x0 finché il file non viene scaricato e le dimensioni finali diventano note.

Impostare aspect-ratio nel CSS non risolve il problema. Con width: auto, il browser tratta inizialmente la larghezza come 0. Un aspect ratio calcolato da 0 produce comunque 0x0.

Ciò che rende questo problema difficile da individuare è la cache del browser. Se l'immagine è nella cache del browser, le dimensioni effettive sono disponibili immediatamente e non si verifica alcuno shift. Ho eseguito il debug di questo problema su decine di siti di clienti ed era sempre memorizzato nella cache sulla macchina dello sviluppatore.

La correzione:

img {
    height: auto;
    max-width: 100%;
}

Rimuovi width: auto. Mantieni height: auto e max-width: 100%. Questo è il pattern raccomandato da web.dev.

Controllo rapido: fai clic destro su qualsiasi immagine, ispezionala, guarda gli stili calcolati (computed). Se vedi width: auto, quello è il tuo problema. Per la procedura completa, vedi risolvere il layout shift causato da immagini auto-dimensionate.

Dimensioni errate dell'immagine

Ricordi l'aspect ratio generato internamente? Qui è dove le cose si fanno un po' tecniche. La parola chiave auto dice al browser: usa questo rapporto come placeholder, ma una volta che l'immagine reale si carica, passa alle dimensioni reali. Se imposti valori errati (width="4" height="3" su un'immagine 16:9), il browser riserva inizialmente uno spazio 4:3, per poi correggerlo a 16:9 quando l'immagine si carica. Quella correzione è un layout shift. Usa sempre le dimensioni in pixel effettive dell'immagine.

Quando CSS aspect-ratio è la scelta migliore

Gli attributi width/height sono l'approccio predefinito e sempre il migliore, ma a volte il tuo CMS non ti permette di aggiungere le dimensioni dell'immagine (e questo succede più spesso di quanto pensi!). In quel caso puoi controllare quanto spazio viene riservato usando il CSS aspect-ratio. Ad esempio, se la tua immagine hero ha la classe .hero, puoi riservare il suo spazio in questo modo:

img.hero {
    aspect-ratio: 16 / 9;
    width: 100%;
}

Funziona in tutti i browser moderni (Chrome 88+, Firefox 87+, Safari 15+) e su qualsiasi elemento, non solo immagini e video.

Video, iframe ed SVG

Video

Stesso problema, stessa correzione. Imposta width e height per corrispondere alla risoluzione del video:

<video src="demo.mp4" width="1280" height="720" autoplay muted loop></video>

Aggiungi height: auto; max-width: 100%; nel CSS. Una cosa a cui fare attenzione: imposta le dimensioni per corrispondere alla risoluzione del video, non all'immagine di poster. Se differiscono, otterrai uno shift all'avvio della riproduzione.

Iframe

A differenza delle immagini, gli iframe non calcolano un aspect ratio dai loro attributi. Senza dimensioni esplicite, il valore predefinito è 300x150 pixel. Per la maggior parte degli embed questo è sbagliato. Per gli iframe è meglio impostare l'aspect-ratio in questo modo:

.responsive-iframe {
    width: 100%;
    height: auto;
    aspect-ratio: 16 / 9;
}

Meglio ancora, non caricare affatto l'iframe. Per YouTube, Vimeo, Google Maps e gli embed social ho smesso di caricare gli iframe al caricamento della pagina anni fa. Mostra un'immagine placeholder statica con l'aspect ratio corretto. Quando l'iframe diventa visibile, JavaScript lo scambia con l'iframe reale. Lo shift derivante dallo scambio avviene entro 500 ms dall'input dell'utente ed è escluso dal CLS by design.

Per i dettagli di implementazione, vedi embed YouTube perfetti e Google Maps senza perdere in PageSpeed.

SVG

Gli SVG caricati tramite <img> hanno bisogno di width e height sul tag, proprio come le immagini raster. Gli elementi <svg> inline hanno bisogno di un viewBox con aspect-ratio in CSS. Senza nessuno dei due, il valore predefinito è 300x150.

Immagini responsive

Mantieni lo stesso rapporto tra tutte le sorgenti srcset

Tutte le immagini in un srcset devono condividere lo stesso aspect ratio. Se lo fanno, un singolo set di width/height sull'<img> è sufficiente:

<img
    src="hero-800.jpg"
    srcset="hero-400.jpg 400w, hero-800.jpg 800w, hero-1200.jpg 1200w"
    sizes="(max-width: 600px) 100vw, 800px"
    width="800" height="450"
    alt="Hero image">

800:450 è lo stesso rapporto su tutte e tre le varianti. Indipendentemente da quale il browser scelga, lo spazio riservato è corretto. Se hai bisogno di rapporti diversi, usa invece <picture> con elementi <source>.

Art direction: rapporti diversi per breakpoint

Quando offri ritagli (crop) diversi a diverse larghezze di viewport, dovrai usare l'elemento <picture>. Imposta width e height su ciascun <source>:

<picture>
    <source
        media="(max-width: 799px)"
        srcset="hero-mobile.jpg"
        width="480" height="600">
    <source
        media="(min-width: 800px)"
        srcset="hero-desktop.jpg"
        width="1200" height="400">
    <img
        src="hero-desktop.jpg"
        width="1200" height="400"
        alt="Product hero image">
</picture>

Chrome e Safari prelevano le dimensioni corrette da qualsiasi <source> sia attivo. Firefox non lo fa (bug 1694741). Usa sempre le dimensioni di fallback dell'<img>. Soluzione alternativa (workaround): fai corrispondere i breakpoint con le media query CSS.

picture img {
    width: 100%;
    height: auto;
}
@media (max-width: 799px) {
    picture img {
        aspect-ratio: 480 / 600;
    }
}
@media (min-width: 800px) {
    picture img {
        aspect-ratio: 1200 / 400;
    }
}

Se tutti i tuoi ritagli condividono lo stesso rapporto, il bug di Firefox non è un problema.

Contenitori fissi, caroselli e contenimento

object-fit per contenitori a dimensione fissa

Griglie di schede prodotto in cui ogni scheda ha la stessa altezza ma le immagini hanno rapporti diversi. Blocca il contenitore, lascia che l'immagine lo riempia:

.product-image {
    width: 100%;
    aspect-ratio: 1 / 1;
    object-fit: cover;
    object-position: center;
}
<img
    src="product.jpg"
    width="400" height="600"
    class="product-image"
    alt="Product name">

La dimensione è bloccata prima che l'immagine si carichi. Questo sostituisce anche le immagini di background CSS. Le immagini di background non possono avere il lazy loading, il preload scanner non le trova e non puoi usare fetchpriority. Un <img> con object-fit: cover ti dà tutti questi controlli.

Caroselli

Le transizioni delle slide che animano left, width o margin attivano il ricalcolo del layout. Poiché l'autoplay non è un input dell'utente, ogni shift contribuisce al CLS. Fissa il contenitore con un aspect-ratio fisso. Anima invece con transform: translateX(). I transform vengono eseguiti sulla GPU e non attivano mai il layout.

Contenimento per embed che non puoi controllare

Spazi pubblicitari, widget di terze parti, contenuti generati dagli utenti. Non controlli cosa renderizzano e non puoi ritagliarli. L'obiettivo realistico è minimizzare lo shift, non eliminarlo.

Inizia riservando lo spazio:

.ad-slot {
    min-height: 250px;
    contain: layout style;
}

Il min-height gestisce il grande vantaggio. Se l'annuncio si carica a 250px o meno, nessuno shift. Se si carica a 300px, ottieni uno shift di 50px invece di uno shift di 300px partendo da zero. Quella differenza è importante.

contain: layout fa qualcosa di diverso. Non impedisce al contenitore di crescere. Isola ciò che accade all'interno. Quando la rete pubblicitaria inietta script che causano il reflow dei propri contenuti (ridimensionamento di iframe, iniezione di nuovi elementi, ricalcolo del layout interno), quei ricalcoli rimangono all'interno del contenitore. Senza contenimento, ogni reflow interno all'annuncio attiva un ricalcolo del layout per l'intera pagina. Con esso, il browser salta tutto ciò che si trova al di fuori del box. Questo rende la pagina più reattiva mentre gli annunci si caricano.

contain: style impedisce ai contatori CSS e ad altri effetti collaterali di stile di fuoriuscire. Un'assicurazione a basso costo.

Per il valore min-height, controlla le dimensioni delle creatività più comuni del tuo provider pubblicitario e scegli quella che copre la maggior parte delle impression. Se il 90% dei tuoi annunci è di 250px e il 10% è di 300px, impostalo a 250px e accetta il piccolo shift occasionale. Impostarlo a 300px significa che il 90% dei caricamenti di pagina avrà 50px di spazio vuoto che collassa quando si carica un annuncio più piccolo. Anche quel collasso è un layout shift.

Non c'è una risposta perfetta per gli annunci. L'obiettivo è lo shift più piccolo possibile sul maggior numero di caricamenti di pagina.

Come trovare il CLS delle immagini

Non rileverai il CLS delle immagini in condizioni di navigazione normali. La cache del tuo browser ha già le dimensioni da una visita precedente, quindi lo shift non avviene mai. Per vedere ciò che vedono i tuoi utenti reali, apri i DevTools (F12), vai alla scheda Network e spunta "Disable cache". La cache è disabilitata solo mentre i DevTools sono aperti. In alternativa, usa una finestra in incognito.

Real User Monitoring

Inizia con CoreDash o un altro strumento RUM. I dati di attribuzione del CLS mostrano esattamente quali elementi si sono spostati. Naviga in CLS, guarda la tabella Element per l'attribuzione. Filtra per immagine e otterrai ogni elemento immagine interessato da layout shift, ordinato per impatto.

Chrome DevTools

Disabilita la cache nella scheda Network, imposta il throttling su Slow 4G, abilita gli screenshot, ricarica. Fai attenzione ai salti visivi. Poi apri il pannello Performance e cerca le voci "Layout Shift". Clicca su uno shift per vedere il nodo, il punteggio e se ha avuto un input utente recente.

Core Web Vitals Visualizer

L'estensione Core Web Vitals Visualizer evidenzia ogni layout shift con un overlay colorato. La uso come primo passo prima di aprire il pannello Performance. Ricarica con l'estensione attiva e vedrai esattamente cosa si è mosso.

Checklist rapida per correggere il CLS

Elemento Causa del CLS Correzione
<img> width/height mancanti Aggiungi width e height; usa height: auto; max-width: 100%; nel CSS
<img> width: auto nel CSS che sovrascrive le dimensioni Rimuovi width: auto; mantieni solo height: auto
<img> Valori errati di width/height Usa le dimensioni in pixel effettive dell'immagine
<video> width/height mancanti Aggiungi width e height corrispondenti alla risoluzione del video
<iframe> 300x150 predefinito aspect-ratio: 16 / 9; width: 100%; nel CSS o il facade pattern
<picture> Rapporti diversi per sorgente (bug di Firefox) Imposta width/height su ciascun <source>; aggiungi fallback con media query CSS
<img srcset> Rapporti misti nel srcset Stesso rapporto per tutte le sorgenti; imposta width/height sull'<img>
Lazy loading JS Placeholder 1x1 con rapporto errato Usa il loading="lazy" nativo o fai corrispondere il rapporto del placeholder
Carosello Autoplay + transizioni che attivano il layout Contenitore con aspect-ratio fisso; transform per le transizioni
SVG Nessuna dimensione integrata Width/height sull'<img> o viewBox + CSS aspect-ratio
Spazi pubblicitari / embed Dimensioni sconosciute min-height + contain: layout style

A che punto è il web sul CLS delle immagini

I numeri del Web Almanac 2025:

  • Il 62% delle pagine mobile ha almeno un'immagine senza dimensioni. In calo rispetto al 66% del 2024. Ancora la maggioranza.
  • Il 65% delle pagine desktop ha immagini senza dimensioni. In calo rispetto al 69%.
  • Al 75° percentile (p75), una pagina desktop ha 9 immagini senza dimensioni. Su mobile ne ha 8.
  • Altezza mediana delle immagini senza dimensioni: 111px su desktop, 98px su mobile. Abbastanza per spostare un paragrafo.
  • Il 72% delle origini desktop e l'81% di quelle mobile supera il CLS. In aumento rispetto al 62% del 2021.

Il CLS è migliorato più di qualsiasi altro Core Web Vital negli ultimi quattro anni. Le immagini senza dimensioni rimangono il principale fattore contribuente. Risolvi questo singolo problema e i layout shift scompariranno sulla maggior parte dei siti.

Guide correlate

About the author

Arjen Karel is a web performance consultant and the creator of CoreDash, a Real User Monitoring platform that tracks Core Web Vitals data across hundreds of sites. He also built the Core Web Vitals Visualizer Chrome extension. He has helped clients achieve passing Core Web Vitals scores on over 925,000 mobile URLs.


I write the code, not the report.

I join your team for 1 to 2 sprints. I set up the monitoring and make sure your team keeps the metrics green after I leave.

Get in touch

Domande frequenti sul CLS di immagini e media

Perché width:auto sulle immagini causa layout shift anche quando sono impostati gli attributi width e height?

L'aspect ratio interno del browser dagli attributi width/height ha la priorità CSS più bassa. width: auto lo sovrascrive, rendendo entrambe le dimensioni sconosciute. L'immagine viene renderizzata a 0x0 finché il file non viene scaricato. Rimuovi width: auto e mantieni solo height: auto; max-width: 100%;.

Ho bisogno di width e height anche sugli elementi video e iframe?

Sì per i video. Stesso meccanismo. Gli iframe sono diversi: non calcolano un rapporto dagli attributi e per default sono 300x150. Usa aspect-ratio nel CSS o il facade pattern.

Come prevengo il CLS con l'elemento picture quando gli aspect ratio differiscono per breakpoint?

Imposta width e height su ciascun <source>. Chrome e Safari usano le dimensioni corrette. Firefox ha un bug per cui usa sempre il fallback dell'<img>. Aggiungi media query CSS con l'aspect-ratio corretto per breakpoint come soluzione alternativa (workaround).

Il lazy loading causa layout shift?

Non se l'immagine ha gli attributi width e height. Ma il lazy loading delle immagini above-the-fold ritarda l'LCP senza alcun beneficio. Non usare mai loading="lazy" sulle immagini nel viewport iniziale.

Perché Lighthouse mostra un buon CLS ma i miei dati sul campo (field data) mostrano layout shift?

Lighthouse viene eseguito su un browser "caldo" con una rete veloce. Non rileva il problema di width: auto perché controlla gli attributi HTML, non gli stili CSS calcolati. Verifica sempre il CLS con i field data da CrUX o uno strumento RUM come CoreDash.

Come le immagini e i media causano il Layout Shift (e come risolverlo)Core Web Vitals Come le immagini e i media causano il Layout Shift (e come risolverlo)