Erste Schritte mit scrollbaren Animationen in CSS

1. Hinweis

Bei Scroll-Animationen können Sie die Wiedergabe einer Animation basierend auf der Scrollposition eines Scrollcontainers steuern. Wenn Sie also nach oben oder unten scrollen, gleitet die Animation vor oder zurück. Darüber hinaus können Sie mit scrollbaren Animationen eine Animation auch basierend auf der Position eines Elements innerhalb des Scroll-Containers steuern. Auf diese Weise können Sie interessante Effekte erstellen, z. B. ein Parallaxe-Hintergrundbild, Bildlaufleisten und Bilder, die sich in der Anzeige sichtbar machen.

Neu in Chrome 115 ist die Unterstützung einer Reihe von JavaScript-Klassen und CSS-Eigenschaften, mit denen Sie ganz einfach deklarative, scrollbare Animationen erstellen können. Diese neuen APIs funktionieren mit vorhandenen Web Animations und CSS Animations APIs.

In diesem Codelab erfahren Sie, wie Sie mithilfe von CSS scrollbare Animationen erstellen. In diesem Codelab machen Sie sich mit den vielen neuen CSS-Eigenschaften vertraut, die durch diese spannende Funktion eingeführt werden, z. B. scroll-timeline, view-timeline, animation-timeline und animation-range.

Lerninhalte

  • Hier erfahren Sie, wie Sie in CSS mit einer Scroll-Zeitachse einen Parallaxe-Hintergrundeffekt erstellen.
  • So erstellen Sie eine Fortschrittsanzeige mit einer Scroll-Zeitachse in CSS.
  • Hier erfahren Sie, wie Sie in CSS einen Effekt zur Bilddarstellung mit einer Zeitachse erstellen.
  • Hier erfahren Sie, wie Sie ein Targeting auf verschiedene Arten von Bereichen einer Zeitachse in CSS festlegen.

Voraussetzungen

Eine der folgenden Gerätekombinationen:

  • Eine aktuelle Version von Chrome (115 oder höher) unter ChromeOS, macOS oder Windows mit den „Experimental Web Platform Features“ aktiviert.
  • Grundlegende HTML-Kenntnisse
  • Grundlegendes Verständnis von CSS, insbesondere Animationen in CSS

2. Einrichten

Alles, was Sie für dieses Projekt benötigen, ist in einem GitHub-Repository verfügbar. Klonen Sie zuerst den Code und öffnen Sie ihn in Ihrer bevorzugten Entwicklungsumgebung.

  1. Öffnen Sie einen neuen Browsertab und rufen Sie https://github.com/googlechromelabs/io23-scroll-driven-animations-codelab auf.
  2. Klonen Sie das Repository.
  3. Öffnen Sie den Code in Ihrer bevorzugten IDE.
  4. Führen Sie npm install aus, um die Abhängigkeiten zu installieren.
  5. Führen Sie npm start aus und rufen Sie http://localhost:3000/ auf.
  6. Wenn du npm nicht installiert hast, kannst du alternativ die Datei src/index.html in Chrome öffnen.

3. Weitere Informationen zu Animationszeitachsen

Standardmäßig wird eine Animation, die an ein Element angehängt ist, auf der Dokumentzeitachse ausgeführt. Das bedeutet, dass sich die Animation beim Laden der Seite im Laufe der Zeit vorwärts bewegt. Dies ist die Standard-Animationszeitachse. Bis jetzt war dies die einzige Animationszeitachse, auf die Sie Zugriff hatten.

Mit scrollbaren Animationen erhalten Sie Zugriff auf zwei neue Arten von Zeitachsen:

  • Scroll-Fortschritt auf der Zeitachse
  • Fortschritts-Zeitachse anzeigen

In CSS können diese Zeitachsen mithilfe der Eigenschaft animation-timeline an eine Animation angehängt werden. Sieh dir an, was diese neuen Zeitpläne bedeuten und wie sie sich voneinander unterscheiden.

Scroll-Fortschritt auf der Zeitachse

Eine Zeitachse für den Scrollfortschritt ist eine Animationszeitachse, die mit dem Fortschritt an der Scrollposition eines Scrollcontainers – auch Scrollport oder Scroller – entlang einer bestimmten Achse verbunden ist. Sie wandelt eine Position in einem Scrollbereich in einen Prozentsatz des Fortschritts entlang einer Zeitachse um.

Die anfängliche Scrollposition entspricht einem Fortschritt von 0% und die letzte Scrollposition einen Fortschritt von 100 %. In der folgenden Visualisierung sehen Sie, dass sich der Fortschritt von 0% bis 100% erhöht, wenn Sie beim Scrollen nach unten scrollen.

Fortschritts-Zeitachse anzeigen

Diese Art von Zeitachse ist mit dem relativen Fortschritt eines bestimmten Elements innerhalb eines Scroll-Containers verknüpft. Genau wie bei einer Zeitachse für den Scroll-Fortschritt wird der Scroll-Offset eines Scrollers erfasst. Im Gegensatz zu einer Zeitachse für den Scrollfortschritt bestimmt die relative Position eines Objekts innerhalb dieses Scrollers den Fortschritt. Dieser Wert ist mit IntersectionObserver vergleichbar, der erfasst, wie viel ein Element im Scroller sichtbar ist. Wenn das Element beim Scrollen nicht sichtbar ist, überschneidet es sich nicht. Wenn es innerhalb des Scrollers sichtbar ist – selbst für den kleinsten Teil –, überschneidet es sich.

Eine Zeitachse des Anzeigefortschritts beginnt an dem Zeitpunkt, an dem sich ein Motiv mit dem Scroller überschneidet, und endet, wenn das Motiv den Scroller nicht mehr kreuzt. In der folgenden Visualisierung sehen Sie, dass der Fortschritt ab 0% hochgezählt wird, wenn das Thema den Scroll-Container betritt, und bis 100% erreicht ist, wenn es den Scroll-Container verlässt.

Standardmäßig wird eine Animation, die mit der Zeitleiste des Fortschritts verknüpft ist, an den gesamten Bereich angehängt. Dies beginnt an dem Moment, an dem das Subjekt den Scrollport betritt, und endet, wenn es den Scrollport verlässt.

Sie können sie auch mit einem bestimmten Teil der Zeitachse für die Fortschrittsanzeige verknüpfen, indem Sie den Bereich angeben, zu dem sie gehören soll. Dies kann beispielsweise nur der Fall sein, wenn das Motiv in den Bildlaufbereich eintritt. In der folgenden Visualisierung wird der Fortschritt bei 0% hochgezählt, wenn das Subjekt in den Scrollcontainer gelangt, aber er erreicht bereits 100% ab dem Zeitpunkt, an dem es sich vollständig überschneidet.

Die möglichen Bereiche der Zeitachse für die Datenansicht, auf die Sie Ihre Anzeigen ausrichten können, sind cover, contain, entry, exit, entry-crossing und exit-crossing. Diese Bereiche werden später in diesem Codelab erläutert. Wenn Sie es jedoch nicht abwarten können, können Sie das Tool unter https://goo.gle/view-timeline-range-tool verwenden, um zu sehen, was die einzelnen Bereiche darstellen.

4. Hintergrundeffekt mit Parallaxe erstellen

Der erste Effekt, der der Seite hinzugefügt werden soll, ist ein Parallaxe-Hintergrundeffekt auf das Haupthintergrundbild. Wenn Sie auf der Seite nach unten scrollen, sollte sich das Hintergrundbild bewegen, allerdings mit einer anderen Geschwindigkeit. Dazu benötigen Sie eine Zeitachse für den Scroll-Fortschritt.

Zur Implementierung sind zwei Schritte erforderlich:

  1. Erstellen Sie eine Animation, bei der die Position des Hintergrundbilds verschoben wird.
  2. Die Animation mit dem Scrollfortschritt des Dokuments verknüpfen.

Animation erstellen

  1. Verwenden Sie zum Erstellen der Animation einen regulären Satz von Keyframes. Verschieben Sie hier die Hintergrundposition von 0% vertikal auf 100%:

src/styles.css

@keyframes move-background {
  from {
    background-position: 50% 0%;
  }
  to {
    background-position: 50% 100%;
  }
}
  1. Fügen Sie diese Keyframes nun an das Body-Element an:

src/styles.css

body {
  animation: 1s linear move-background;
}

Mit diesem Code wird die move-background-Animation zum <body>-Element hinzugefügt. Das Attribut animation-duration ist auf eine Sekunde festgelegt und verwendet ein Easing vom Typ linear.

Am einfachsten lässt sich eine Zeitachse für den Scrollfortschritt erstellen, indem Sie die Funktion scroll() verwenden. Dadurch wird eine anonyme Zeitachse für den Scrollfortschritt erstellt, die Sie als Wert für die Eigenschaft animation-timeline festlegen können.

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

Für das Argument <scroller> sind folgende Werte zulässig:

  • nearest Verwendet den Scroll-Container des nächstgelegenen Ancestors (Standard).
  • root Verwendet den Darstellungsbereich des Dokuments als Scroll-Container.
  • self Verwendet das Element selbst als Scroll-Container.

Für das Argument <axis> sind folgende Werte zulässig:

  • block Verwendet das Maß des Fortschritts entlang der Blockachse des Scrollcontainers (Standardeinstellung).
  • inline Verwendet das Maß des Fortschritts entlang der Inline-Achse des Scroll-Containers.
  • y Verwendet das Maß des Fortschritts entlang der Y-Achse des Scroll-Containers.
  • x Verwendet das Maß des Fortschritts entlang der x-Achse des Scroll-Containers.

Um die Animation mit dem Stamm-Scroller auf der Blockachse zu verknüpfen, müssen die Werte root und block an scroll() übergeben werden. Insgesamt beträgt der Wert scroll(root block).

  • Legen Sie scroll(root block) als Wert für das Attribut animation-timeline im Text fest.
  • Da ein in Sekunden ausgedrücktes animation-duration keinen Sinn ergibt, sollten Sie die Dauer auf auto festlegen. Wenn Sie keine animation-duration angeben, wird standardmäßig auto verwendet.

src/styles.css

body {
  animation: linear move-background;
  animation-duration: auto;
  animation-timeline: scroll(root block);
}

Da der Root-Scroller auch der nächstgelegene übergeordnete Scroller für das body-Element ist, können Sie auch den Wert nearest verwenden:

src/styles.css

body {
  animation: linear move-background;
  animation-duration: auto;
  animation-timeline: scroll(nearest block);
}

Da nearest und block die Standardwerte sind, können Sie sie sogar weglassen. In diesem Fall kann der Code so vereinfacht werden:

src/styles.css

body {
  animation: linear move-background;
  animation-duration: auto;
  animation-timeline: scroll();
}

Änderungen prüfen

Wenn alles gut gelaufen ist, sollten Sie jetzt Folgendes erhalten:

Ist dies nicht der Fall, sehen Sie sich den solution-step-1-Branch des Codes an.

5. Fortschrittsanzeige für die Bildergalerie erstellen

Auf der Seite befindet sich ein horizontales Karussell, das anhand einer Fortschrittsanzeige anzeigt, welches Foto Sie sich gerade ansehen.

Die Auszeichnung für das Karussell sieht so aus:

src/index.html

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

Die Keyframes für die Fortschrittsanzeige sind bereits vorhanden und sehen wie folgt aus:

src/styles.css

@keyframes adjust-progress {
  from {
    transform: scaleX(calc(1 / var(--num-images)));
  }
  to {
    transform: scaleX(1);
  }
}

Diese Animation muss an angehängt werden .gallery__progress-Element mit einer Scroll-Fortschritts-Zeitachse. Wie im vorherigen Schritt gezeigt, können Sie dies erreichen, indem Sie mit der Funktion scroll() eine anonyme Zeitachse für den Scroll-Fortschritt erstellen:

src/styles.css

.gallery__progress {
  animation: linear adjust-progress;
  animation-duration: auto;
  animation-timeline: scroll(nearest inline);
}

Dieses Code-Snippet scheint zu funktionieren, liegt aber nicht an der Funktionsweise der automatischen Scroll-Container-Suche mit nearest. Bei der Suche nach dem nächsten Scroller berücksichtigt das Element nur die Elemente, die sich auf seine Position auswirken können. Da .gallery__progress absolut positioniert ist, ist das erste übergeordnete Element, das seine Position bestimmt, das .gallery-Element, auf das position: relative angewendet wurde. Das bedeutet, dass das .gallery__scrollcontainer-Element – der Scroller, auf den das Targeting erfolgen muss – bei dieser automatischen Suche überhaupt nicht berücksichtigt wird.

Sie können dieses Problem umgehen, indem Sie eine benannte Scroll-Fortschritts-Zeitachse für das .gallery__scrollcontainer-Element erstellen und das .gallery__progress unter diesem Namen damit verknüpfen.

Wenn Sie eine benannte Scrollfortschritt-Zeitachse für ein Element erstellen möchten, legen Sie die CSS-Eigenschaft scroll-timeline-name im Scrollcontainer auf einen gewünschten Wert fest. Der Wert muss mit -- beginnen.

Da in der Galerie horizontal gescrollt wird, müssen Sie auch die Eigenschaft scroll-timeline-axis festlegen. Zulässige Werte sind dieselben wie für das Argument <axis> von scroll().

Um die Animation mit der Zeitachse für den Scroll-Fortschritt zu verknüpfen, legen Sie schließlich die Eigenschaft animation-timeline des zu animierten Elements auf denselben Wert fest wie die Kennung für scroll-timeline-name.

  • Ändern Sie die Datei styles.css so, dass sie Folgendes enthält:

src/styles.css

.gallery__scrollcontainer {
  /* Create the gallery-is-scrolling timeline */
  scroll-timeline-name: --gallery-is-scrolling;
  scroll-timeline-axis: inline;
}

.gallery__progress {
  animation: linear adjust-progress;
  animation-duration: auto;
  /* Set gallery-is-scrolling as the timeline */
  animation-timeline: --gallery-is-scrolling;
}

Änderungen prüfen

Wenn alles gut gelaufen ist, sollten Sie jetzt Folgendes erhalten:

Ist dies nicht der Fall, sehen Sie sich den solution-step-2-Branch des Codes an.

6. Galeriebilder beim Betreten und Verlassen des Scrollport animieren

Anonyme Zeitachse für den Wiedergabefortschritt einrichten

Ein schöner Effekt ist, dass die Galeriebilder ausgeblendet werden, wenn sie angezeigt werden. Dazu können Sie eine Zeitachse für den Fortschritt verwenden.

Mit der Funktion view() können Sie eine Zeitachse für den Fortschritt erstellen. Die zulässigen Argumente sind <axis> und <view-timeline-inset>.

  • <axis> ist identisch mit der Zeitachse für den Scrollfortschritt und definiert, welche Achse verfolgt werden soll.
  • Mit <view-timeline-inset> können Sie einen Versatz (positiv oder negativ) angeben, um die Grenzen anzupassen, wenn ein Element als sichtbar angesehen wird oder nicht.
  • Die Keyframes sind bereits vorhanden, sodass Sie sie nur noch anbringen müssen. Erstellen Sie dazu für jedes .gallery__entry-Element eine Zeitachse für den Fortschritt.

src/styles.css

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

.gallery__entry {
  animation: linear animate-in;
  animation-duration: auto;
  animation-timeline: view(inline);
}

Den Bereich einer Zeitachse für den Aufruffortschritt einschränken

Wenn Sie den CSS-Code speichern und die Seite laden, werden die Elemente eingeblendet, doch etwas scheint nicht zu stimmen. Sie beginnen bei der Deckkraft 0, wenn sie vollständig außerhalb des Sichtbereichs liegen, und enden bei der Deckkraft 1 erst, wenn sie vollständig ausgeblendet sind.

Das liegt daran, dass der Standardbereich für eine Zeitachse des Aufrufverlaufs der gesamte Bereich ist. Dies wird als cover-Bereich bezeichnet.

  1. Wenn Sie nur den entry-Bereich des Objekts ausrichten möchten, verwenden Sie die CSS-Eigenschaft animation-range, um die Ausführung der Animation einzuschränken.

src/styles.css

.gallery__entry {
  animation: linear fade-in;
  animation-duration: auto;
  animation-timeline: view(inline);
  animation-range: entry 0% entry 100%;
}

Die Animation läuft jetzt von entry 0% (das Motiv beginnt gleich den Scroller) bis entry 100% (das Motiv hat den Bildlauf vollständig betreten).

Folgende Bereiche der Zeitachse sind möglich:

  • cover Gesamter Bereich der Zeitachse für den Aufruffortschritt
  • entry Stellt den Bereich dar, in dem das Hauptkontofeld in den Sichtbarkeitsbereich des Ansichtsfortschritts eintritt.
  • exit Stellt den Bereich dar, in dem das Hauptkontofeld den Sichtbarkeitsbereich des Ansichtsfortschritts verlässt.
  • entry-crossing Der Bereich, in dem der Hauptrahmen den Endrahmen überschreitet.
  • exit-crossing Der Bereich, in dem der Hauptrahmen den Startrand überschreitet.
  • contain Gibt den Bereich an, in dem das Hauptkontofeld innerhalb des Scrollports entweder vollständig in den Sichtbarkeitsbereich des Ansichtsfortschritts eingeschlossen oder vollständig überdeckt ist. Das hängt davon ab, ob das Motiv größer oder kürzer als der Scroller ist.

Mit dem Tool unter https://goo.gle/view-timeline-range-tool können Sie herausfinden, wofür die einzelnen Bereiche stehen und wie sich die Prozentsätze auf die Start- und Endpositionen auswirken.

  1. Da die Start- und Endbereiche hier identisch sind und die Standard-Offsets verwendet werden, vereinfachen Sie animation-range, indem Sie einen einzelnen Animationsbereichnamen angeben:

src/styles.css

.gallery__entry {
  animation: linear animate-in;
  animation-duration: auto;
  animation-timeline: view(inline);
  animation-range: entry;
}
  • Um die Bilder beim Verlassen des Scrollers auszublenden, können Sie genauso vorgehen wie bei der animierten Animation, jedoch mit einem anderen Bereich.

src/styles.css

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

.gallery__entry {
  animation: linear animate-in, linear animate-out;
  animation-duration: auto;
  animation-timeline: view(inline);
  animation-range: entry, exit;
}

Die Keyframes animate-in werden auf den Bereich entry und die Keyframes animate-out auf den Bereich exit angewendet.

Änderungen prüfen

Wenn alles gut gelaufen ist, sollten Sie jetzt Folgendes erhalten:

Ist dies nicht der Fall, sehen Sie sich den solution-step-3-Branch des Codes an.

7. Mit einem Satz von Keyframes können Sie die Galeriebilder animieren, während sie den Scrollport betreten und verlassen.

Ein Beispiel für eine Reihe von Keyframes,

Anstatt zwei Animationen verschiedenen Bereichen zuzuweisen, können Sie einen Satz von Keyframes erstellen, der bereits die Bereichsinformationen enthält.

Die Form der Keyframes sieht so aus:

@keyframes keyframes-name {
  range-name range-offset {
    ...
  }
  range-name range-offset {
    ...
  }
}
  1. Kombinieren Sie die Ein- und Ausblendungs-Keyframes wie folgt:

src/styles.css

@keyframes animate-in-and-out {
  entry 0% {
    opacity: 0;
    clip-path: inset(50% 0% 50% 0%);
  }
  entry 90% {
    opacity: 1;
    clip-path: inset(0% 0% 0% 0%);
  }

  exit 10% {
    opacity: 1;
    clip-path: inset(0% 0% 0% 0%);
  }
  exit 100% {
    opacity: 0;
    clip-path: inset(50% 0% 50% 0%);
  }
}
  1. Wenn die Bereichsinformationen in den Keyframes vorhanden sind, müssen Sie animation-range nicht mehr separat angeben. Hängen Sie die Keyframes als animation-Eigenschaft an.

src/styles.css

.gallery__entry {
  animation: linear animate-in-and-out both;
  animation-duration: auto;
  animation-timeline: view(inline);
}

Änderungen prüfen

Wenn alles gut gelaufen ist, sollten Sie dasselbe Ergebnis wie im vorherigen Schritt erhalten. Ist dies nicht der Fall, sehen Sie sich den solution-step-4-Branch des Codes an.

8. Glückwunsch!

Sie haben dieses Codelab abgeschlossen und wissen jetzt, wie Sie Zeitachsen für den Scroll- und Fortschrittsfortschritt in CSS erstellen.

Weitere Informationen

Ressourcen: