Die Spezifikation für Scroll-Linked Animations ist eine kommende und experimentelle Erweiterung von CSS. Dank der @scroll-timeline At-Regel und der animation-timeline Eigenschaft, die diese Spezifikation bietet, können Sie die Zeitposition regulärer CSS-Animationen durch Scrollen steuern.
In diesem Beitrag werden wir einige praktische Anwendungsfälle untersuchen, bei denen scroll-verknüpfte Animationen nützlich sind und wie sie das Surferlebnis Ihrer Besucher bereichern können.
👨🔬 Die in diesem Beitrag beschriebenen CSS-Funktionen sind noch experimentell und keineswegs endgültig. Sie werden zum Zeitpunkt des Schreibens von keinem Browser unterstützt, außer von Chromium ≥ 89 mit aktiviertem Flag „Experimental Web Platform Features“.
CSS Scroll-Linked Animations, eine kurze Einführung
Mit den in der Spezifikation für Scroll-Linked Animations beschriebenen Funktionen können Sie eine CSS-Animation durch Scrollen steuern: Wenn Sie beim Scrollen nach oben oder unten durch einen Scroll-Container blättern, wird die verknüpfte CSS-Animation entsprechend vor- oder zurückgespult. Diese scroll-verknüpften Animationen können Ihren Seiten eine sehr schöne Note verleihen.
Obwohl es bereits mehrere JavaScript-Bibliotheken zur Implementierung dieser Scroll-Linked Animations gibt,unterscheidet sich die Spezifikation für Scroll-Linked Animations von diesen durch
- Bereitstellung einer JS- und einer CSS-Schnittstelle zur Implementierung dieser Effekte
- Beibehaltung der Leistung, da die Animationen auf dem Compositor ausgeführt werden (z.B. „off main thread“)
Während die Spezifikation für Scroll-Linked Animations auch eine JavaScript-Schnittstelle beschreibt, die sich gut in die Web Animations API integriert, konzentriert sich dieser Beitrag nur auf ihr CSS-Gegenstück.
Um eine grundlegende scroll-verknüpfte Animation in CSS zu implementieren, benötigen Sie drei Schlüsselelemente
- eine CSS-Animation
- eine Scroll-Timeline
- eine Verknüpfung zwischen beiden
CSS-Animation
Dies ist eine normale CSS-Animation, wie wir sie bereits kennen
@keyframes adjust-progressbar {
from {
transform: scaleX(0);
}
to {
transform: scaleX(1);
}
}
Wie üblich, weisen Sie sie einem Element mit der animation-Eigenschaft zu
#progressbar {
animation: 1s linear forwards adjust-progressbar;
}
Scroll-Timeline
Die Scroll-Timeline ermöglicht es uns, den Scroll-Abstand dem Animationsfortschritt zuzuordnen. In CSS beschreiben wir dies mit der CSS-At-Rule @scroll-timeline.
@scroll-timeline scroll-in-document-timeline {
source: auto;
orientation: vertical;
scroll-offsets: 0%, 100%;
}
Neben der Benennung der Scroll-Timeline kann sie mit mehreren Deskriptoren konfiguriert werden
- Die
sourcebeschreibt das scrollbare Element, dessen Scrollen die Aktivierung auslöst und den Fortschritt der Timeline steuert. Standardmäßig ist dies das gesamte Dokument (Wert:auto). - Die
orientationbestimmt die Scroll-Richtung, die die Animation auslösen soll. Standardmäßig ist diesvertical. - Die Eigenschaft
scroll-offsetsist ein Array von Schlüsselpunkten, das den Bereich beschreibt, in dem die Animation aktiv sein soll. Diese Offsets können relative/absolute Werte (z. B. Prozentsätze und Längen) oder elementbasierte Offsets sein.
Eine frühere Version der Spezifikation erforderte, dass Sie auch einen time-range-Deskriptor festlegen. Dieser Deskriptor wurde entfernt und übernimmt automatisch die animation-duration aus der verknüpften Animation. Sie können Spuren dieses Deskriptors immer noch in Demos sehen, aber Sie können ihn getrost ignorieren.
Eine Verknüpfung zwischen beiden
Um unsere @scroll-timeline mit unserer CSS-Animation zu verknüpfen, verwenden wir die neue CSS-Eigenschaft animation-timeline und lassen sie auf den Namen der Timeline verweisen.
#progressbar {
animation: 1s linear forwards adjust-progressbar;
animation-timeline: scroll-in-document-timeline;
}
Damit ist die Animation adjust-progressbar nicht mehr automatisch beim Laden der Seite aktiv, sondern wird erst beim Scrollen nach unten auf der Seite fortgeschritten.
Für eine eingehendere Einführung in @scroll-timeline verweisen wir auf Teil 1 und Teil 2 meiner Serie über Scroll-Linked Animations.
Der erste Beitrag befasst sich detaillierter mit jedem Deskriptor und erklärt ihn mit einem Beispiel, bevor viele weitere interessante Demos behandelt werden.
Der zweite Beitrag geht noch tiefer und befasst sich mit elementbasierten Offsets, die es uns ermöglichen, eine Animation zu steuern, wenn ein Element beim Scrollen in den Scrollport ein- und ausblendet.
Praktische Anwendungsfälle
Neben der oben gezeigten Fortschrittsbalken-Demo gibt es noch einige weitere Anwendungsfälle oder Szenarien für diese Scroll-Linked Animations.
- Parallax-Header
- Bild ein-/ausblenden
- Tipp-Animation
- Karussell-Indikatoren
- Scrollspy
Parallax-Header
Der klassischste Anwendungsfall für Scroll-Linked Animations ist ein Parallax-Effekt, bei dem sich verschiedene Abschnitte einer Seite scheinbar mit unterschiedlicher Geschwindigkeit bewegen. Es gibt zwar eine Möglichkeit, diese Art von Effekten nur mit CSS zu erstellen, aber das erfordert verblüffende transform-Hacks mit translate-z() und scale().
Inspiriert vom Firewatch Header, der den erwähnten transform-Hack verwendet, habe ich diese Version erstellt, die eine CSS-Scroll-Timeline nutzt.
Im Vergleich zur Original-Demo
- Die Markup-Struktur wurde beibehalten, mit Ausnahme der zusätzlichen Klasse
.parallax__cover, die nicht mehr benötigt wird. - Dem
<body>wurde einemin-heightzugewiesen, um etwas Scroll-Effekt zu erzeugen. - Die Positionierung des Elements
.parallaxund seiner Kindelemente.parallax_layerwurde angepasst. - Der
transform/perspective-Hack wurde durch eine Scroll-Timeline ersetzt.
Jede verschiedene Ebene nutzt dieselbe Scroll-Timeline: Scrollen über eine Distanz von 100vh.
@scroll-timeline scroll-for-100vh {
scroll-offsets: 0, 100vh;
}
.parallax__layer {
animation: 1s parallax linear;
animation-timeline: scroll-for-100vh;
}
Was sich zwischen den Ebenen unterscheidet, ist die Distanz, die sie sich beim Scrollen nach unten bewegen.
- Die hinterste Ebene sollte an Ort und Stelle bleiben, d.h. sich um
0vhbewegen. - Die vorderste Ebene sollte sich am schnellsten bewegen, z.B.
100vh. - Alle Ebenen dazwischen werden interpoliert.
@keyframes parallax {
to {
transform: translateY(var(--offset));
}
}
.parallax__layer__0 {
--offset: 100vh;
}
.parallax__layer__1 {
--offset: 83vh;
}
.parallax__layer__2 {
--offset: 67vh;
}
.parallax__layer__3 {
--offset: 50vh;
}
.parallax__layer__4 {
--offset: 34vh;
}
.parallax__layer__5 {
--offset: 17vh;
}
.parallax__layer__6 {
--offset: 0vh;
}
Da sich die vorderen Ebenen über eine größere Distanz bewegen, scheinen sie sich schneller zu bewegen als die hinteren Ebenen, wodurch der Parallax-Effekt erzielt wird.
Bild ein-/ausblenden
Ein weiterer großartiger Anwendungsfall für scroll-verknüpfte Animationen ist ein Bild-Reveal: Wenn ein Bild ins Bild gleitet, enthüllt es sich selbst.
Standardmäßig hat das Bild eine Opazität von 0 und wird mit einem clip-path maskiert.
#revealing-image {
opacity: 0;
clip-path: inset(45% 20% 45% 20%);
}
Im Endzustand möchten wir, dass das Bild vollständig sichtbar ist, also haben wir den Endframe unserer Animation entsprechend eingestellt.
@keyframes reveal {
to {
clip-path: inset(0% 0% 0% 0%);
opacity: 1;
}
}
Durch die Verwendung von elementbasierten Offsets als Offsets für unsere Scroll-Timeline können wir erreichen, dass unsere Reveal-Animation erst beginnt, wenn das Bild selbst ins Bild gleitet.
@scroll-timeline revealing-image-timeline {
scroll-offsets:
selector(#revealing-image) end 0.5,
selector(#revealing-image) end 1
;
}
#revealing-image {
animation: reveal 1s linear forwards;
animation-timeline: revealing-image-timeline;
}
😵 Kann man mit diesen elementbasierten Offsets nicht folgen? Diese Visualisierung/Tool hilft Ihnen dabei.
Tipp-Animation
Da CSS-Scroll-Timelines an jede bestehende CSS-Animation gekoppelt werden können, können Sie jede CSS-Animations-Demo nehmen und sie transformieren. Nehmen Sie zum Beispiel diese Tipp-Animation.
Durch Hinzufügen einer Scroll-Timeline und der Eigenschaft animation-timeline kann sie so angepasst werden, dass sie „beim Scrollen tippt“.
Beachten Sie, dass dem <body> eine Höhe von 300vh zugewiesen wurde, um einen Scroll-Effekt zu erzielen.
Durch die Verwendung einer anderen Animation kann der obige Code leicht angepasst werden, um einen Zoom-beim-Scrollen-Effekt zu erzielen.
Ich kann mir vorstellen, dass diese beiden Effekte hervorragend für Artikel-Intros geeignet wären.
Karussell/Slider-Indikatoren
Eine der Komponenten eines Karussells (auch Slider genannt) ist ein Indikator, der anzeigt, wie viele Folien es enthält und welche Folie gerade aktiv ist. Dies geschieht normalerweise mit Punkten.
Dies ist wieder etwas, das wir mit einer CSS-Scroll-Timeline erreichen können, wie in dieser Demo von Fabrizio Calderan gezeigt.
Der aktive Bullet wird über .slider nav::before injiziert und hat eine Animation, die ihn über die anderen Bulletpunkte bewegt.
/* Styling of the dots */
.slider nav::before, .slider a {
inline-size: 1rem;
aspect-ratio: 1;
border-radius: 50%;
background: #9bc;
}
/* Positioning of the active dot */
.slider nav::before {
content: "";
position: absolute;
z-index: 1;
display: block;
cursor: not-allowed;
transform: translateX(0);
animation: dot 1s steps(1, end) 0s forwards;
}
/* Position over time of the active dot */
@keyframes dot {
0%
{ transform: translateX(0); }
33%
{ transform: translateX(calc((100% + var(--gap)) * 1)); }
66%
{ transform: translateX(calc((100% + var(--gap)) * 2)); }
100%
{ transform: translateX(calc((100% + var(--gap)) * 3)); }
}
Durch das Anfügen einer @scroll-timeline an den Slider kann sich der Punkt, der den aktiven Zustand anzeigt, beim Scrollen bewegen.
@scroll-timeline slide {
source: selector(#s);
orientation: inline;
}
.slider nav::before {
/* etc. */
animation-timeline: slide;
}
Der Punkt bewegt sich erst, nachdem die Folie an ihrer Position eingerastet ist, dank der Einbeziehung einer steps() Funktion in die Animation. Wenn Sie diese entfernen, wird deutlicher, wie sich der Punkt beim Scrollen bewegt.
💡 Dies fühlt sich wie das letzte fehlende Teil für Christian Shaefer's CSS-only Karussell an.
ScrollSpy
Anfang 2020 habe ich eine sticky Inhaltsübersicht mit scrollenden aktiven Zuständen erstellt. Der letzte Schritt zur Erstellung der Demo war die Verwendung von IntersectionObserver, um die aktiven Zustände in der Inhaltsübersicht beim Scrollen nach oben/unten im Dokument einzustellen.
Im Gegensatz zur Karussell-Indikatoren-Demo von oben können wir nicht einfach einen einzigen Punkt bewegen, da die Texte in der Inhaltsübersicht angepasst werden. Um diese Situation anzugehen, müssen wir jeder einzelnen Inhaltsübersichts-Element zwei Animationen zuweisen.
- Die erste Animation dient dazu, das Inhaltsübersichts-Element visuell zu aktivieren, wenn der entsprechende Abschnitt am unteren Rand des Dokuments sichtbar wird.
- Die zweite Animation dient dazu, das Inhaltsübersichts-Element visuell zu deaktivieren, wenn der entsprechende Abschnitt am oberen Rand des Dokuments aus der Sicht verschwindet.
.section-nav li > a {
animation:
1s activate-on-enter linear forwards,
1s deactivate-on-leave linear forwards;
}
Da wir zwei Animationen haben, müssen wir auch zwei Scroll-Timelines erstellen, und zwar für jeden Abschnitt des Inhalts. Nehmen wir zum Beispiel den Abschnitt #introduction.
@scroll-timeline section-introduction-enter {
scroll-offsets:
selector(#introduction) end 0,
selector(#introduction) end 1;
}
@scroll-timeline section-introduction-leave {
scroll-offsets:
selector(#introduction) start 1,
selector(#introduction) start 0;
}
Sobald beide Timelines mit beiden Animationen verknüpft sind, funktioniert alles wie erwartet.
.section-nav li > a[href"#introduction"] {
animation-timeline:
section-introduction-enter,
section-introduction-leave;
}
Zum Schluss
Ich hoffe, ich habe Sie vom Potenzial der Spezifikation für Scroll-Linked Animations überzeugt.
Leider wird diese derzeit nur in Chromium-basierten Browsern unterstützt, versteckt hinter einem Flag. Angesichts dieses Potenzials hoffe ich persönlich, dass andere Browserhersteller nachziehen werden, sobald die Spezifikation einen endgültigen Syntax hat.
Wenn auch Sie Scroll-Linked Animations in anderen Browsern sehen möchten, können Sie die entsprechenden Browser-Probleme aktiv mit einem Stern versehen/verfolgen.
Durch aktives Starren von Problemen können wir Entwickler unser Interesse an diesen Funktionen gegenüber Browserherstellern signalisieren.
Was ist das spezifische experimentelle Web-Plattform-Feature, das aktiviert werden muss? Ich bin in Chrome 91 und sehe „CSS Scroll-Linked Animations“ nicht als verfügbares Experiment.
Hallo! Aktivieren Sie die Option „Experimental Web Platform features“ und starten Sie den Browser neu. Sie kann in Chrome oder Chrome Canary aktiviert werden.
Vielen Dank für den Überblick über Scroll-Timelines, es ist eine aufregende Funktion, mit der ich auf zukünftigen Projekten wirklich gerne experimentieren würde (und obwohl ich GSAPs ScrollTrigger liebe, begrüße ich immer CSS-only-Lösungen).
Ich bin normalerweise kein Fan von Parallax-Scrolling-Effekten, aber ich habe die Firewatch-Website schon immer geliebt, und ich bin so froh, dass Sie diese Funktion damit demonstriert haben!
Das ist sehr aufregend!
Gibt es einen bestimmten Zeitrahmen, in dem Chrome plant, dies aus dem „Experimental Web Platform features“-Flag herauszunehmen und in den Mainstream-Browser zu integrieren?
Hallo!
Ich benutze Chrome Canary 110, habe die „Experimental Web Platform features“ aktiviert und die Funktionen auf dieser Seite sind für mich nicht sichtbar. Keine davon. Was soll ich tun?
Ich würde das gerne erforschen.