Layout Shift causé par les transitions CSS

Apprenez à trouver et supprimer les transitions CSS qui créent des layout shifts

Arjen Karel Core Web Vitals Consultant
Arjen Karel - linkedin
Last update: 2026-03-02

Pourquoi les transitions CSS causent-elles des layout shifts

Les Cumulative Layout Shifts causés par les transitions CSS se produisent souvent tôt pendant la phase de chargement de la page. Ces layout shifts ne se produisent pas de manière cohérente, ce qui les rend difficiles à déboguer.

Dernière révision par Arjen Karel en mars 2026

Le problème de transition: all

La cause la plus fréquente des layout shifts liés aux transitions est transition: all. Selon le chapitre CSS du Web Almanac 2022, 53 % des pages utilisent transition: all. Cela signifie que chaque changement de propriété est animé, y compris ceux qui affectent la mise en page (layout) comme width, height, margin et padding.

Une transition CSS a une propriété, une durée, une fonction de synchronisation (timing-function) et un délai. Le raccourci ressemble à ceci :

/* property | duration | timing-function | delay */
transition: margin-right 4s ease-in-out 1s;

Le problème commence lorsque les développeurs écrivent transition: all .3s ease au lieu de spécifier la propriété exacte qu'ils veulent animer. Pendant le chargement de la page, un élément au-dessus de la ligne de flottaison (above-the-fold) comme un menu de navigation passe de son état initial (sans style) à son état final (avec style ou même caché). Si la propriété de transition est all, cela inclut la largeur (width), la hauteur (height) et même la visibilité. Le résultat : un layout shift qui ne se produit que pendant le chargement et qui est presque impossible à reproduire de manière cohérente.

Quelles propriétés CSS causent un layout shift ?

Toutes les transitions CSS ne causent pas de layout shifts. Seules les propriétés qui modifient la géométrie ou la position d'un élément déclenchent l'étape de mise en page (layout) du navigateur. Selon les recherches de Google, les pages qui animent des propriétés CSS induisant une mise en page ont 15 % moins de chances de réussir le CLS. Les pages qui animent margin ou border-width ont un mauvais CLS à près du double du taux normal.

Propriétés qui causent un layout shift : width, height, margin, padding, top, left, right, bottom, border-width, font-size, display

Propriétés sûres (composite uniquement, pas de layout shift) : transform, opacity, filter, clip-path

Propriétés sûres (peinture uniquement, pas de layout shift) : background-color, color, box-shadow, outline

L'idée clé : transform et opacity sont gérés entièrement par le thread compositeur du navigateur. Ils ne déclenchent jamais de recalcul de la mise en page, donc ils ne comptent jamais dans le CLS. Si vous avez besoin de déplacer un élément, utilisez transform: translate() au lieu de top/left. Si vous avez besoin de redimensionner visuellement, utilisez transform: scale() au lieu de width/height.

Jetez un œil à l'exemple ci-dessous. Cela démontre un layout shift causé par des transitions CSS qui se produisent pendant la phase de chargement d'une page. Je vois ce modèle tout le temps et trouver et corriger ce genre de problèmes peut être difficile.

Trouver et corriger les transitions CSS

Pour trouver et corriger tous les layout shifts causés par les transitions CSS, nous devons exécuter un test rapide. D'abord, nous trouvons toutes les transitions CSS sur la page. Ensuite, nous vérifions si l'une d'entre elles modifie des propriétés affectant la mise en page. Enfin, nous mesurons l'impact de la désactivation ou de la modification de ces transitions pour confirmer qu'elles causaient le CLS.

Astuce Core Web Vitals : Les Cumulative Layout Shifts causés par les transitions CSS se produisent souvent tôt pendant la phase de chargement de la page. Ces layout shifts ne se produisent pas de manière cohérente, ce qui les rend difficiles à déboguer. Ralentir votre réseau en émulant un appareil mobile et en désactivant votre cache facilitera leur recherche !

Étape 1 : Trouver les transitions CSS

Trouver les transitions CSS peut se faire manuellement : inspectez toutes les feuilles de style et cherchez le mot 'transition'. Cela ne devrait pas prendre plus de 10 minutes de travail, mais il y a un meilleur moyen ! Collez simplement cet extrait dans la console et appuyez sur Entrée

(() => {

  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>`);

})()

Cela vous montrera un tableau de toutes les transitions, les éléments sur lesquels elles agissent et plus de détails sur les transitions.

Pour trouver les layout shifts, recherchez les propriétés de transition comme width, height, margin, padding, top, left, display et surtout all (puisque all inclut toutes les propriétés de transition valides).

Étape 2 : Modifier les transitions CSS

L'extrait JavaScript ci-dessus montrera toutes les transitions et fournira également un exemple de code sur la façon de désactiver ces transitions. À des fins de test rapide, je vous suggère de prendre le chemin le plus simple et de désactiver toutes les transitions avec une simple ligne de code CSS

<style>*{transition-property: none !important;}</style>

Bien sûr, pour les environnements de production, un peu plus de finesse est requise. Supprimez soigneusement uniquement les propriétés de transition inutiles sur une base par sélecteur. Par exemple, changez #button{transition: all .2s} en #button{transition: background-color .2s}

Étape 3 : Mesurer le changement de layout shift

La prochaine et dernière étape consiste à mesurer l'impact. Vous pouvez utiliser mon extension chrome Core Web Vitals Visualizer ou un outil RUM comme CoreDash pour mesurer l'impact réel de ces changements de code. Dans les données de surveillance de CoreDash, les sites qui ont remplacé transition: all par des propriétés spécifiques ont vu leur CLS s'améliorer de [CD:placeholder] % en moyenne.

Meilleures pratiques pour les transitions

  1. Spécifiez toujours la propriété exacte : N'utilisez jamais transition: all. Écrivez plutôt transition: background-color .2s ease. Cela empêche les layout shifts accidentels provenant de propriétés que vous n'aviez pas l'intention d'animer.
  2. Utilisez transform et opacity pour les animations : Ces deux propriétés sont gérées par le compositeur et ne déclenchent jamais la mise en page. Utilisez transform: translate() pour déplacer des éléments, transform: scale() pour les redimensionner visuellement, et opacity pour les fondre. C'est ce que Google recommande pour les animations haute performance.
  3. Définissez des dimensions explicites sur les éléments animés : Si un élément a besoin de transition, assurez-vous qu'il a une largeur et une hauteur explicites (ou un ratio d'aspect) avant et après la transition. Cela empêche le contenu environnant de se décaler. Pour en savoir plus, consultez comment corriger les layout shifts causés par des images à redimensionnement automatique.
  4. Faites attention avec will-change : La propriété CSS will-change indique au navigateur de se préparer à une animation en promouvant l'élément dans son propre calque de compositeur. Mais cela s'accompagne de compromis : cela crée un nouveau contexte d'empilement (stacking context), augmente l'utilisation de la mémoire du GPU et établit un bloc conteneur (containing block) pour les descendants positionnés. Appliquez-le dynamiquement avec JavaScript juste avant le début de l'animation, et supprimez-le à la fin de l'animation. Ne laissez pas will-change dans votre feuille de style de manière permanente.

Malgré tout cela, le Web Almanac 2025 rapporte que 40 % des pages mobiles exécutent encore des animations non compositées. La bonne nouvelle : le CLS est le Core Web Vital avec le taux de réussite le plus élevé avec 81 % sur mobile. La mauvaise nouvelle : si votre site fait partie des 19 % qui échouent, les transitions CSS pourraient être la cause que vous n'avez pas encore vérifiée.

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.

The RUM tool I built for my own clients.

CoreDash is what I use to audit enterprise platforms. Under 1KB tracking script, EU hosted, no consent banner. AI with MCP support built in. The same tool, available to everyone.

Create Free Account
Layout Shift causé par les transitions CSSCore Web Vitals Layout Shift causé par les transitions CSS