Signatur
Beschreibung
Der Konstruktor ViewTimeline() gehört zur API für Scroll-gesteuerte Animationen (Scroll-driven Animations). Er erzeugt eine Zeitleiste, deren Fortschritt nicht von der Uhrzeit abhängt, sondern von der Sichtbarkeit eines bestimmten Elements, des subject, in seinem nächsten scrollbaren Vorfahren. Der Fortschritt steigt von 0 % (das Element taucht gerade am Rand des Scrollbereichs auf) bis 100 % (das Element hat den Bereich auf der anderen Seite ganz verlassen).
Typische Einsatzfälle sind Einblend-Effekte beim Scrollen („Reveal on Scroll“), Parallax-Effekte, Fortschrittsanzeigen für einzelne Abschnitte oder Bilder, die beim Durchscrollen gezoomt werden. Das geht ganz ohne scroll-Event-Listener oder IntersectionObserver. Die Animation läuft auf dem Compositor-Thread und ruckelt daher deutlich weniger.
Die erzeugte Timeline übergibst du als timeline-Option an Element.animate() oder an den Konstruktor new Animation(). Mit rangeStart und rangeEnd (z. B. "entry 0%", "cover 50%") legst du fest, in welcher Phase der Sichtbarkeit die Animation abläuft. In CSS entspricht das den Eigenschaften view-timeline bzw. der Funktion animation-timeline: view().
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $options | object | {} | Optionales Konfigurationsobjekt mit den folgenden Eigenschaften. |
| $options.subject | Element | null | Das Element, dessen Sichtbarkeit die Zeitleiste steuert. Als Quelle (source) dient automatisch der nächste scrollbare Vorfahre dieses Elements. |
| $options.axis | "block" | "inline" | "x" | "y" | "block" | Die Scroll-Achse, die ausgewertet wird. block und inline richten sich nach dem Schreibmodus, x und y sind feste Achsen. |
| $options.inset | string | Array<CSSNumericValue | CSSKeywordValue | string> | "auto" | Verkleinert oder vergrößert den Sichtbereich, in dem das Element als sichtbar gilt, z. B. "100px 20%" (Start- und End-Einzug). Entspricht der CSS-Eigenschaft view-timeline-inset. |
Rückgabewert
ViewTimeline-Instanz mit den Eigenschaften subject, startOffset, endOffset sowie den von ScrollTimeline geerbten Eigenschaften source, axis und currentTime.Beispiele
Karte beim Hereinscrollen einblenden
const card = document.querySelector('.card');
const timeline = new ViewTimeline({
subject: card,
axis: 'block'
});
// Einblenden, während die Karte den Sichtbereich betritt
card.animate(
[
{ opacity: 0, transform: 'translateY(40px)' },
{ opacity: 1, transform: 'translateY(0)' }
],
{
timeline,
fill: 'both',
rangeStart: 'entry 0%',
rangeEnd: 'entry 100%'
}
);
Mehrere Bilder mit Feature-Erkennung animieren
const images = document.querySelectorAll('.gallery img');
if ('ViewTimeline' in window) {
images.forEach((img) => {
const timeline = new ViewTimeline({ subject: img });
img.animate(
[{ transform: 'scale(0.8)' }, { transform: 'scale(1)' }],
{ timeline, fill: 'both', rangeStart: 'cover 0%', rangeEnd: 'cover 50%' }
);
});
} else {
// Fallback: Bilder einfach ohne Animation anzeigen
images.forEach((img) => img.style.transform = 'none');
console.log('ViewTimeline wird nicht unterstützt');
}
Inset setzen und Fortschritt auslesen
const section = document.querySelector('#kapitel-2');
const timeline = new ViewTimeline({
subject: section,
axis: 'y',
inset: '80px 0px' // z. B. Platz für eine fixierte Kopfzeile
});
console.log(timeline.subject === section); // true
console.log(timeline.axis); // "y"
document.addEventListener('scroll', () => {
// currentTime ist ein CSSUnitValue in Prozent (oder null)
const progress = timeline.currentTime;
if (progress) console.log(`Fortschritt: ${progress.value.toFixed(1)} %`);
}, { passive: true });
// Wichtig · Fallstricke
- Browser-Unterstützung: Verfügbar in Chromium-basierten Browsern ab Version 115 und in Safari ab 26. In Firefox ist die API nur hinter dem Flag
layout.css.scroll-driven-animations.enablednutzbar. Prüfe sie daher immer mit'ViewTimeline' in windowoder nutze ein Polyfill (z. B. scroll-timeline von flackr). - Hat das
subjectkeinen scrollbaren Vorfahren oder ist es nicht gerendert (display: none), ist die Timeline inaktiv undcurrentTimeistnull. - Scroll-gesteuerte Animationen haben keine Zeitdauer. Gib deshalb keine
durationin Millisekunden an. Die Phase steuerst du überrangeStart/rangeEnd, also z. B.entry,exit,coverundcontain. - Mit
fill: 'both'verhinderst du, dass das Element außerhalb des Animationsbereichs auf seinen Ausgangszustand zurückspringt. - Barrierefreiheit: Berücksichtige
prefers-reduced-motionund lass bei aktivierter Einstellung auffällige Bewegungen weg.