Layout Shift causato dalle transizioni CSS
Scopri come trovare e rimuovere le transizioni CSS che creano layout shift

Perché le transizioni CSS causano layout shift
I Cumulative Layout Shift causati dalle transizioni CSS si verificano spesso all'inizio della fase di caricamento della pagina. Questi layout shift non si verificano in modo coerente, il che li rende difficili da eseguire il debug.
Ultima revisione di Arjen Karel nel marzo 2026
Table of Contents!
Il problema di transition: all
La causa più comune dei layout shift correlati alle transizioni è transition: all. Secondo il capitolo CSS del Web Almanac 2022, il 53% delle pagine utilizza transition: all. Ciò significa che ogni modifica di proprietà viene animata, comprese quelle che influiscono sul layout come width, height, margin e padding.
Una transizione CSS ha una proprietà (property), una durata (duration), una funzione di temporizzazione (timing-function) e un ritardo (delay). La scorciatoia ha questo aspetto:
/* property | duration | timing-function | delay */ transition: margin-right 4s ease-in-out 1s;
Il problema inizia quando gli sviluppatori scrivono transition: all .3s ease invece di specificare l'esatta proprietà che vogliono animare. Durante il caricamento della pagina, un elemento above-the-fold come un menu di navigazione passa dal suo stato iniziale (senza stile) al suo stato finale (con stile o persino nascosto). Se la proprietà di transizione è all, ciò include larghezza, altezza e persino visibilità. Il risultato: un layout shift che si verifica solo durante il caricamento ed è quasi impossibile da riprodurre in modo coerente.
Quali proprietà CSS causano layout shift?
Non tutte le transizioni CSS causano layout shift. Solo le proprietà che modificano la geometria o la posizione di un elemento attivano il passaggio di layout (layout step) del browser. Secondo la ricerca di Google, le pagine che animano le proprietà CSS che inducono il layout hanno il 15% di probabilità in meno di superare il CLS. Le pagine che animano margin o border-width hanno un CLS scarso a quasi il doppio del tasso normale.
Proprietà che causano layout shift: width, height, margin, padding, top, left, right, bottom, border-width, font-size, display
Proprietà sicure (solo composite, nessun layout shift): transform, opacity, filter, clip-path
Proprietà sicure (solo paint, nessun layout shift): background-color, color, box-shadow, outline
L'intuizione chiave: transform e opacity sono gestiti interamente dal thread compositore del browser. Non attivano mai il ricalcolo del layout, quindi non contano mai ai fini del CLS. Se devi spostare un elemento, usa transform: translate() invece di top/left. Se devi ridimensionarlo visivamente, usa transform: scale() invece di width/height.
Dai un'occhiata all'esempio qui sotto. Questo dimostra un layout shift causato da transizioni CSS che si verificano durante la fase di caricamento di una pagina. Vedo questo pattern continuamente e trovare e risolvere questo tipo di problemi può essere difficile.
Trovare e risolvere le transizioni CSS
Per trovare e risolvere tutti i layout shift causati dalle transizioni CSS dobbiamo eseguire un rapido test. Prima troviamo tutte le transizioni CSS sulla pagina. Poi controlliamo se qualcuna di esse modifica le proprietà che influenzano il layout. Infine misuriamo l'impatto della disabilitazione o modifica di quelle transizioni per confermare che stavano causando il CLS.
Suggerimento per i Core Web Vitals: i Cumulative Layout Shift causati dalle transizioni CSS si verificano spesso all'inizio della fase di caricamento della pagina. Questi layout shift non si verificano in modo coerente, il che li rende difficili da eseguire il debug. Rallentare la tua rete emulando un dispositivo mobile e disabilitando la cache renderà più facile trovarli!
Passaggio 1: Trovare le transizioni CSS
La ricerca delle transizioni CSS può essere eseguita manualmente: ispeziona tutti i fogli di stile e cerca la parola "transition". Non dovrebbero volerci più di 10 minuti di lavoro, ma c'è un modo migliore! Incolla semplicemente questo snippet nella console e premi invio
(() => {
let nodeTable = [];
let nodeArray = [];
// Get the name of the node
function getName(node) {
const name = node.nodeName;
return node.nodeType === 1
? name.toLowerCase()
: name.toUpperCase().replace(/^#/, '');
}
// Get the selector
const getSelector = (node) => {
let sel = '';
try {
while (node && node.nodeType !== 9) {
const el = node;
const part = el.id
? '#' + el.id
: getName(el) +
(el.classList &&
el.classList.value &&
el.classList.value.trim() &&
el.classList.value.trim().length
? '.' + el.classList.value.trim().replace(/\s+/g, '.')
: '');
if (sel.length + part.length > (100) - 1) return sel || part;
sel = sel ? part + '>' + sel : part;
if (el.id) break;
node = el.parentNode;
}
} catch (err) {
// Do nothing...
}
return sel;
};
const getNodesWithTransition = (node) => {
// Get the computed style
let cs = window.getComputedStyle(node);
let tp = cs['transition-property'];
let td = cs['transition-duration'];
// If there is a transition, add it to the table
if (tp !== '' && tp !== 'none' && td != '0s') {
nodeTable.push({ selector: getSelector(node), transition: cs['transition'] });
nodeArray.push(node);
}
// Recursively call this function for each child node
for (let i = 0; i < node.children.length; i++) {
getNodesWithTransition(node.children[i]);
}
}
// find all transitions
getNodesWithTransition(document.body);
// Display the results in the console
console.log('%cReadable table of selectors and their transitions', 'color: red; font-weight: bold;');
console.table(nodeTable);
console.log('%cNodeList for you to inspect (harder to read but more info)', 'color: red; font-weight: bold;');
console.log(nodeArray);
// styles to temporarity override the transitions
let selectors = nodeTable.map((item) => item.selector).join(', ');
console.log('%cSpecific CSS to disable all transitions on this page', 'color: red; font-weight: bold;');
console.log(`<style>${selectors}{transition-property: none !important;}</style>`);
console.log('%cGlobal CSS to disable all transitions on this page (not suggested on production)', 'color: red; font-weight: bold;');
console.log(`<style>*{transition-property: none !important;}</style>`);
})()
Ti mostrerà una tabella di tutte le transizioni, degli elementi su cui stanno lavorando e maggiori dettagli sulle transizioni.

Per trovare i layout shift, cerca proprietà di transizione come width, height, margin, padding, top, left, display e in particolare all (poiché all include ogni proprietà di transizione valida).
Passaggio 2: Modificare le transizioni CSS
Lo snippet JavaScript qui sopra mostrerà tutte le transizioni e fornirà un codice di esempio su come disabilitarle. Per scopi di test rapidi ti suggerisco di prendere la strada più semplice e disabilitare tutte le transizioni con una semplice riga di codice CSS
<style>*{transition-property: none !important;}</style>Naturalmente per gli ambienti live (di produzione) è necessaria un po' più di finezza. Rimuovi attentamente solo le proprietà di transizione non necessarie per ciascun selettore. Ad esempio, cambia #button{transition: all .2s} in #button{transition: background-color .2s}
Passaggio 3: Misurare il cambiamento nel layout shift
transition: all con proprietà specifiche hanno visto migliorare il loro CLS in media del [CD:placeholder]% .
Migliori pratiche per le transizioni
- Specifica sempre l'esatta proprietà: Non usare mai
transition: all. Scrivi invecetransition: background-color .2s ease. Ciò impedisce layout shift accidentali da proprietà che non intendevi animare. - Usa transform e opacity per le animazioni: Queste due proprietà sono gestite dal compositore e non attivano mai il layout. Usa
transform: translate()per spostare gli elementi,transform: scale()per ridimensionarli visivamente eopacityper dissolverli. Questo è ciò che Google raccomanda per animazioni ad alte prestazioni. - Imposta dimensioni esplicite sugli elementi animati: Se un elemento ha bisogno di una transizione, assicurati che abbia una larghezza e un'altezza esplicite (o un aspect ratio) prima e dopo la transizione. Ciò impedisce al contenuto circostante di spostarsi. Per saperne di più, vedi risolvere i layout shift causati da immagini con ridimensionamento automatico.
- Fai attenzione con will-change: La proprietà CSS
will-changedice al browser di prepararsi per un'animazione promuovendo l'elemento a un proprio livello (layer) compositore. Ma ha dei compromessi: crea un nuovo contesto di impilamento (stacking context), aumenta l'utilizzo della memoria GPU e stabilisce un blocco contenitore (containing block) per i discendenti posizionati. Applicala dinamicamente con JavaScript appena prima dell'inizio dell'animazione e rimuovila al termine dell'animazione. Non lasciarewill-changenel tuo foglio di stile in modo permanente.
Nonostante tutto questo, il Web Almanac 2025 riporta che il 40% delle pagine mobile esegue ancora animazioni non composite. La buona notizia: il CLS è il Core Web Vital con il tasso di superamento più alto con l'81% su dispositivi mobili. La cattiva notizia: se il tuo sito rientra nel 19% che fallisce, le transizioni CSS potrebbero essere la causa che non hai ancora controllato.
Pinpoint the route, device, and connection that fails.
CoreDash segments every metric by route, device class, browser, and connection type. Real time data. Not the 28 day average Google gives you.
Explore Segmentation
