Signatur
Beschreibung
ScrollTimeline gehört zur Web Animations API und erbt von AnimationTimeline. Eine normale DocumentTimeline läuft mit der Zeit. Eine ScrollTimeline folgt dagegen dem Scrollfortschritt eines Scroll-Containers: Ganz oben (bzw. links) ist der Fortschritt 0%, am Ende der scrollbaren Strecke 100%. Eine Animation, die an diese Timeline gebunden ist, läuft beim Vor- und Zurückscrollen genau mit.
Typische Einsätze sind Lesefortschrittsbalken, Parallax-Effekte, Kopfzeilen, die beim Scrollen schrumpfen, und Einblend-Effekte. Früher brauchte man dafür scroll-Event-Handler oder einen IntersectionObserver. Scroll-gesteuerte Animationen können dagegen oft direkt auf dem Compositor-Thread laufen, also ohne den Haupt-Thread. Das macht sie deutlich flüssiger.
Die JavaScript-Schnittstelle entspricht der CSS-Funktion scroll() bzw. der Eigenschaft scroll-timeline. Man erzeugt eine Instanz mit new ScrollTimeline({ source, axis }) und übergibt sie als Option timeline an Element.animate() oder an den Konstruktor new Animation(). Wichtige Eigenschaften:
source: das beobachtete Scroll-Element (nur lesbar).axis: die Scrollachse, also"block","inline","x"oder"y"(nur lesbar).currentTime, geerbt: der aktuelle Fortschritt alsCSSUnitValuein Prozent, z. B.CSS.percent(42). Ist der Container nicht scrollbar, ist der Wertnull.
Soll eine Animation vom Sichtbarkeitsbereich eines Elements im Scroll-Container abhängen statt vom Gesamtfortschritt, verwendet man die Unterklasse ViewTimeline.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $options | object | {} | Optionsobjekt für den Konstruktor new ScrollTimeline(options). |
| $options.source | Element | null | document.scrollingElement | Scroll-Container, dessen Fortschritt die Timeline steuert. Standard ist der Dokument-Scroller, meist <html>. |
| $options.axis | "block" | "inline" | "x" | "y" | "block" | Scrollachse. block und inline richten sich nach dem Schreibmodus, x und y sind physische Achsen. |
Rückgabewert
timeline-Option an Element.animate().Beispiele
Lesefortschrittsbalken für die ganze Seite
// HTML: <div id="progress"></div>, fixiert oben, transform-origin: left
const bar = document.querySelector('#progress');
const timeline = new ScrollTimeline({
source: document.documentElement,
axis: 'block'
});
bar.animate(
{ transform: ['scaleX(0)', 'scaleX(1)'] },
{
timeline,
fill: 'both',
easing: 'linear'
}
);
Horizontaler Scroller steuert eine Drehung
const scroller = document.querySelector('.carousel');
const icon = document.querySelector('.carousel-icon');
const timeline = new ScrollTimeline({ source: scroller, axis: 'x' });
const animation = new Animation(
new KeyframeEffect(
icon,
{ rotate: ['0deg', '360deg'] },
{ duration: 1, fill: 'both' } // bei Scroll-Timelines wird die Dauer ignoriert bzw. in Prozent umgerechnet
),
timeline
);
animation.play();
console.log(timeline.source === scroller, timeline.axis);
Aktuellen Fortschritt auslesen mit Feature-Erkennung
if ('ScrollTimeline' in window) {
const timeline = new ScrollTimeline(); // Standard: Dokument-Scroller, Achse block
window.addEventListener('scroll', () => {
const t = timeline.currentTime; // CSSUnitValue oder null
if (t) console.log(`Fortschritt: ${t.value.toFixed(1)}${t.unit === 'percent' ? '%' : t.unit}`);
}, { passive: true });
} else {
console.log('ScrollTimeline wird nicht unterstützt – Fallback nutzen.');
}
// Wichtig · Fallstricke
- Browser-Unterstützung: Chromium-Browser unterstützen die Schnittstelle ab Version 115, Safari ab Version 26. In Firefox ist sie nur über das Flag
layout.css.scroll-driven-animations.enabledverfügbar. Deshalb immer mit'ScrollTimeline' in windowprüfen. Als Ersatz gibt es das Polyfill scroll-timeline von flackr, oder man nutzt einenscroll-Handler. currentTimeist keine Zahl in Millisekunden, sondern einCSSUnitValuein Prozent. Ist die Quelle nicht scrollbar (kein Überlauf,display: none), ist der Wertnullund die Animation inaktiv.- Zeitangaben wie
durationin Millisekunden ergeben bei Scroll-Timelines wenig Sinn. Nutzen Siefill: 'both'undeasing: 'linear', damit die Animation genau dem Scrollen folgt. Den Bereich können Sie überrangeStart/rangeEndeingrenzen. sourceundaxissind nach dem Erzeugen nicht mehr änderbar. Für eine andere Quelle brauchen Sie eine neue Timeline.- Barrierefreiheit: Berücksichtigen Sie
prefers-reduced-motionund schalten Sie starke Bewegungseffekte bei Bedarf ab.