Elemente beim Scrollen mit Scroll-Animationen animieren

Hier erfahren Sie, wie Sie mit Scroll- und Ansichtszeitachsen deklarativ scrollgesteuerte Animationen erstellen.

Veröffentlicht: 5. Mai 2023

Scroll-basierte Animationen

Unterstützte Browser

  • Chrome: 115.
  • Edge: 115.
  • Firefox: hinter einer Flagge.
  • Safari: Nicht unterstützt.

Quelle

Scroll-animierte Elemente sind ein gängiges UX-Muster im Web. Eine scrollgesteuerte Animation ist mit der Scrollposition eines Scrollcontainers verknüpft. Das bedeutet, dass die verknüpfte Animation direkt in die gewünschte Richtung weiterläuft, wenn Sie nach oben oder unten scrollen. Beispiele hierfür sind Effekte wie Parallaxe-Hintergrundbilder oder Leseanzeigen, die sich beim Scrollen bewegen.

Ein Leseanzeiger über einem Dokument, der durch Scrollen gesteuert wird.

Eine ähnliche Art von scrollbasierter Animation ist eine Animation, die mit der Position eines Elements in seinem Scrollcontainer verknüpft ist. So können Elemente beispielsweise einblenden, wenn sie in den Blick kommen.

Die Bilder auf dieser Seite werden eingeblendet, sobald sie in den Blick kommen.

Die klassische Methode, um diese Art von Effekten zu erzielen, besteht darin, auf Scrollereignisse im Hauptthread zu reagieren. Dies führt zu zwei Hauptproblemen:

  • Moderne Browser führen das Scrollen in einem separaten Prozess aus und senden daher Scrollereignisse asynchron.
  • Animationseffekte im Hauptthread können zu Rucklern führen.

Das macht es unmöglich oder sehr schwierig, leistungsstarke scrollbasierte Animationen zu erstellen, die mit dem Scrollen synchronisiert sind.

Ab Chrome-Version 115 gibt es eine neue Reihe von APIs und Konzepten, mit denen Sie deklarative scrollbasierte Animationen aktivieren können: Scroll-Zeitleisten und Ansichtszeitleisten.

Diese neuen Konzepte lassen sich in die vorhandene Web Animations API (WAAPI) und die CSS Animations API einbinden und profitieren so von den Vorteilen dieser APIs. Dazu gehört auch die Möglichkeit, scrollgesteuerte Animationen über den Hauptthread auszuführen. Ja, Sie haben richtig gelesen: Mit nur wenigen zusätzlichen Codezeilen können Sie jetzt flüssige, vom Scrollen gesteuerte Animationen im Hauptthread ausführen. Was gibt es da nicht zu mögen?

Animationen im Web – eine kleine Zusammenfassung

Animationen im Web mit CSS

Wenn Sie eine Animation in CSS erstellen möchten, definieren Sie mit dem Attribut-Regeln @keyframes eine Reihe von Keyframes. Verknüpfen Sie es mit einem Element über die Property animation-name und legen Sie ein animation-duration fest, um zu bestimmen, wie lange die Animation dauern soll. Es gibt weitere animation-*-Langformeigenschaften, z. B. animation-easing-function und animation-fill-mode, die alle in der Kurzform animation kombiniert werden können.

Hier ist beispielsweise eine Animation zu sehen, bei der ein Element auf der X-Achse vergrößert und gleichzeitig seine Hintergrundfarbe geändert wird:

@keyframes scale-up {
  from {
    background-color: red;
    transform: scaleX(0);
  }
  to {
    background-color: darkred;
    transform: scaleX(1);
  }
}

#progressbar {
  animation: 2.5s linear forwards scale-up;
}
.

Animationen im Web mit JavaScript

In JavaScript kann dies mit der Web Animations API erreicht werden. Dazu kannst du entweder neue Animation- und KeyFrameEffect-Instanzen erstellen oder die viel kürzere Element animate()-Methode verwenden.

document.querySelector('#progressbar').animate(
  {
    backgroundColor: ['red', 'darkred'],
    transform: ['scaleX(0)', 'scaleX(1)'],
  },
  {
    duration: 2500,
    fill: 'forwards',
    easing: 'linear',
   }
);

Das visuelle Ergebnis des JavaScript-Snippets oben ist mit der vorherigen CSS-Version identisch.

Animationsabfolgen

Standardmäßig wird eine an ein Element angehängte Animation auf der Dokumentzeitachse ausgeführt. Der Ursprungszeitraum beginnt bei 0, wenn die Seite geladen wird, und läuft mit der Zeit weiter. Dies ist die Standard-Animationszeitachse und bis jetzt die einzige Animationszeitachse, auf die Sie Zugriff hatten.

In der Spezifikation für scrollgesteuerte Animationen werden zwei neue Arten von Zeitleisten definiert, die Sie verwenden können:

  • Zeitachse für den Scrollvorgang: Eine Zeitachse, die mit der Scrollposition eines Scrollcontainers entlang einer bestimmten Achse verknüpft ist.
  • Zeitachse für den Fortschritt ansehen: Eine Zeitachse, die mit der relativen Position eines bestimmten Elements innerhalb seines Scrollcontainers verknüpft ist.

Zeitachse für den Fortschritt scrollen

Eine Scroll-Fortschritts-Zeitachse ist eine Animations-Zeitachse, die mit dem Fortschritt der Scrollposition eines Scrollcontainers – auch Scrollport oder Scroller genannt – entlang einer bestimmten Achse verknüpft ist. Hiermit wird eine Position in einem Scrollbereich in einen Prozentsatz des Fortschritts umgewandelt.

Die Startposition der Bildlaufleiste steht für 0% Fortschritt und die Endposition für 100 %. In der folgenden Visualisierung sehen Sie, dass der Fortschritt von 0% auf 100% ansteigt, wenn Sie den Schieberegler von oben nach unten bewegen.

Visualisierung einer Zeitachse für den Scrollvorgang. Wenn Sie zum Ende des Scrollers scrollen, steigt der Fortschrittswert von 0% auf 100%.

✨ Probieren Sie es selbst aus

Eine Zeitachse für den Scrollvorgang wird oft einfach als „Scroll-Zeitachse“ abgekürzt.

Zeitachse für den Fortschritt ansehen

Diese Art von Zeitachse ist mit dem relativen Fortschritt eines bestimmten Elements innerhalb eines Scrollcontainers verknüpft. Genau wie bei einer Scroll-Fortschrittsleiste wird auch der Scroll-Offset eines Scrollers erfasst. Im Gegensatz zu einer Scroll-Fortschrittsleiste wird der Fortschritt hier durch die relative Position eines Motivs innerhalb des Scrollers bestimmt.

Das ist vergleichbar mit der Funktionsweise von IntersectionObserver, mit der erfasst werden kann, wie viel eines Elements im Scroller sichtbar ist. Wenn das Element im Scroller nicht sichtbar ist, überschneidet es sich nicht. Wenn es im Scroller sichtbar ist, auch nur der kleinste Teil, überschneidet es sich.

Eine Zeitachse für den Wiedergabefortschritt beginnt in dem Moment, in dem ein Motiv mit dem Scroller übereinstimmt, und endet, wenn das Motiv nicht mehr mit dem Scroller übereinstimmt. In der folgenden Visualisierung sehen Sie, dass der Fortschritt von 0% ansteigt, wenn das Testobjekt den Scrollcontainer betritt, und 100% erreicht, sobald das Testobjekt den Scrollcontainer verlässt.

Visualisierung einer Zeitachse für den Fortschritt der Wiedergabe. Der Fortschritt wird von 0% auf 100% gezählt, während das Motiv (grünes Feld) den Scroller passiert.

✨ Probieren Sie es selbst aus

Eine Zeitachse für den Wiedergabeverlauf wird oft einfach als „Zeitachse“ bezeichnet. Es ist möglich, basierend auf der Größe des Motivs auf bestimmte Teile einer Zeitachse für den Wiedergabeverlauf zuzugreifen. Mehr dazu später.

Scroll-Fortschritts-Zeitachsen in der Praxis

Anonyme Scrollvorgang-Zeitachse in CSS erstellen

Die einfachste Methode zum Erstellen einer Scroll-Zeitachse in CSS ist die Verwendung der Funktion scroll(). Dadurch wird eine anonyme Scroll-Zeitachse erstellt, die Sie als Wert für die neue animation-timeline-Property festlegen können.

Beispiel:

@keyframes animate-it { … }

.subject {
  animation: animate-it linear;
  animation-timeline: scroll(root block);
}

Die Funktion scroll() akzeptiert ein <scroller>- und ein <axis>-Argument.

Zulässige Werte für das Argument <scroller>:

  • nearest: Der nächste übergeordnete Scrollcontainer wird verwendet (Standard).
  • root: Der Dokument-Viewport wird als Scrollcontainer verwendet.
  • self: Das Element selbst wird als Scrollcontainer verwendet.

Zulässige Werte für das Argument <axis>:

  • block: Es wird der Fortschritt entlang der Blockachse des Scrollcontainers verwendet (Standard).
  • inline: Der Fortschritt wird anhand der Inline-Achse des Scrollcontainers gemessen.
  • y: Der Fortschritt wird anhand der Y-Achse des Scrollcontainers gemessen.
  • x: Es wird der Fortschritt entlang der X-Achse des Scrollcontainers verwendet.

Wenn Sie beispielsweise eine Animation an den Stamm-Scroller auf der Blockachse binden möchten, sind die Werte root und block für scroll() zu übergeben. Zusammen ergibt das den Wert scroll(root block).

Demo: Fortschrittsanzeige für das Lesen

In dieser Demo ist oben im Darstellungsbereich ein Fortschrittsanzeiger für das Lesen zu sehen. Wenn Sie auf der Seite nach unten scrollen, wird die Fortschrittsanzeige größer, bis sie am Ende des Dokuments die gesamte Breite des Darstellungsbereichs einnimmt. Für die Animation wird eine anonyme Zeitachse für den Scrollvorgang verwendet.

Demo: Lesefortschrittsanzeige

✨ Probieren Sie es selbst aus

Die Lesefortschrittsanzeige ist oben auf der Seite mit der Option „Position fixiert“ positioniert. Bei zusammengesetzten Animationen wird nicht das width animiert, sondern das Element wird mit einem transform auf der X-Achse verkleinert.

<body>
  <div id="progress"></div>
  …
</body>
@keyframes grow-progress {
  from { transform: scaleX(0); }
  to { transform: scaleX(1); }
}

#progress {
  position: fixed;
  left: 0; top: 0;
  width: 100%; height: 1em;
  background: red;

  transform-origin: 0 50%;
  animation: grow-progress auto linear;
  animation-timeline: scroll();
}

Die Zeitachse für die Animation grow-progress auf dem Element #progress ist auf eine anonyme Zeitachse festgelegt, die mit scroll() erstellt wurde. Da für scroll() keine Argumente angegeben werden, werden die Standardwerte verwendet.

Der Standard-Scroller, der erfasst werden soll, ist nearest und die Standardachse ist block. Dadurch wird der Stamm-Scroller effektiv anvisiert, da er der nächstgelegene Scroller des #progress-Elements ist, während die Blockrichtung verfolgt wird.

Eine benannte Zeitachse für den Scrollvorgang in CSS erstellen

Alternativ können Sie eine benannte Zeitachse für den Scrollvorgang verwenden. Diese Methode ist etwas ausführlicher, kann aber nützlich sein, wenn Sie nicht auf einen übergeordneten oder den Stamm-Scroller ausrichten, wenn auf der Seite mehrere Zeitachsen verwendet werden oder wenn automatische Suchanfragen nicht funktionieren. So können Sie eine Scroll-Fortschritts-Zeitachse anhand des von Ihnen festgelegten Namens identifizieren.

Wenn Sie eine benannte Scroll-Fortschritts-Zeitachse für ein Element erstellen möchten, legen Sie für die CSS-Property scroll-timeline-name des Scroll-Containers eine beliebige Kennung fest. Der Wert muss mit -- beginnen.

Wenn Sie festlegen möchten, welche Achse erfasst werden soll, deklarieren Sie auch die Property scroll-timeline-axis. Zulässige Werte sind dieselben wie für das <axis>-Argument von scroll().

Um die Animation mit der Scroll-Fortschritts-Zeitachse zu verknüpfen, legen Sie für das Element, das animiert werden soll, die animation-timeline-Eigenschaft auf denselben Wert wie die für die scroll-timeline-name verwendete Kennung fest.

Codebeispiel:

@keyframes animate-it { … }

.scroller {
  scroll-timeline-name: --my-scroller;
  scroll-timeline-axis: inline;
}

.scroller .subject {
  animation: animate-it linear;
  animation-timeline: --my-scroller;
}

Wenn Sie möchten, können Sie scroll-timeline-name und scroll-timeline-axis in der Kurzform scroll-timeline kombinieren. Beispiel:

scroll-timeline: --my-scroller inline;

In dieser Demo wird über jedem Bildkarussell ein Schritt-Indikator angezeigt. Wenn ein Karussell drei Bilder enthält, beginnt die Anzeigeleiste mit einer Breite von 33 %, um anzuzeigen, dass Sie sich gerade Bild 1 von 3 ansehen. Wenn das letzte Bild angezeigt wird, was daran erkannt wird, dass der Bildlauf nach unten bis zum Ende erfolgt ist, nimmt der Indikator die gesamte Breite des Bildlaufs ein. Für die Animation wird eine benannte Zeitachse für den Scrollvorgang verwendet.

Demo: Schrittanzeige für horizontales Karussell

✨ Probieren Sie es selbst aus

Das Basis-Markup für eine Galerie sieht so aus:

<div class="gallery" style="--num-images: 2;">
  <div class="gallery__scrollcontainer">
    <div class="gallery__progress"></div>
    <div class="gallery__entry">…</div>
    <div class="gallery__entry">…</div>
  </div>
</div>

Das .gallery__progress-Element ist innerhalb des .gallery-Wrapper-Elements absolut positioniert. Die ursprüngliche Größe wird durch das benutzerdefinierte Attribut --num-images bestimmt.

.gallery {
  position: relative;
}


.gallery__progress {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 1em;
  transform: scaleX(calc(1 / var(--num-images)));
}

Das .gallery__scrollcontainer legt die enthaltenen .gallery__entry-Elemente horizontal aus und ist das Element, das gescrollt wird. Durch das Erfassen der Scrollposition wird das .gallery__progress animiert. Dazu wird auf die benannte Zeitachse „Scroll Progress“ (Scrollvorgang) --gallery__scrollcontainer verwiesen.

@keyframes grow-progress {
  to { transform: scaleX(1); }
}

.gallery__scrollcontainer {
  overflow-x: scroll;
  scroll-timeline: --gallery__scrollcontainer inline;
}
.gallery__progress {
  animation: auto grow-progress linear forwards;
  animation-timeline: --gallery__scrollcontainer;
}

Zeitachse für den Scrollvorgang mit JavaScript erstellen

Wenn du eine Scroll-Zeitachse in JavaScript erstellen möchtest, musst du eine neue Instanz der Klasse ScrollTimeline erstellen. Übergeben Sie einen Property-Bag mit den source und axis, die Sie erfassen möchten.

  • source: Ein Verweis auf das Element, dessen Scroller Sie erfassen möchten. Verwenden Sie document.documentElement, um den übergeordneten Scroller auszuwählen.
  • axis: Bestimmt, welche Achse erfasst werden soll. Ähnlich wie bei der CSS-Variante sind block, inline, x und y zulässige Werte.
const tl = new ScrollTimeline({
  source: document.documentElement,
});

Wenn Sie es an eine Webanimation anhängen möchten, geben Sie es als timeline-Eigenschaft ein und lassen Sie duration weg, falls vorhanden.

$el.animate({
  opacity: [0, 1],
}, {
  timeline: tl,
});

Demo: Fortschrittsanzeige für das Lesen, noch einmal

Wenn Sie die Leseprogressanzeige mit JavaScript neu erstellen und dabei dasselbe Markup verwenden möchten, verwenden Sie den folgenden JavaScript-Code:

const $progressbar = document.querySelector('#progress');

$progressbar.style.transformOrigin = '0% 50%';
$progressbar.animate(
  {
    transform: ['scaleX(0)', 'scaleX(1)'],
  },
  {
    fill: 'forwards',
    timeline: new ScrollTimeline({
      source: document.documentElement,
    }),
  }
);

Das visuelle Ergebnis ist in der CSS-Version identisch: Der erstellte timeline verfolgt den Root-Scroller und skaliert den #progress auf der X-Achse von 0% auf 100 %, während Sie auf der Seite scrollen.

✨ Probieren Sie es selbst aus

Die Zeitachse für den Fortschritt der Videowiedergabe

Zeitachse für den Fortschritt der anonymen Wiedergabe in CSS erstellen

Verwenden Sie die Funktion view(), um eine Zeitachse für den Fortschritt der Wiedergabe zu erstellen. Zulässige Argumente sind <axis> und <view-timeline-inset>.

  • <axis> ist mit dem Wert aus der Zeitachse für den Scrollvorgang identisch und definiert, welche Achse erfasst werden soll. Der Standardwert ist block.
  • Mit <view-timeline-inset> können Sie einen positiven oder negativen Offset angeben, um die Grenzen anzupassen, wenn ein Element als sichtbar oder nicht sichtbar betrachtet wird. Der Wert muss ein Prozentsatz oder auto sein. auto ist der Standardwert.

Wenn Sie beispielsweise eine Animation an ein Element binden möchten, das sich auf der Blockachse mit dem Scroller überschneidet, verwenden Sie view(block). Legen Sie dies ähnlich wie bei scroll() als Wert für das Attribut animation-timeline fest und vergessen Sie nicht, animation-duration auf auto zu setzen.

Mit dem folgenden Code wird jedes img eingeblendet, wenn es beim Scrollen den Viewport durchläuft.

@keyframes reveal {
  from { opacity: 0; }
  to { opacity: 1; }
}

img {
  animation: reveal linear;
  animation-timeline: view();
}

Intermezzo: Zeitachsenbereiche ansehen

Standardmäßig wird eine mit der Zeitleiste der Datenansicht verknüpfte Animation auf den gesamten Zeitleistenbereich angewendet. Dieser Zeitraum beginnt, wenn das Motiv in den Scrollbereich eintritt, und endet, wenn es ihn vollständig verlassen hat.

Sie können ihn auch mit einem bestimmten Teil der Zeitachse der Datenansicht verknüpfen, indem Sie den Bereich angeben, an den er angehängt werden soll. Das kann beispielsweise nur der Fall sein, wenn das Motiv in den Scrollbereich eintritt. In der folgenden Visualisierung beginnt der Fortschritt bei 0 %, wenn das Motiv in den Scrollcontainer eintritt, erreicht aber bereits 100 %, sobald es vollständig überschneidet.

Eine Ansichtszeitachse, die so festgelegt ist, dass der Eintragsbereich des Subjekts erfasst wird. Die Animation wird nur ausgeführt, während das Motiv in den Scrollbereich eintritt.

Folgende Zeiträume der Wiedergabezeitachse können Sie als Targeting verwenden:

  • cover: Stellt den gesamten Zeitverlauf des Wiedergabefortschritts dar.
  • entry: Der Bereich, in dem das Hauptfeld in den Sichtbarkeitsbereich für den Wiedergabefortschritt eintritt.
  • exit: Der Bereich, in dem das Hauptfeld den Sichtbarkeitsbereich des Fortschritts der Ansicht verlässt.
  • entry-crossing: Stellt den Bereich dar, in dem der Hauptbereich den Endrand des Rahmens schneidet.
  • exit-crossing: Stellt den Bereich dar, in dem der Hauptbereich die Startgrenze schneidet.
  • contain: Der Bereich, in dem sich das Hauptfeld entweder vollständig innerhalb des Sichtbarkeitsbereichs des Wiedergabefortschritts im Scrollbereich befindet oder diesen vollständig bedeckt. Das hängt davon ab, ob das Motiv höher oder kürzer als der Scroller ist.

Wenn Sie einen Bereich definieren möchten, müssen Sie „Bereich-Start“ und „Bereich-Ende“ festlegen. Jedes besteht aus einem Bereichsnamen (siehe Liste oben) und einem Bereichsoffset, um die Position innerhalb dieses Bereichsnamens zu bestimmen. Der Bereichsoffset ist in der Regel ein Prozentsatz zwischen 0% und 100%. Sie können aber auch eine feste Länge wie 20em angeben.

Wenn Sie beispielsweise eine Animation ab dem Moment ausführen möchten, in dem ein Motiv eintritt, wählen Sie entry 0% als Start des Bereichs aus. Wenn die Animation fertig sein soll, bevor das Subjekt eintritt, wählen Sie entry 100% als Wert für das Ende des Bereichs aus.

In CSS wird dies mit der animation-range-Eigenschaft festgelegt. Beispiel:

animation-range: entry 0% entry 100%;

Verwenden Sie in JavaScript die Properties rangeStart und rangeEnd.

$el.animate(
  keyframes,
  {
    timeline: tl,
    rangeStart: 'entry 0%',
    rangeEnd: 'entry 100%',
  }
);

Im unten eingebetteten Tool sehen Sie, was die einzelnen Bereichsnamen bedeuten und wie sich die Prozentsätze auf die Start- und Endpositionen auswirken. Legen Sie als „Bereichsanfang“ entry 0% und als „Bereichsendpunkt“ cover 50% fest und ziehen Sie dann den Schieberegler, um das Animationsergebnis zu sehen.

Visualisierung der Zeitachsenbereiche, verfügbar unter https://goo.gle/view-timeline-range-tool

Aufzeichnung ansehen

Wie Sie beim Ausprobieren dieses Tools für Zeitachsenbereiche vielleicht feststellen, können einige Bereiche auf zwei verschiedene Kombinationen aus Bereichsname und Bereichsoffset ausgerichtet werden. Beispiel: entry 0%, entry-crossing 0% und cover 0% sind auf denselben Bereich ausgerichtet.

Wenn „Bereichsanfang“ und „Bereichsendpunkt“ auf denselben Bereichsnamen ausgerichtet sind und den gesamten Bereich von 0% bis 100 % abdecken, können Sie den Wert auf den Bereichsnamen verkürzen. So kann beispielsweise animation-range: entry 0% entry 100%; in das viel kürzere animation-range: entry umgeschrieben werden.

Demo: Bild enthüllen

In dieser Demo werden die Bilder eingeblendet, sobald sie den Scrollport erreichen. Dazu wird eine Zeitachse für anonyme Aufrufe verwendet. Der Animationsbereich wurde so angepasst, dass jedes Bild bei halber Scrollposition vollständig undurchsichtig ist.

Demo: Bilder enthüllen

✨ Probieren Sie es selbst aus

Der Ausdehnungseffekt wird durch einen animierten Clip-Pfad erzielt. Hier ist das dafür verwendete CSS:

@keyframes reveal {
  from { opacity: 0; clip-path: inset(0% 60% 0% 50%); }
  to { opacity: 1; clip-path: inset(0% 0% 0% 0%); }
}

.revealing-image {
  animation: auto linear reveal both;
  animation-timeline: view();
  animation-range: entry 25% cover 50%;
}

Zeitachse für den Fortschritt einer Ansicht mit Namen in CSS erstellen

Ähnlich wie bei Scroll-Zeitachsen können Sie auch Ansichtszeitachsen mit Namen erstellen. Anstelle der scroll-timeline-*-Properties verwenden Sie Varianten mit dem Präfix view-timeline-, nämlich view-timeline-name und view-timeline-axis.

Es gelten dieselben Wertetypen und Regeln für das Auffinden einer benannten Zeitachse.

Demo: Bildveröffentlichung, noch einmal

Wenn wir die Demo zur Bildentfaltung von vorhin überarbeiten, sieht der überarbeitete Code so aus:

.revealing-image {
  view-timeline-name: --revealing-image;
  view-timeline-axis: block;

  animation: auto linear reveal both;
  animation-timeline: --revealing-image;
  animation-range: entry 25% cover 50%;
}

Mit view-timeline-name: revealing-image wird das Element im nächstgelegenen Scrollelement erfasst. Derselbe Wert wird dann als Wert für die Property animation-timeline verwendet. Die visuelle Ausgabe ist genau dieselbe wie zuvor.

✨ Probieren Sie es selbst aus

Zeitachse für den Wiedergabefortschritt in JavaScript erstellen

Wenn Sie eine Ansichtszeitachse in JavaScript erstellen möchten, erstellen Sie eine neue Instanz der Klasse ViewTimeline. Übergeben Sie einen Property-Bag mit der subject, die Sie erfassen möchten, axis und inset.

  • subject: Ein Verweis auf das Element, das Sie in seinem eigenen Scroller erfassen möchten.
  • axis: Die Achse, die erfasst werden soll. Ähnlich wie bei der CSS-Variante sind block, inline, x und y zulässige Werte.
  • inset: Ein Einzug (positiv) oder ein Überstand (negativ) des Scrollbereichs, um zu bestimmen, ob das Feld im Blickfeld ist.
const tl = new ViewTimeline({
  subject: document.getElementById('subject'),
});

Wenn Sie es an eine Webanimation anhängen möchten, geben Sie es als timeline-Eigenschaft ein und lassen Sie duration weg, falls vorhanden. Optional können Sie mit den Properties rangeStart und rangeEnd Informationen zum Bereich übergeben.

$el.animate({
  opacity: [0, 1],
}, {
  timeline: tl,
  rangeStart: 'entry 25%',
  rangeEnd: 'cover 50%',
});

✨ Probieren Sie es selbst aus

Weitere Funktionen ausprobieren

Mehrere Zeitachsenbereiche der Ansicht mit einem Satz von Keyframes anhängen

Sehen wir uns diese Demo einer Kontaktliste an, in der die Listeneinträge animiert sind. Wenn ein Listeneintrag von unten in den Scrollbereich eintritt, wird er eingeblendet und eingeblendet. Wenn er den Scrollbereich oben verlässt, wird er ausgeblendet und ausgeblendet.

Demo: Kontaktliste

✨ Probieren Sie es selbst aus

In dieser Demo wird jedes Element mit einer Ansichtszeitachse versehen, die das Element verfolgt, während es seinen Scrollbereich durchläuft. Es sind jedoch zwei scrollbasierte Animationen daran angehängt. Die animate-in-Animation ist mit dem Bereich entry der Zeitachse und die animate-out-Animation mit dem Bereich exit der Zeitachse verknüpft.

@keyframes animate-in {
  0% { opacity: 0; transform: translateY(100%); }
  100% { opacity: 1; transform: translateY(0); }
}
@keyframes animate-out {
  0% { opacity: 1; transform: translateY(0); }
  100% { opacity: 0; transform: translateY(-100%); }
}

#list-view li {
  animation: animate-in linear forwards,
             animate-out linear forwards;
  animation-timeline: view();
  animation-range: entry, exit;
}

Anstatt zwei verschiedene Animationen für zwei verschiedene Bereiche auszuführen, können Sie auch einen Satz von Frames erstellen, der bereits die Bereichsinformationen enthält.

@keyframes animate-in-and-out {
  entry 0%  {
    opacity: 0; transform: translateY(100%);
  }
  entry 100%  {
    opacity: 1; transform: translateY(0);
  }
  exit 0% {
    opacity: 1; transform: translateY(0);
  }
  exit 100% {
    opacity: 0; transform: translateY(-100%);
  }
}

#list-view li {
  animation: linear animate-in-and-out;
  animation-timeline: view();
}

Da die keyframes die Bereichsinformationen enthalten, müssen Sie animation-range nicht angeben. Das Ergebnis ist genau das gleiche wie zuvor.

✨ Probieren Sie es selbst aus

Scrollzeitachse nicht an übergeordnete Elemente anhängen

Der Suchmechanismus für benannte Scroll- und Ansichtszeitachsen ist auf Scrollvorfahren beschränkt. Sehr oft ist das Element, das animiert werden muss, jedoch kein untergeordnetes Element des Scrollers, der erfasst werden muss.

Dazu kommt die Property timeline-scope ins Spiel. Mit dieser Property deklarieren Sie eine Zeitachse mit diesem Namen, ohne sie tatsächlich zu erstellen. Dadurch wird der Zeitplan mit diesem Namen erweitert. In der Praxis verwenden Sie die timeline-scope-Eigenschaft für ein freigegebenes übergeordnetes Element, damit die Zeitachse eines untergeordneten Scrollers daran angehängt werden kann.

Beispiel:

.parent {
  timeline-scope: --tl;
}
.parent .scroller {
  scroll-timeline: --tl;
}
.parent .scroller ~ .subject {
  animation: animate linear;
  animation-timeline: --tl;
}

In diesem Snippet:

  • Das .parent-Element deklariert eine Zeitachse mit dem Namen --tl. Alle untergeordneten Elemente können ihn finden und als Wert für die Property animation-timeline verwenden.
  • Das .scroller-Element definiert tatsächlich eine Scroll-Zeitachse mit dem Namen --tl. Standardmäßig wäre es nur für seine untergeordneten Elemente sichtbar, aber da .parent es als scroll-timeline-root festgelegt hat, wird es daran angehängt.
  • Für das Element .subject wird die Zeitachse --tl verwendet. Es geht den Stammbaum nach oben und findet --tl auf der .parent. Wenn die --tl auf der .parent auf die --tl von .scroller zeigt, verfolgt die .subject im Wesentlichen die Scroll-Fortschrittsleiste der .scroller.

Mit timeline-root können Sie eine Zeitachse also zu einem übergeordneten Element verschieben (Hoisting), damit alle untergeordneten Elemente darauf zugreifen können.

Das Attribut timeline-scope kann sowohl mit Scroll- als auch mit Ansichtszeitachsen verwendet werden.

Weitere Demos und Ressourcen

Alle Demos in diesem Artikel finden Sie auf der Mini-Website „scroll-driven-animations.style“. Auf der Website finden Sie viele weitere Demos, die die Möglichkeiten von scrollbasierten Animationen veranschaulichen.

Eines der zusätzlichen Demos ist diese Liste mit Albumcovern. Jedes Cover dreht sich in 3D, während es im Mittelpunkt steht.

Demo: Cover Flow

✨ Probieren Sie es selbst aus

Oder diese Demo mit gestapelten Karten, in der position: sticky verwendet wird. Wenn die Karten aufeinander gestapelt werden, werden die bereits angepinnten Karten verkleinert, was einen schönen Tiefeneffekt erzeugt. Am Ende verschwindet der gesamte Stapel als Gruppe aus dem Blickfeld.

Demo: Stapelkarten.

✨ Probieren Sie es selbst aus

Auf scroll-driven-animations.style finden Sie auch eine Reihe von Tools wie die Visualisierung des Fortschritts des Zeitachsenbereichs, die bereits in diesem Beitrag erwähnt wurde.

Scroll-basierte Animationen werden auch im Artikel Neuerungen bei Web-Animationen auf der Google I/O 2023 behandelt.