Elemente beim Scrollen mit Scroll-Animationen animieren

Hier erfahren Sie, wie Sie mit Scroll- und View-Zeitachsen deklarative scrollgesteuerte Animationen erstellen.

Veröffentlicht: 5. Mai 2023

Scrollgesteuerte Animationen

Browser Support

  • Chrome: 115.
  • Edge: 115.
  • Firefox: behind a flag.
  • Safari: 26.

Source

Scrollgesteuerte Animationen sind ein häufiges UX-Muster im Web. Eine scrollgesteuerte Animation ist mit der Scrollposition eines Scroll-Containers verknüpft. Das bedeutet, dass die verknüpfte Animation beim Scrollen nach oben oder unten direkt vor- oder zurückgespult wird. Beispiele hierfür sind Effekte wie Parallax-Hintergrundbilder oder Leseindikatoren, die sich beim Scrollen bewegen.

Eine Leseanzeige oben auf einem Dokument, die durch Scrollen gesteuert wird.

Eine ähnliche Art von scrollgesteuerter Animation ist eine Animation, die mit der Position eines Elements in seinem Scroll-Container verknüpft ist. Damit können Elemente beispielsweise eingeblendet werden, wenn sie in den sichtbaren Bereich kommen.

Die Bilder auf dieser Seite werden eingeblendet, wenn sie in den sichtbaren Bereich kommen.

Die klassische Methode, um solche Effekte zu erzielen, besteht darin, auf Scroll-Ereignisse im Hauptthread zu reagieren. Dies führt zu zwei Hauptproblemen:

  • In modernen Browsern wird das Scrollen in einem separaten Prozess ausgeführt. Daher werden Scroll-Ereignisse asynchron übermittelt.
  • Animationen im Hauptthread können ruckeln.

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

Ab Chrome 115 gibt es eine neue Reihe von APIs und Konzepten, mit denen Sie deklarative scrollgesteuerte Animationen aktivieren können: Scroll-Zeitachsen und View-Zeitachsen.

Diese neuen Konzepte werden in die bestehende Web Animations API (WAAPI) und CSS Animations API integriert, sodass sie die Vorteile dieser bestehenden APIs nutzen können. Dazu gehört die Möglichkeit, scrollgesteuerte Animationen außerhalb des Hauptthreads auszuführen. Ja, Sie haben richtig gelesen: Mit nur wenigen zusätzlichen Codezeilen können Sie jetzt flüssige, scrollgesteuerte Animationen außerhalb des Hauptthreads ausführen. Was gibt es da nicht zu mögen?

Animationen im Web – eine kurze Zusammenfassung

Animationen im Web mit CSS

Wenn Sie eine Animation in CSS erstellen möchten, definieren Sie mit der @keyframes-Regel eine Reihe von Keyframes. Verknüpfen Sie es mit einem Element über die animation-name-Eigenschaft und legen Sie gleichzeitig eine animation-duration fest, um die Dauer der Animation zu bestimmen. Es gibt weitere animation-*-Langform-Attribute – animation-easing-function und animation-fill-mode, um nur einige zu nennen –, die alle in der animation-Kurzform kombiniert werden können.

Hier sehen Sie ein Beispiel für eine Animation, bei der ein Element auf der X-Achse vergrößert wird und sich gleichzeitig seine Hintergrundfarbe ändert:

@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 die Web Animations API verwendet werden, um genau dasselbe zu erreichen. Dazu können Sie 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 identisch mit der vorherigen CSS-Version.

Animationszeitachsen

Standardmäßig wird eine Animation, die einem Element zugewiesen ist, auf der Dokumentzeitachse ausgeführt. Die Ursprungszeit beginnt beim Laden der Seite bei 0 und wird mit der Zeit immer größer. Das ist die Standard-Animationszeitachse und war bisher die einzige Animationszeitachse, auf die Sie Zugriff hatten.

In der Scroll-driven Animations Specification werden zwei neue Arten von Zeitachsen definiert, die Sie verwenden können:

  • Zeitachse für Scrollfortschritt: Eine Zeitachse, die mit der Scrollposition eines Scrollcontainers entlang einer bestimmten Achse verknüpft ist.
  • Fortschrittszeitachse: Eine Zeitachse, die mit der relativen Position eines bestimmten Elements in seinem Scroll-Container verknüpft ist.

Scrollen auf der Fortschritts-Zeitachse

Eine Scrollfortschritt-Zeitachse ist eine Animationszeitachse, die mit dem Fortschritt der Scrollposition eines Scrollcontainers (auch Scrollport oder Scroller genannt) entlang einer bestimmten Achse verknüpft ist. Wandelt eine Position in einem Scrollbereich in einen Prozentsatz des Fortschritts um.

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

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

✨ Selbst ausprobieren

Eine Scroll-Fortschritts-Zeitachse wird oft einfach als „Scroll-Zeitachse“ bezeichnet.

Fortschrittszeitachse ansehen

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

Das ist in etwa vergleichbar mit der Funktionsweise von IntersectionObserver, mit der nachverfolgt werden kann, wie viel von einem Element im Scroller sichtbar ist. Wenn das Element nicht im Scroller sichtbar ist, überschneidet es sich nicht. Wenn es im Scroller sichtbar ist, auch nur zum Teil, überschneidet es sich.

Eine Zeitachse für den Fortschritt der Ansicht beginnt, wenn sich ein Motiv mit dem Scroller überschneidet, und endet, wenn sich das Motiv nicht mehr mit dem Scroller überschneidet. In der folgenden Visualisierung sehen Sie, dass der Fortschritt ab 0% gezählt wird, wenn das Motiv in den Scroll-Container eintritt, und 100% erreicht, sobald das Motiv den Scroll-Container verlässt.

Visualisierung einer Zeitachse für den Fortschritt einer Ansicht. Der Fortschritt wird von 0% bis 100% hochgezählt, wenn das Motiv (grünes Rechteck) den Scroller überquert.

✨ Selbst ausprobieren

Eine Ansichtsfortschritt-Zeitachse wird oft einfach als „Ansichtszeitachse“ bezeichnet. Es ist möglich, bestimmte Teile einer Ansichtszeitachse basierend auf der Größe des Motivs auszurichten. Dazu später mehr.

Scroll Progress Timelines in der Praxis

Anonyme Scroll-Fortschritts-Zeitachse in CSS erstellen

Die einfachste Methode zum Erstellen einer Scroll-Zeitleiste 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 die Argumente <scroller> und <axis>.

Für das <scroller>-Argument sind die folgenden Werte zulässig:

  • nearest: Verwendet den nächsten übergeordneten Scrollcontainer (Standard).
  • root: Verwendet den Dokument-Viewport als Scroll-Container.
  • self: Das Element selbst wird als Scrollcontainer verwendet.

Für das <axis>-Argument sind die folgenden Werte zulässig:

  • block: Verwendet das Maß für den Fortschritt entlang der Blockachse des Scrollcontainers (Standard).
  • inline: Verwendet das Maß für den Fortschritt entlang der Inline-Achse des Scroll-Containers.
  • y: Verwendet das Maß für den Fortschritt entlang der Y-Achse des Scroll-Containers.
  • x: Verwendet das Maß für den Fortschritt entlang der X-Achse des Scrollcontainers.

Wenn Sie beispielsweise eine Animation an den Root-Scroller auf der Blockachse binden möchten, sind die Werte, die an scroll() übergeben werden müssen, root und block. Zusammen ergibt sich der Wert scroll(root block).

Demo: Lesefortschrittsanzeige

In dieser Demo ist oben im Darstellungsbereich eine Lesefortschrittsanzeige fixiert. Wenn Sie auf der Seite nach unten scrollen, wird die Fortschrittsanzeige immer größer, bis sie am Ende des Dokuments die gesamte Breite des Darstellungsbereichs einnimmt. Die Animation wird durch eine anonyme Zeitachse für den Scrollfortschritt gesteuert.

Demo: Fortschrittsanzeige

✨ Selbst ausprobieren

Die Lesefortschrittsanzeige wird mit „position: fixed“ oben auf der Seite platziert. 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 für das #progress-Element wird auf eine anonyme Zeitachse festgelegt, die mit scroll() erstellt wird. Für scroll() werden keine Argumente angegeben, sodass die Standardwerte verwendet werden.

Der Standard-Scroller, der erfasst wird, ist nearest und die Standardachse ist block. So wird effektiv auf den Stamm-Scroller ausgerichtet, da er der nächste Scroller des #progress-Elements ist, während seine Blockrichtung erfasst wird.

Benannte Scroll-Fortschritts-Zeitachse in CSS erstellen

Alternativ können Sie eine benannte Scroll-Fortschritts-Zeitachse verwenden. Das ist zwar etwas ausführlicher, kann aber nützlich sein, wenn Sie nicht auf einen übergeordneten oder den Stamm-Scroller ausgerichtet sind, wenn auf der Seite mehrere Zeitachsen verwendet werden oder wenn automatische Suchvorgänge nicht funktionieren. So können Sie eine Scroll-Fortschritts-Zeitachse anhand des Namens identifizieren, den Sie ihr geben.

Wenn Sie für ein Element eine benannte Scroll-Fortschritts-Zeitachse erstellen möchten, legen Sie die CSS-Eigenschaft scroll-timeline-name für den Scroll-Container auf einen beliebigen Bezeichner fest. Der Wert muss mit -- beginnen.

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

Um die Animation mit der Zeitachse für den Scrollfortschritt zu verknüpfen, legen Sie die Eigenschaft animation-timeline für das zu animierende Element auf denselben Wert wie die Kennung fest, die für scroll-timeline-name verwendet wird.

Codebeispiel:

@keyframes animate-it {  }

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

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

Bei Bedarf 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 Schrittindikator angezeigt. Wenn ein Karussell drei Bilder enthält, beginnt die Indikatorleiste mit einer Breite von 33 %, um anzugeben, dass Sie sich gerade das erste von drei Bildern ansehen. Wenn das letzte Bild zu sehen ist (der Scroller wurde also bis zum Ende gescrollt), nimmt die Anzeige die gesamte Breite des Scrollers ein. Eine benannte Zeitachse für den Scrollfortschritt wird verwendet, um die Animation zu steuern.

Demo: Horizontal carousel step indicator.

✨ Selbst ausprobieren

Die grundlegende Markierung 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 absolut innerhalb des .gallery-Wrapper-Elements positioniert. Die ursprüngliche Größe wird durch die benutzerdefinierte Property --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)));
}

Im .gallery__scrollcontainer werden die enthaltenen .gallery__entry-Elemente horizontal angeordnet. Es ist das Element, das gescrollt wird. Durch die Erfassung der Scrollposition wird das .gallery__progress animiert. Dazu wird auf die benannte Scroll-Fortschritts-Zeitachse --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;
}

Scroll-Fortschritts-Zeitachse mit JavaScript erstellen

Um eine Scroll-Timeline in JavaScript zu erstellen, erstellen Sie eine neue Instanz der Klasse ScrollTimeline. Übergeben Sie ein Property-Bag mit den source und axis, die Sie erfassen möchten.

  • source: Eine Referenz auf das Element, dessen Scroller Sie erfassen möchten. Verwenden Sie document.documentElement, um den Stamm-Scroller auszurichten.
  • axis: Gibt an, welche Achse verfolgt werden soll. Ähnlich wie bei der CSS-Variante sind die akzeptierten Werte block, inline, x und y.
const tl = new ScrollTimeline({
  source: document.documentElement,
});

Wenn Sie sie an eine Web-Animation anhängen möchten, übergeben Sie sie als timeline-Attribut und lassen Sie alle duration weg, sofern vorhanden.

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

Demo: Lesefortschrittsanzeige – aktualisiert

Wenn Sie den Lesefortschrittsindikator mit JavaScript und demselben Markup neu erstellen 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 #progress auf der x-Achse von 0% auf 100 %, während Sie auf der Seite scrollen.

✨ Selbst ausprobieren

„Fortschrittszeitachse ansehen“ praktisch nutzen

Fortschrittszeitachse für anonyme Ansichten in CSS erstellen

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

  • <axis> ist dasselbe wie in der Zeitachse für den Scrollfortschritt 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 gilt. 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 diesen Wert 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 beim Scrollen eingeblendet, sobald es in den sichtbaren Bereich kommt.

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

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

Kurzinfo: Zeitachse ansehen

Standardmäßig wird eine mit der Ansichtszeitachse verknüpfte Animation an den gesamten Zeitachsenbereich angehängt. Sie beginnt, wenn das Motiv in den Scrollport eintritt, und endet, wenn es ihn vollständig verlassen hat.

Sie können sie auch mit einem bestimmten Teil der Zeitachse der Ansicht verknüpfen, indem Sie den Bereich angeben, an den sie angehängt werden soll. Das kann beispielsweise nur dann der Fall sein, wenn das Motiv in den Scroller eintritt. In der folgenden Visualisierung beginnt der Fortschritt bei 0 %, wenn das Motiv in den Scroll-Container eintritt. Er erreicht jedoch bereits 100 %, sobald das Motiv vollständig sichtbar ist.

Eine Ansichtszeitachse, die auf den Eingabebereich des Subjekts eingestellt ist. Die Animation wird nur ausgeführt, während das Motiv in den Scrollport eintritt.

Folgende Zeiträume für die Zeitachse sind verfügbar:

  • cover: Stellt den gesamten Bereich der Zeitachse für den Fortschritt der Ansicht dar.
  • entry: Stellt den Bereich dar, in dem das Hauptfeld in den Sichtbarkeitsbereich für den Ansichtsfortschritt eintritt.
  • exit: Stellt den Bereich dar, in dem das Hauptfeld den Sichtbarkeitsbereich für den Fortschritt verlässt.
  • entry-crossing: Stellt den Bereich dar, in dem das Hauptfeld die Endgrenze überschreitet.
  • exit-crossing: Stellt den Bereich dar, in dem das Hauptfeld die Startgrenze überschreitet.
  • contain: Stellt den Bereich dar, in dem das Hauptfeld entweder vollständig im Sichtbarkeitsbereich des Ansichtsfortschritts im Scrollport enthalten ist oder diesen vollständig abdeckt. Das hängt davon ab, ob das Motiv größer oder kleiner als der Scroller ist.

Um einen Bereich zu definieren, müssen Sie einen Bereichsstart und ein Bereichsende festlegen. Jeder besteht aus einem Bereichsnamen (siehe Liste oben) und einem Bereichsoffset, um die Position innerhalb dieses Bereichsnamens zu bestimmen. Das Bereichs-Offset 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 Bereichsstart aus. Wenn die Aktion abgeschlossen sein soll, bevor das Subjekt eintrifft, wählen Sie entry 100% als Wert für das Bereichsende aus.

In CSS legen Sie dies mit der Eigenschaft animation-range fest. Beispiel:

animation-range: entry 0% entry 100%;

Verwenden Sie in JavaScript die Attribute rangeStart und rangeEnd.

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

Mit dem unten eingebetteten Tool können Sie sich ansehen, wofür die einzelnen Bereichsnamen stehen und wie sich die Prozentsätze auf die Start- und Endpositionen auswirken. Legen Sie den Bereichsstart auf entry 0% und das Bereichsende auf cover 50% fest und ziehen Sie dann den Scrollbalken, um das Animationsergebnis zu sehen.

Der View Timeline Ranges Visualizer ist unter https://goo.gle/view-timeline-range-tool verfügbar.

Aufzeichnung ansehen

Wenn Sie mit diesen Tools arbeiten, werden Sie feststellen, dass einige Bereiche durch zwei verschiedene Kombinationen aus Bereichsname und Bereichs-Offset angesprochen werden können. Beispielsweise zielen entry 0%, entry-crossing 0% und cover 0% alle auf denselben Bereich ab.

Wenn die range-start- und range-end-Attribute auf denselben range-name verweisen und den gesamten Bereich von 0% bis 100 % abdecken, können Sie den Wert auf den Bereichsnamen verkürzen. animation-range: entry 0% entry 100%; kann beispielsweise in das viel kürzere animation-range: entry umgeschrieben werden.

Demo: Bild enthüllen

In dieser Demo werden die Bilder eingeblendet, wenn sie in den Scrollport gelangen. Dazu wird eine Zeitachse für anonyme Ansichten verwendet. Der Animationsbereich wurde so angepasst, dass jedes Bild auf halbem Weg des Scrollers die volle Deckkraft erreicht.

Demo: Bild enthüllen

✨ Selbst ausprobieren

Der Expanding-Effekt wird durch die Verwendung eines animierten Clip-Pfads erzielt. Das für diesen Effekt verwendete CSS sieht so aus:

@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%;
}

Benannte Ansichtsfortschritts-Zeitachse in CSS erstellen

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

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

Demo: Bild enthüllen – neu

Der überarbeitete Code für die Demo zum Einblenden von Bildern sieht 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%;
}

Wenn Sie view-timeline-name: revealing-image verwenden, wird das Element im nächstgelegenen Scroller erfasst. Derselbe Wert wird dann als Wert für das Attribut animation-timeline verwendet. Die visuelle Ausgabe ist genau dieselbe wie zuvor.

✨ Selbst ausprobieren

Zeitachse für den Fortschritt der Ansicht in JavaScript erstellen

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

  • subject: Eine Referenz auf das Element, das im eigenen Scroller getrackt werden soll.
  • axis: Die zu verfolgende Achse. Ähnlich wie bei der CSS-Variante sind die akzeptierten Werte block, inline, x und y.
  • inset: Eine positive oder negative Anpassung des Scrollports, um zu ermitteln, ob sich das Feld im Blickfeld befindet.
const tl = new ViewTimeline({
  subject: document.getElementById('subject'),
});

Wenn Sie sie an eine Web-Animation anhängen möchten, übergeben Sie sie als timeline-Attribut und lassen Sie alle duration weg, sofern vorhanden. Optional können Sie Bereichsinformationen mit den Attributen rangeStart und rangeEnd übergeben.

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

✨ Selbst ausprobieren

Weitere Möglichkeiten

Mehrere View Timeline-Bereiche mit einem Satz von Keyframes verknüpfen

Sehen wir uns dieses Beispiel für eine Kontaktliste an, in dem die Listeneinträge animiert sind. Wenn ein Listeneintrag von unten in den Scrollport eintritt, wird er eingeblendet und gleitet nach oben. Wenn er den Scrollport oben verlässt, wird er ausgeblendet und gleitet nach oben.

Demo: Kontaktliste

✨ Selbst ausprobieren

In dieser Demo wird jedes Element mit einer View-Zeitachse versehen, die das Element verfolgt, wenn es den Scrollport durchläuft. Es sind jedoch zwei scrollgesteuerte Animationen daran angehängt. Die animate-in-Animation ist an den entry-Bereich der Zeitachse angehängt und die animate-out-Animation an den exit-Bereich.

@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;
}

Statt zwei verschiedene Animationen zu verwenden, die an zwei unterschiedliche Bereiche angehängt sind, können Sie auch einen Satz von Keyframes 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 dasselbe wie zuvor.

✨ Selbst ausprobieren

An eine Scroll-Zeitleiste anhängen, die kein übergeordnetes Element ist

Der Suchmechanismus für benannte Scroll- und View-Zeitachsen ist auf Scroll-Vorgänger beschränkt. Sehr oft ist das Element, das animiert werden muss, jedoch kein untergeordnetes Element des Scrollers, der verfolgt werden muss.

Dazu wird die Eigenschaft timeline-scope verwendet. Mit dieser Eigenschaft können Sie eine Zeitachse mit diesem Namen deklarieren, ohne sie tatsächlich zu erstellen. Dadurch erhält die Zeitachse mit diesem Namen einen größeren Umfang. In der Praxis verwenden Sie das Attribut timeline-scope für ein gemeinsames ü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 gilt Folgendes:

  • Das Element .parent deklariert eine Zeitachse mit dem Namen --tl. Jedes untergeordnete Element kann es finden und als Wert für die Property animation-timeline verwenden.
  • Das .scroller-Element definiert eine Scroll-Timeline mit dem Namen --tl. Standardmäßig wäre es nur für die Kinder sichtbar, aber da .parent es als scroll-timeline-root festgelegt hat, wird es daran angehängt.
  • Für das .subject-Element wird die --tl-Zeitachse verwendet. Es durchläuft den Stammbaum der Vorfahren und findet --tl auf der .parent. Wenn die --tl auf der .parent auf die --tl von .scroller verweist, wird mit der .subject im Wesentlichen die Zeitachse für den Scrollfortschritt von .scroller erfasst.

Anders ausgedrückt: Mit timeline-root können Sie eine Zeitachse auf ein übergeordnetes Element (auch Hoisting genannt) verschieben, sodass alle untergeordneten Elemente des übergeordneten Elements darauf zugreifen können.

Die Property timeline-scope kann sowohl mit Scroll- als auch mit View-Timelines verwendet werden.

Weitere Demos und Ressourcen

Alle in diesem Artikel behandelten Demos finden Sie auf der Mini-Website scroll-driven-animations.style. Auf der Website finden Sie viele weitere Demos, die zeigen, was mit scrollgesteuerten Animationen möglich ist.

Eines der zusätzlichen Beispiele ist diese Liste mit Albumcovern. Jedes Cover wird in 3D gedreht, wenn es im Mittelpunkt steht.

Demo: Cover Flow

✨ Selbst ausprobieren

Oder diese Demo für das Stapeln von Karten, bei der position: sticky verwendet wird. Wenn die Karten gestapelt werden, werden die bereits angezeigten Karten verkleinert, wodurch ein schöner Tiefeneffekt entsteht. Am Ende gleitet der gesamte Stapel als Gruppe aus dem Blickfeld.

Demo: Karten stapeln.

✨ Selbst ausprobieren

Auf Auch auf scroll-driven-animations.style finden Sie eine Sammlung von Tools wie die Visualisierung des View Timeline Range Progress, die weiter oben in diesem Beitrag enthalten war.

Scrollgesteuerte Animationen werden auch im Google I/O 2023-Vortrag What’s new in Web Animations behandelt.