Start · Sprachen · JavaScript · Referenz · ScrollTimeline

ScrollTimeline

Schnittstelle

Stellt eine Scroll-Fortschritts-Timeline dar: Der Fortschritt einer Animation hängt an der Scrollposition eines Containers statt an der Zeit.

seit JavaScript Chrome/Edge 115+, Safari 26+; Firefox nur hinter F Kategorie: webapi

Signatur

interface ScrollTimeline extends AnimationTimeline

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 als CSSUnitValue in Prozent, z. B. CSS.percent(42). Ist der Container nicht scrollbar, ist der Wert null.

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

Typ
ScrollTimeline
Beschreibung
Neue Timeline-Instanz. Man übergibt sie z. B. als 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);
true "x"

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.');
}
Fortschritt: 37.4%

// 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.enabled verfügbar. Deshalb immer mit 'ScrollTimeline' in window prüfen. Als Ersatz gibt es das Polyfill scroll-timeline von flackr, oder man nutzt einen scroll-Handler.
  • currentTime ist keine Zahl in Millisekunden, sondern ein CSSUnitValue in Prozent. Ist die Quelle nicht scrollbar (kein Überlauf, display: none), ist der Wert null und die Animation inaktiv.
  • Zeitangaben wie duration in Millisekunden ergeben bei Scroll-Timelines wenig Sinn. Nutzen Sie fill: 'both' und easing: 'linear', damit die Animation genau dem Scrollen folgt. Den Bereich können Sie über rangeStart/rangeEnd eingrenzen.
  • source und axis sind nach dem Erzeugen nicht mehr änderbar. Für eine andere Quelle brauchen Sie eine neue Timeline.
  • Barrierefreiheit: Berücksichtigen Sie prefers-reduced-motion und schalten Sie starke Bewegungseffekte bei Bedarf ab.