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: 3 ago 2026 · Advanced
Lingue

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.” 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”: 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).”

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.

One shift scores the visible area affected multiplied by the farthest movement relative to the viewport. Fonte: web.dev

Three cards form the equation. Impact fraction is 0.75: the visible viewport area affected between two frames. Distance fraction is 0.25: the farthest movement divided by the viewport's largest dimension. Multiplying them produces a unitless individual layout-shift score of 0.1875. CLS ultimately keeps the largest session-window total, not a lifetime sum of every shift.

© 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.” Un burst è 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.” CLS è il punteggio della finestra più grande, non la somma e non la media.

Evidence for this claim 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. Scope: Current CLS session-window and recent-input rules. Confidence: high · Verified: 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.” 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.” Apri un accordion o espandi 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.
Evidence for this claim A layout shift occurring within 500 milliseconds of a qualifying recent user input has hadRecentInput set and is excluded from CLS. Scope: field and lab Confidence: high · Verified: 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,” misurato al “the 75th percentile of page loads, segmented across mobile and desktop devices.” Le fasce complete:

Evidence for this claim CLS is good at 0.1 or less and poor above 0.25, assessed at the 75th percentile of page loads. Scope: Current web.dev CLS field thresholds. Confidence: high · Verified: web.dev: Cumulative Layout Shift
  • Good: ≤ 0,1
  • Needs improvement: da 0,1 a 0,25
  • Poor: > 0,25
Evidence for this claim CLS is good at 0.1 or less and poor above 0.25, assessed at the 75th percentile of page loads. Scope: Current web.dev CLS field thresholds. Confidence: high · Verified: 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.” 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.” 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.” 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 timestamp-trigger: 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.

Add an expert note

Pin an expert quote

New person? Create their unclaimed profile at /admin/experts/ → Pin a quote first.