Cumulative Layout Shift (CLS): guida alla stabilità visiva

Che cosa misura Cumulative Layout Shift, come si calcola il punteggio (impatto × distanza), le finestre di sessione, le soglie, le cause comuni e come correggere e diagnosticare gli spostamenti.

Prima pubblicazione: 26 giu 2026 · Ultimo aggiornamento: 24 ago 2026 · Avanzato

Cumulative Layout Shift (CLS) è il Core Web Vital della stabilità visiva: misura quanto il contenuto visibile si sposta in modo inatteso mentre una pagina è in uso. È un punteggio senza unità (impact fraction × distance fraction per ogni spostamento) e, da giugno 2021, rappresenta la finestra di sessione più grande degli spostamenti, non la somma sull’intera vita della pagina. Un valore buono è ≤ 0,1 al 75° percentile dei dati sul campo; da 0,1 a 0,25 necessita miglioramenti; oltre 0,25 è scarso. Le cause abituali sono immagini, annunci, iframe ed embed senza dimensioni, font web e contenuti inseriti sopra la piega; correggili riservando spazio (width/height o aspect-ratio), regolando font-display e animando con transform. Lighthouse spesso legge valori vicini a 0 perché non interagisce con la pagina e non esegue l’intero ciclo di vita; i dati sul campo (CrUX) sono quelli che Google misura davvero.

TL;DR — CLS è il Core Web Vital della stabilità visiva. Ogni spostamento riceve il punteggio impact fraction × distance fraction; la metrica è la finestra di sessione più grande degli spostamenti (≤ 1 s tra gli spostamenti, finestra di ≤ 5 s), non la somma sull’intera vita della pagina, che era la definizione precedente a giugno 2021. Buono è ≤ 0,1, necessita miglioramenti fino a 0,25, scarso > 0,25, al 75° percentile dei dati sul campo. Contano solo gli spostamenti visibili nella viewport; sono esclusi quelli entro 500 ms da un input discreto (lo scrolling no). Le cause sono immagini/video/annunci/iframe/embed senza dimensioni, font web e contenuti inseriti sopra contenuti esistenti; le correzioni consistono nel riservare spazio, usare font-display/size-adjust e animare solo con transform. La trappola da evitare: Lighthouse (laboratorio) legge spesso valori vicini a 0 perché non interagisce con la pagina e non esegue l’intero ciclo di vita; i dati sul campo (CrUX) sono ciò che Google misura davvero.

Che cosa misura il CLS

L’inquadramento di Google è questo: “Cumulative Layout Shift (CLS) is a stable Core Web Vital metric. It’s an important, user-centric metric for measuring visual stability because it helps quantify how often users experience unexpected layout shifts.” (traduzione) «Cumulative Layout Shift è una metrica Core Web Vital stabile e incentrata sull’utente, che misura la stabilità visiva quantificando la frequenza degli spostamenti inattesi». La parola operativa è inaspettato: contenuto che si sposta da solo, non perché l’utente abbia fatto qualcosa.

Fa parte del trio dei Core Web Vitals insieme a Largest Contentful Paint (caricamento) e Interaction to Next Paint (reattività). Mentre LCP e INP si misurano in millisecondi, il CLS è l’eccezione: un punteggio di rapporto senza unità. È una distinzione che confonde continuamente. Un CLS di 0,05 non è 50 ms: non ha alcuna unità di tempo.

La formula: impatto × distanza

Per ogni spostamento, Google la definisce così:

layout shift score = impact fraction × distance fraction
  • Impact fraction “measures how unstable elements impact the viewport area between two frames” (traduzione) «misura l’area della viewport interessata dagli elementi instabili tra due fotogrammi»: è l’area visibile combinata occupata dagli elementi in movimento, prima e dopo, espressa come quota della viewport.
  • Distance fraction è “the greatest horizontal or vertical distance any unstable element has moved in the frame divided by the viewport’s largest dimension (width or height, whichever is greater).” (traduzione) «la maggiore distanza orizzontale o verticale percorsa da un elemento instabile, divisa per la dimensione maggiore della viewport».

Entrambe le dimensioni contano indipendentemente. Un elemento piccolo che attraversa quasi tutto lo schermo e un elemento grande che si sposta appena possono ottenere punteggi molto diversi. L’esempio svolto di web.dev: una impact fraction di 0.75 e una distance fraction di 0.25 producono un punteggio di layout shift pari a 0.1875.

Un singolo spostamento misura l’area visibile interessata moltiplicata per il movimento più lontano rispetto alla viewport. Fonte: web.dev

Tre schede formano l’equazione. La impact fraction è 0,75: l’area visibile della viewport interessata tra due frame. La distance fraction è 0,25: il movimento più lontano diviso per la dimensione maggiore della viewport. Moltiplicandole si ottiene un punteggio di layout shift individuale senza unità pari a 0,1875. Alla fine CLS conserva il totale della finestra di sessione più grande, non una somma di ogni spostamento sulla vita della pagina.

© Patrick Stox LLC · CC BY 4.0 ·

Finestre di sessione: la parte che tutti interpretano male

Ecco il fatto sul CLS che viene riportato più spesso in modo errato e che voglio soprattutto tu ricordi. CLS non è la somma di tutti gli spostamenti durante la vita della pagina. Un tempo lo era, ma è cambiato nel giugno 2021.

Oggi: “CLS measures the largest burst of layout shift scores for every unexpected layout shift that occurs during the entire lifecycle of a page.” (traduzione) «CLS misura la maggiore sequenza di punteggi degli spostamenti inattesi nell’intero ciclo di vita della pagina». Una sequenza è una finestra di sessione: “one or more individual layout shifts occur in rapid succession with less than 1-second in between each shift and a maximum of 5 seconds for the total window duration.” (traduzione) «uno o più spostamenti avvengono in rapida successione, con meno di un secondo tra l’uno e l’altro e per una durata totale massima di cinque secondi». CLS è il punteggio della finestra più grande, non la somma e non la media.

Prova a sostegno di questa affermazione CLS uses the largest session window of unexpected layout shifts, with gaps under one second and a maximum five-second window; recent discrete input can exclude a shift. Ambito: Current CLS session-window and recent-input rules. Attendibilità: alta · Verificato: web.dev: Cumulative Layout Shift

Perché il cambiamento? La vecchia definizione, che sommava tutto, penalizzava silenziosamente le pagine longeve. Una single-page app o un feed a scorrimento infinito accumulava più CLS solo per il fatto di esistere più a lungo, anche se ogni spostamento era piccolo e ben distanziato. Il team Chrome Speed Metrics è passato alla finestra di sessione massima per evitare di penalizzare la durata e ha scelto il massimo invece della media per evitare il risultato perverso per cui correggere uno spostamento secondario piccolo avrebbe potuto peggiorare il punteggio. Quando la modifica è stata distribuita, nessun origin ha ricevuto un punteggio peggiore, la maggior parte non ha visto cambiamenti e una parte delle pagine con UI lenta o scrolling infinito è migliorata. Se leggi un articolo vecchio che parla ancora della “somma di tutti gli spostamenti”, è obsoleto.

Che cosa conta e che cosa no

Tre esclusioni decidono che cosa finisce davvero nel punteggio:

  • Ciò che è sotto la piega non conta. Vengono valutati solo gli spostamenti del contenuto visibile nella viewport corrente. Uno spostamento in fondo a una pagina lunga, che l’utente non raggiunge mai con lo scroll, non ha alcun impatto. In pratica, correggere gli spostamenti nella viewport ha quasi sempre un ROI maggiore che inseguire quelli molto più in basso.
  • Gli spostamenti avviati dall’utente hanno una deroga di 500 ms. “Layout shifts that occur within 500 milliseconds of user input will have the hadRecentInput flag set, so they can be excluded from calculations.” (traduzione) «Gli spostamenti entro 500 millisecondi da un input dell’utente ricevono il flag hadRecentInput e possono essere esclusi dai calcoli». La posizione di Google è che gli spostamenti “that occur in response to user interactions… are generally fine, as long as the shift occurs close enough to the interaction that the relationship is clear to the user.” (traduzione) «in risposta alle interazioni sono in genere accettabili, purché avvengano abbastanza vicino all’interazione da rendere chiara la relazione». Apri un pannello espandibile o un menu: il movimento è atteso, quindi viene perdonato.
  • Lo scrolling però non è una deroga automatica. L’esclusione di 500 ms vale solo per eventi discreti: tocco, clic, pressione di un tasto. I gesti continui (scrolling, pinch-zoom) non attivano la finestra di esclusione. Se il contenuto si sposta mentre qualcuno scorre, conta comunque. Molte descrizioni sbagliano questa distinzione: è importante applicarla correttamente.
Prova a sostegno di questa affermazione A layout shift occurring within 500 milliseconds of a qualifying recent user input has hadRecentInput set and is excluded from CLS. Ambito: field and lab Attendibilità: alta · Verificato: Cumulative Layout Shift (CLS)

Soglie e origine del punteggio

“To provide a good user experience, sites should strive to have a CLS score of 0.1 or less,” (traduzione) «Per offrire una buona esperienza utente, i siti dovrebbero puntare a un CLS pari o inferiore a 0,1», misurato al “the 75th percentile of page loads, segmented across mobile and desktop devices.” (traduzione) «75° percentile dei caricamenti, separando dispositivi mobili e desktop». Le fasce complete:

Prova a sostegno di questa affermazione CLS is good at 0.1 or less and poor above 0.25, assessed at the 75th percentile of page loads. Ambito: Current web.dev CLS field thresholds. Attendibilità: alta · Verificato: web.dev: Cumulative Layout Shift
  • Good: ≤ 0,1
  • Needs improvement: da 0,1 a 0,25
  • Poor: > 0,25
Prova a sostegno di questa affermazione CLS is good at 0.1 or less and poor above 0.25, assessed at the 75th percentile of page loads. Ambito: Current web.dev CLS field thresholds. Attendibilità: alta · Verificato: web.dev: Cumulative Layout Shift

La soglia di 0,1 non è arbitraria. La ricerca sugli utenti di Google ha rilevato che “levels of shift from 0.15 and higher were consistently perceived as disruptive, while shifts of 0.1 and lower were noticeable but not excessively disruptive.” (traduzione) «Gli spostamenti da 0,15 in su erano percepiti costantemente come fastidiosi, mentre quelli pari o inferiori a 0,1 erano visibili ma non eccessivamente disturbanti». Hanno scelto 0,1 invece di una soglia più rigida anche perché gli embed di terze parti (annunci, social) causano spostamenti così spesso che una soglia più severa sarebbe poco pratica per il web reale.

La parte “75° percentile dei dati sul campo” è fondamentale, e ci porta alla trappola di misurazione più grande.

Laboratorio e campo: perché i numeri non coincidono

È qui che la maggior parte delle persone si scotta. Lighthouse e altri strumenti di laboratorio riportano spesso un CLS vicino a 0,0 mentre i dati sul campo — e Google — mostrano qualcosa di molto peggiore. La differenza non significa che uno strumento sia disonesto: è una differenza di ambito. Un test di laboratorio è un singolo caricamento breve e programmato; non scorre, non fa clic e non si trattiene, quindi cattura solo gli spostamenti del caricamento iniziale. I dati sul campo (CrUX) aggregano visite reali di molti utenti, dispositivi e navigazioni su una finestra mobile, e CLS è definito sull’intero ciclo di vita della pagina: apertura dei menu, caricamento lazy dei contenuti durante lo scrolling, riempimento tardivo degli annunci, per tutta la durata della sessione. Un breve test di laboratorio non può strutturalmente vedere gran parte di tutto questo.

La regola pratica è quindi: usa i dati di laboratorio per diagnosticare uno spostamento specifico e i dati sul campo per conoscere il tuo punteggio reale. Google usa per il ranking i dati sul campo del Chrome User Experience Report (CrUX), mostrati in PageSpeed Insights e Search Console. Se Lighthouse legge 0,0 ma PageSpeed Insights mostra 0,18, considera il numero sul campo quello che riflette i tuoi utenti reali; poi riproduci lo spostamento in laboratorio interagendo con la pagina come farebbe un visitatore. Ci sono altri due divari di ambito da conoscere: la maggior parte degli strumenti, incluso Lighthouse, non propaga al punteggio del documento padre gli spostamenti di layout degli iframe, anche se CrUX può rifletterli; inoltre il RUM basato sulla Layout Instability API eredita lo stesso punto cieco sugli iframe, quindi il tuo monitoraggio degli utenti reali può spiegare solo in parte un numero CrUX peggiore di quanto mostri l’attribuzione di prima parte.

Le cause comuni

In ordine approssimativo di frequenza con cui le vedo:

  1. Immagini e video senza dimensioni. Senza un’altezza riservata, tutto ciò che sta sotto salta quando il contenuto multimediale si carica.
  2. Annunci, embed e iframe senza spazio riservato. Le reti pubblicitarie distribuiscono dimensioni dinamiche e gli embed non dichiarano la propria altezza prima di caricarsi.
  3. Contenuti inseriti dinamicamente sopra contenuti esistenti. Banner dei cookie, barre di notifica, widget “correlati”, promozioni caricate tardi: tutto ciò che spinge verso il basso quello che è già sullo schermo.
  4. Font web (FOIT/FOUT). Quando il font personalizzato sostituisce il fallback, il testo si ridistribuisce se le metriche sono diverse.
  5. Animazioni su proprietà che attivano il layout. Animare top, left, margin, box-shadow o box-sizing obbliga il browser a ricalcolare il layout della pagina a ogni frame.

Le correzioni

Ogni correzione rispecchia la propria causa:

  • Immagini/video — riserva lo spazio. Imposta gli attributi width e height così il browser calcola il rapporto d’aspetto e mantiene il riquadro; abbinali a img { height: auto; width: 100%; } per il comportamento responsive, oppure usa la proprietà CSS aspect-ratio. Nella maggior parte dei siti è la correzione CLS con il maggior effetto.
  • Annunci/embed/iframe — riserva lo spazio anche qui. Usa min-height o aspect-ratio sul contenitore; per gli spazi pubblicitari, la guida Google Publisher Tag è netta: “Setting a fixed height and width directly on the ad slot div is the most effective way to do this.” (traduzione) «Impostare altezza e larghezza fisse direttamente sul div dello slot pubblicitario è il metodo più efficace». Per gli spazi con più dimensioni, riserva quella della dimensione configurata più grande. Sposta più in basso i contenuti caricati tardi, così ogni spostamento residuo resta sotto la piega.
  • Contenuti dinamici — non inserirli nel flusso. Riserva un segnaposto della dimensione finale oppure sovrapponi il contenuto invece di inserirlo. Gli skeleton loader aiutano solo se corrispondono esattamente alle dimensioni finali: anche uno skeleton più corto di pochi pixel rispetto al contenuto reale provoca uno spostamento. Preferisci caricamenti attivati dall’utente (“Carica altro”) alle inserzioni a sorpresa.
  • Font — abbina le metriche. font-display: optional è l’unico valore con un rischio CLS effettivamente nullo; swap riduce al minimo il testo invisibile ma può provocare uno spostamento durante il cambio. Meglio ancora, usa gli override delle metriche CSS — size-adjust, ascent-override, descent-override, line-gap-override — per dimensionare il font fallback in modo che corrisponda al web font e rendere il cambio impercettibile. Precarica i font critici.
  • Animazioni — solo transform. Anima con transform (translate, scale, rotate) invece di top/left/margin. Le animazioni basate su transform vengono composte e non attivano il layout, quindi non spostano nulla.

Come il CLS si inserisce nel ranking (con la giusta proporzione)

CLS è uno degli input del segnale page experience di Google. Google dice che i Core Web Vitals sono usati dai suoi sistemi di ranking, ma la documentazione attuale della Ricerca non pubblica un peso CLS preciso, una regola di spareggio o una garanzia di ranking; quindi considera ogni meccanismo specifico (incluso “è uno spareggio”) un’approssimazione operativa, non un fatto documentato. Il mio consiglio costante su tutto ciò che scrivo sui Core Web Vitals è: entra nella fascia “good” e vai avanti. La maggior parte dei siti non vedrà un aumento significativo di ranking o di risultati aziendali portando 0,08 a 0,02, e un singolo punteggio raramente spiega da solo un risultato di ricavi o conversioni. Il CLS è una condizione minima: vuoi superare la soglia, ma non dovrebbe diventare il fulcro del programma SEO a discapito di LCP, INP o, francamente, dei tuoi contenuti.

Due note operative che evitano molta confusione:

  • CrUX è indietro di circa 28 giorni. È una finestra mobile di 28 giorni, quindi una correzione distribuita oggi non si registrerà completamente in PageSpeed Insights o Search Console per settimane. Non allarmarti se il numero non cambia la mattina dopo.
  • L’elemento attribuito spesso non è la causa principale. La Layout Shift Attribution API indica quale elemento si è spostato, ma come osserva web.dev, “it’s possible that these elements are only indirectly related to the ‘root cause’ of layout instability.” (traduzione) «È possibile che questi elementi siano collegati solo indirettamente alla causa principale dell’instabilità del layout». Il testo che salta è di solito la vittima di un’immagine senza dimensioni sopra che si carica tardi: correggi la causa, non il sintomo. Trattalo come un ciclo tra istante ed evento scatenante: annota l’ora d’inizio dello spostamento, poi controlla che cos’altro sia cambiato nella stessa finestra — una richiesta di rete completata, l’arrivo di un’immagine o di un font, un ridimensionamento o una modifica di classe/stile — e considera il nodo attribuito un indizio, non una prova, finché non lo hai collegato a quel trigger.

Aggiungi una nota dell’esperto

Fissa una citazione dell’esperto

Persona nuova? Crea il suo profilo non rivendicato in /admin/experts/ → Fissa una citazione dell’esperto prima.