Layout Shift wywołany przez przejścia CSS

Dowiedz się, jak znaleźć i usunąć przejścia CSS, które powodują layout shifts

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

Layout Shift wywołany przez przejścia CSS: zrozumienie i łagodzenie skutków

Cumulative Layout Shift wywołane przez przejścia CSS często pojawiają się na wczesnym etapie fazy ładowania strony. Te layout shifts nie występują regularnie, co sprawia, że trudno je debugować.

Zrozumienie przejść CSS:

Przejścia CSS to potężne narzędzie do animowania zmian właściwości w czasie. Są powszechnie używane do efektów takich jak zanikanie, przesuwanie i skalowanie elementów na stronie internetowej. Programiści mogą definiować efekty przejść, określając właściwość, która ma być animowana, czas trwania przejścia oraz funkcję czasową kontrolującą przyspieszenie przejścia.

Przejście może mieć właściwość, czas trwania, funkcję czasową i opóźnienie. Skrócony zapis transition wygląda następująco:

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

Layout Shifts: niezamierzone konsekwencje:

Layout shifts występują, gdy elementy na stronie internetowej zmieniają pozycję lub rozmiar, powodując przeformatowanie innych elementów i przesunięcie ogólnego układu strony. Chociaż przejścia CSS zostały zaprojektowane w celu zapewnienia płynnych animacji, mogą nieumyślnie wywoływać layout shifts, prowadząc do irytujących i zakłócających user experience. Najczęstsze przyczyny layout shifts podczas przejść CSS obejmują zmiany wymiarów, pozycji lub widoczności elementów.

Cumulative Layout Shift wywołane przez przejścia CSS zazwyczaj występują, gdy element powyżej linii zgięcia, taki jak menu nawigacyjne, przechodzi ze swojego pierwszego (niestylowanego) stanu do stanu końcowego (stylowanego lub nawet ukrytego). Jest to zwykle niezamierzona konsekwencja zbyt szeroko zdefiniowanych właściwości transition. Na przykład element menu powinien animować tylko kolor tła, a zamiast właściwości transition 'background-color' wybrano 'all'. Prowadzi to nie tylko do przejścia tła, ale w niektórych przypadkach również do przejścia szerokości, wysokości, a nawet widoczności podczas ładowania strony.

Spójrz na poniższy przykład. Demonstruje on layout shift wywołany przez przejścia CSS, które występują podczas fazy ładowania strony. Niestety widzę ten wzorzec cały czas, a znajdowanie i naprawianie tego rodzaju problemów może być trudne.

Znajdź i napraw przejścia CSS:

Aby znaleźć i naprawić wszystkie layout shifts wywołane przez przejścia CSS, musimy przeprowadzić szybki test. Najpierw musimy znaleźć wszystkie przejścia CSS. Gdy to zrobimy, musimy upewnić się, że przejście nie zmienia pozycji (width, height, margin, padding, visibility) elementu. Możemy to zrobić, modyfikując lub wyłączając te przejścia. Na koniec możemy przetestować wpływ tych zmian i raz na zawsze zdecydować, czy przejścia CSS powodują problemy z CLS. 

Core Web Vitals tip: Cumulative Layout Shift wywołane przez przejścia CSS często pojawiają się na wczesnym etapie fazy ładowania strony. Te layout shifts nie występują regularnie, co sprawia, że trudno je debugować. Spowolnienie sieci poprzez emulację urządzenia mobilnego i wyłączenie pamięci podręcznej ułatwi ich znalezienie! 

Krok 1: Znajdź przejścia CSS

Znajdowanie przejść CSS można wykonać ręcznie: przejrzyj wszystkie arkusze stylów i wyszukaj słowo 'transition'. To nie powinno zająć więcej niż 10 minut, ale jest lepszy sposób! Wystarczy wkleić ten fragment kodu w konsoli i nacisnąć enter

(() => {
 
  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>`);

})()

Pokaże ci tabelę wszystkich przejść, elementów, na których działają, oraz więcej szczegółów dotyczących przejść.

cls snippet table

Aby znaleźć layout shift, musimy szukać właściwości transition takich jak width,height, margin,paddingtransform, display a zwłaszcza all (ponieważ all obejmuje wszystkie prawidłowe właściwości transition)

Krok 2: Modyfikuj przejścia CSS

Powyższy fragment JavaScript pokaże wszystkie przejścia oraz dostarczy przykładowy kod do wyłączenia tych przejść. Do szybkich testów sugeruję wybrać łatwą drogę i wyłączyć wszystkie przejścia jedną prostą linią kodu CSS

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

Oczywiście w środowiskach produkcyjnych wymagana jest większa precyzja. Ostrożnie usuwaj tylko niepotrzebne właściwości transition dla poszczególnych selektorów. Na przykład zmień #button{transition: all .2s} na  #button{transition: background-color .2s}

Krok 3: Zmierz zmianę w layout shift

Następnym i ostatnim krokiem jest zmierzenie wpływu. Możesz użyć mojego rozszerzenia Chrome Core Web Vitals Visualizer lub narzędzia RUM takiego jak CoreDash do zmierzenia rzeczywistego wpływu tych zmian w kodzie.

layout shift transition measured by coredash


Inne dobre praktyki dotyczące przejść:

  1. Preferuj akcelerację GPU: Wykorzystanie akceleracji GPU dla przejść CSS może przenieść obciążenie renderowania z CPU na GPU. Można to osiągnąć, upewniając się, że animowane właściwości sprzyjają akceleracji GPU, takie jak opacity i transform.
  2. Używaj właściwości "will-change": Właściwość CSS will-change informuje przeglądarkę, że dany element prawdopodobnie zostanie zmieniony, co pozwala jej odpowiednio zoptymalizować renderowanie. 
  3. Zapewnij spójne wymiary: Aby zapobiec layout shifts wywołanym przez zmiany wymiarów, upewnij się, że elementy mają spójne wymiary przed i po przejściu. Może to obejmować ustawianie jawnych wymiarów, używanie wartości procentowych lub stosowanie technik takich jak pojemniki z proporcjami.
  4. Optymalizuj funkcje czasowe: Wybór funkcji czasowej może znacząco wpłynąć na postrzeganie płynności podczas przejścia. Zwracaj uwagę na wzorce przyspieszania i zwalniania oraz rozważ użycie ease-in-out lub niestandardowych funkcji cubic bezier dla bardziej naturalnego efektu.

Secure your Q3 Metrics.

Do not let technical debt derail your Core Web Vitals. I provide the strategy, the code, and the verification to pass Google's assessment.

Start the Engagement >>

  • Strategic Planning
  • Code Implementation
  • Verification & Testing
Layout Shift wywołany przez przejścia CSSCore Web Vitals Layout Shift wywołany przez przejścia CSS