Wie durch Scrollen ausgelöste Animationen CLS verursachen
Dein Hide-on-Scroll-Header lässt deinen CLS vielleicht unbemerkt durchfallen. Warum das so ist und wie du es behebst.
Teilen
Wenn ich ein Audit für den Cumulative Layout Shift mache, fange ich natürlich mit Shifts während der Ladephase an. Ich prüfe Bilder ohne Größenangaben, nachgeladene Ads und Font-Swaps (FOUT).
Aber nicht jeder CLS entsteht beim Laden der Seite. Manchmal lösen Interaktionen wie Scrollen ihn aus. Solche Fälle sind schwer zu finden. Lighthouse scrollt nicht, und du musst genau wissen, wo du suchen musst.
Zuletzt geprüft von Arjen Karel im März 2026
Bei einem aktuellen Audit habe ich RUM-Daten aus CoreDash hinzugezogen und ein verdächtiges Muster gesehen. Ein #header-Element schien deutlich mehr Layout-Shifts zu verursachen als üblich.

Hier sehen wir einen fixierten Header: Er blendet sich beim Scrollen nach unten aus und erscheint beim Scrollen nach oben wieder. Dieses Muster sehe ich oft. Wenn es falsch umgesetzt ist, verursacht jeder Richtungswechsel beim Scrollen einen Layout-Shift.
Warum durch Scrollen ausgelöste Layout-Shifts anders sind
Normalerweise entsteht nach einer Interaktion kein CLS. CLS misst unerwartete Layout-Shifts. Nach einer Interaktion erwartet man jedoch, dass sich das Layout verändert. Deshalb hat die CLS-Metrik eine automatische Schonfrist von 500 ms. Layout-Shifts innerhalb von 500 Millisekunden nach einer Nutzerinteraktion werden nicht für den CLS-Score gewertet. Der Browser regelt das, indem er bei diesen Shifts ein hadRecentInput-Flag setzt und prüft.
Das Problem: Das gilt nur für diskrete Events wie Klicks, Taps und Tastendrücke. Laut der Layout-Instability-Spezifikation zählt Scrollen explizit nicht als ausschließender Input. Drag- oder Pinch-Zoom-Gesten ebenfalls nicht. Nur diskrete Events bekommen die 500-ms-Schonfrist.
Das bedeutet: Jeder Layout-Shift, den ein Scroll-Event auslöst, zählt direkt für deinen CLS-Score.
Laut dem Web Almanac 2025 nutzen immer noch 40 % der mobilen Seiten nicht-kompositierte Animationen. Das sind Animationen auf Eigenschaften wie top, height oder margin, die bei jedem Frame das Layout neu berechnen. Feuern sie beim Scrollen, zählt jeder einzelne Frame für deinen CLS.
Das Problem mit Hide-on-Scroll-Headern
Beginnen wir mit dem Problem, das ich heute gefunden habe: dem „Hide-on-Scroll-Header-Problem“. Ein fixierter Header nutzt JavaScript, um die Sichtbarkeit beim Scrollen umzuschalten. Die Implementierung sieht so aus:
/* CSS */
#header {
position: fixed;
top: 0;
transition: top 0.3s ease;
}
/* JavaScript */
window.addEventListener('scroll', () => {
if (scrollingDown) {
header.style.top = '-80px'; // hide
} else {
header.style.top = '0px'; // show
}
}); Der Layout-Shift entsteht durch die Kombination aus transition: top 0.3s ease und der Änderung von header.style.top in JavaScript.
Der Grund dafür: top ist eine Layout-Eigenschaft. Verarbeitet der Browser eine Änderung an top, durchläuft er die komplette Rendering-Pipeline: Style, Layout, Paint, Composite. Bei jedem Frame während dieser Transition berechnet der Browser das Layout neu. Jede Neuberechnung erzeugt einen neuen Layout-Shift-Eintrag.
Bei jedem Richtungswechsel beim Scrollen klettert der CLS-Zähler weiter nach oben, solange der Nutzer mit der Seite interagiert.
Ich habe genau dieses Verhalten einer Website aus einem meiner Audits in einer Demo nachgebaut und ein Video aufgenommen. Nach etwas Scrollen kletterte der CLS über 0,1. Zugegeben: So extrem scrollt im Alltag kaum jemand. An der Mechanik ändert das jedoch nichts. Ich habe schon oft erlebt, dass genau dieser Layout-Shift Websites über das Limit drückt und der CLS durchfällt.
Welche CSS-Eigenschaften können bei Animationen Layout-Shifts verursachen?
Damit eine Animation CLS verursacht, muss sie Layout auslösen. Die Rendering-Pipeline des Browsers hat nach der Style-Berechnung drei Hauptphasen: Layout, Paint und Composite. Eigenschaften, die nur die Composite-Phase betreffen, verursachen niemals Layout-Shifts. Details dazu, wie CSS-Transitions Layout-Shifts verursachen, findest du im Begleitartikel.
Eigenschaften, die Layout auslösen (und bei Animationen CLS verursachen):
top, left, right, bottom, width, height, margin, padding, border-width, font-size
Sie alle verändern die Geometrie oder Position eines Elements. Der Browser muss die Position des Elements neu berechnen (und oft auch die weiterer Elemente).
Eigenschaften, die Layout komplett überspringen (und für Animationen sicher sind):
transform und opacity laufen auf dem Compositor-Thread. Sie umgehen sowohl Layout als auch Paint. Der Browser verarbeitet sie auf der GPU. Deshalb laufen diese Animationen selbst dann flüssig, wenn der Main-Thread ausgelastet ist. Da sie niemals eine Layout-Neuberechnung auslösen, erzeugen sie auch keine Layout-Shift-Einträge.
Layout-Eigenschaften durch Transforms ersetzen
Der Fix für den Hide-on-Scroll-Header ist einfach: Ersetze die top-Animation durch transform: translateY().
/* CSS - BEFORE (causes CLS) */
#header {
position: fixed;
top: 0;
transition: top 0.3s ease;
}
/* CSS - AFTER (no CLS) */
#header {
position: fixed;
top: 0;
transition: transform 0.3s ease;
}
/* JavaScript - BEFORE */
header.style.top = '-80px';
/* JavaScript - AFTER */
header.style.transform = 'translateY(-80px)'; Das optische Ergebnis ist identisch: Der Header fährt nach oben und verschwindet. Doch transform: translateY() läuft komplett auf dem Compositor und verursacht nie einen Layout-Shift.
Dasselbe Prinzip gilt für jede durch Scrollen ausgelöste Animation:
- Sliding-Panels: Nutze
transform: translateX()stattleftoderright - Aufklappende Elemente: Nutze
transform: scaleY()stattheight - Ausblendende Elemente: Nutze
opacitystattvisibilitykombiniert mit Höhenänderungen
Weitere durch Scrollen ausgelöste Muster, die CLS verursachen
Den Hide-on-Scroll-Header sehe ich oft – es gibt aber noch weitere Fälle. Jedes JavaScript, das als Reaktion auf ein Scroll-Event eine Layout-Eigenschaft ändert, erzeugt einen Layout-Shift. Zum Beispiel:
Parallax-Effekte mit top oder margin-top. Ersetze sie durch transform: translateY() oder nutze den CSS-Ansatz mit perspective und translateZ für reines CSS-Parallax.
Sticky-Navigationen, die ihre Höhe beim Scrollen ändern. Eine Navigationsleiste, die von 80 px auf 50 px schrumpft, sobald der Nutzer über einen Schwellenwert scrollt. Wird die Höhenänderung per transition: height animiert, ersetze das durch transform: scaleY().
Scroll-abhängige Fortschrittsbalken mit width. Ein Lesefortschrittsbalken, der durch die Animation von width von links nach rechts wächst. Nutze stattdessen transform: scaleX() mit transform-origin: left.
Moderne Alternative: CSS Scroll-Driven Animations. Mit der animation-timeline: scroll()-API steuerst du Animationen direkt über den Scroll-Fortschritt – komplett ohne JavaScript. Da diese Animationen standardmäßig transform und opacity nutzen und auf dem Compositor laufen, verursachen sie niemals Layout-Shifts. Die Browser-Unterstützung umfasst Chrome 115+ und Edge 115+; für Safari ist das Feature noch in Entwicklung. Für scroll-basierte Effekte wie Parallax, Fortschrittsbalken und Reveal-Animationen ist das die sauberste Lösung. Wenn du JavaScript-Scrolling komplett abschaffen willst, ist die Scroll-Driven-Animations-API der richtige Weg.
Warum Lighthouse das nicht erkennt
Lighthouse simuliert das Laden der Seite. Es scrollt nicht. Es interagiert nach dem Laden nicht mit der Seite. Durch Scrollen ausgelöste Layout-Shifts sind in Lab Data daher völlig unsichtbar.
Diese Shifts findest du nur mit Real User Monitoring. Field Data erfasst den gesamten Lebenszyklus der Seite – inklusive jedes Layout-Shifts beim Scrollen, Klicken und Navigieren. Ist dein CrUX-CLS-Score schlechter als dein Lighthouse-CLS-Score, solltest du als Erstes durch Scrollen ausgelöste Animationen prüfen. CoreDash trackt den CLS echter Besucher inklusive jedes durch Scrollen ausgelösten Layout-Shifts. So siehst du genau, welche Elemente dafür verantwortlich sind.
So findest du durch Scrollen ausgelöste Layout-Shifts
Öffne die Chrome DevTools. Wechsle in den Performance-Tab. Starte die Aufnahme (das Kreis-Symbol) und scrolle die Seite mehrmals auf und ab. Stoppe die Aufnahme. Suche im Track „Layout Shifts“ nach lila Rauten. Siehst du dort eine Häufung von Shifts, die mit deinen Scroll-Bewegungen zusammenfallen, hast du ein Problem mit scroll-basiertem CLS. Du kannst auch die Chrome-Extension Core Web Vitals Visualizer nutzen, um CLS beim Scrollen in Echtzeit zu sehen.

Die Faustregel
Was sich beim Scrollen bewegt, animierst du mit transform. Was beim Scrollen ein- oder ausblendet, animierst du mit opacity. Diese Eigenschaften laufen ausschließlich auf dem Compositor.
Für JavaScript gilt: Prüfe deine Scroll-Event-Handler, IntersectionObserver-Callbacks und jedes Skript, das Element-Styles anhand der Scroll-Position verändert. Verwendet der Code top, left, margin, width, height oder padding, ersetze das durch das entsprechende transform.

Brauchst du eine schnellere Website?
Ich bin Arjen und mache seit 17 Jahren langsame Websites schnell. Wenn du auf Probleme stößt, die du nicht selbst lösen kannst, schick mir deine URL und wir reden darüber.
Schick mir deine URL
Warum funktioniert unser Fix nicht?
Manchmal liefert das CDN noch das alte HTML aus, oder der Fix steckt im Desktop-Template und Mobilgeräte nutzen ein anderes. Schick mir deine URL und das Problem, dann antworte ich mit ein paar Terminvorschlägen. Ich prüfe zuerst deine Field Data, dann arbeiten wir eine Stunde an deiner Website, und innerhalb eines Tages hast du meine Notizen schriftlich. 350 € zzgl. MwSt.
Schick mir deine URLKein Entwickler für den Fix? Ich mache die Arbeit selbst, auf einer Kopie deiner Website.