Insets in Animations-Timelines verstehen
Standardmäßig verfolgen View-Progress-Timelines Elemente über den gesamten Animationsbereich hinweg. Der Fortschrittspunkt 0% liegt am Anfang des Bereichs, der Fortschrittspunkt 100% an dessen Ende. Der Animationsbereich lässt sich durch Festlegen eines Timeline-Bereichsnamens ändern. Die Position der Fortschrittspunkte 0% und 100% innerhalb des Bereichs lässt sich mit längen- oder prozentbasierten Inset-Werten anpassen.
Dieser Leitfaden erklärt, wie Sie die Animations-Timeline mithilfe von Längen- oder Prozentwerten für Insets auf einen bestimmten Abschnitt des Animationsbereichs begrenzen.
Animations-Timelines: eine Einführung
CSS-Animationen werden erstellt, indem benannte @keyframes-Animationen definiert werden, die das Verhalten einer Animation festlegen. Anschließend wird die Keyframe-Animation über ihren Namen einem Element zugewiesen.
Die durch die Eigenschaft animation-timeline definierte Animations-Timeline des Elements bestimmt, wie und wann das Element die Keyframes durchläuft. Standardmäßig ist die Timeline zeitbasiert und verwendet die standardmäßige zeitbasierte DocumentTimeline des Dokuments.
Das Modul für scrollgesteuerte CSS-Animationen definiert Scroll-Progress- und View-Progress-Timelines. Mit ihnen lassen sich Eigenschaftswerte entlang einer scrollbasierten Timeline statt entlang der standardmäßigen zeitbasierten Dokument-Timeline animieren. In diesem Artikel geht es ausschließlich um View-Progress-Timelines, da Scroll-Progress-Timelines für Timeline-Insets nicht relevant sind.
View-Progress-Timelines
Bei View-Progress-Timelines wird der Animationsfortschritt nicht durch den Zeitverlauf, sondern durch die Sichtbarkeit des Elements bestimmt. Das Durchlaufen der Keyframes hängt von der Position und Sichtbarkeit des animierten Elements innerhalb des Scroll-Containers ab. Die Animation läuft vorwärts oder rückwärts, je nachdem, in welche Richtung sich das Element durch den Scrollport bewegt. Sie läuft nur, wenn mindestens ein Teil des Elements im Scrollport sichtbar ist, und pausiert, wenn das Scrollen pausiert.
.animated_element {
animation-name: nameOfAnimation;
animation-timeline: view();
}
Durch Festlegen von animation-name wird die Animation auf das ausgewählte Element angewendet.
Hinweis:
Die Eigenschaft animation-timeline sollte immer nach allen animation-Kurzschreibweisen stehen. Mit der Kurzschreibweise lässt sich animation-timeline zwar nicht festlegen, sie setzt die Timeline aber auf die standardmäßige zeitbasierte Dokument-Timeline zurück.
Hinweis:
In allen Beispielen ist der Scroll-Container 250px hoch. Für animation-iteration-count (1), animation-delay (0s) und animation-direction (normal) verwenden wir die Standardwerte. Wir setzen animation-timing-function auf step-end und animation-fill-mode auf forward, damit deutlicher erkennbar ist, wann der Animationsdurchlauf noch nicht begonnen hat, aktiv ist oder abgeschlossen wurde. Weitere Informationen finden Sie im Leitfaden zur Verwendung von CSS-Animationen.
Wenn Sie nach oben scrollen, schreitet die Animation voran. Wenn Sie nach unten scrollen, läuft sie rückwärts.
In diesem Beispiel läuft die Animation, sobald ein beliebiger Teil des animierten Elements im Scrollport sichtbar ist. Standardmäßig beginnt eine View-Progress-Animation, wenn die obere Kante des Elements mit der unteren Kante des Scroll-Containers zusammenfällt. Sie endet bei 100% Fortschritt, wenn die Endkante des Elements die Anfangskante des Containers erreicht – unabhängig von der Größe des Elements. Standardmäßig wird die Animation also angewendet, solange irgendein Teil des Elements im Scrollport sichtbar ist.
Animationsbereiche
Wenn für eine View-Progress-Timeline keine Eigenschaften für den Animationsbereich definiert sind, hat <timeline-range-name> den Wert normal, der standardmäßig cover entspricht. Die Animation läuft, solange ein Teil des animierten Elements sichtbar ist. Der standardmäßige Animationsbereich ergibt sich somit aus der Höhe des Scroll-Containers plus der Höhe des animierten Elements; die zusätzliche Höhe liegt jenseits der Scroll-Endkante. In unserem Beispiel ist der Scroll-Container 250px hoch und das animierte Element entweder 50px, 250px oder 500px. Der vertikale Animationsbereich beträgt entsprechend 300px, 500px oder 750px.
Der Fortschrittspunkt 0% liegt dort, wo die Anfangskante des animierten Elements an der Endkante in den Scrollport eintritt. 100% wird erreicht, wenn die Endkante des Elements den Scrollport an dessen Anfangskante verlässt. Beim vertikalen Scrollen sind dies die obere und untere Kante des Elements beziehungsweise des Scrollports. Beim horizontalen Scrollen sind es je nach Schreibrichtung die linke und rechte oder die rechte und linke Kante.
Die folgende Abbildung zeigt die Position des animierten Elements an den Fortschrittspunkten 0% und 100% für die drei Elementgrößen:
Die gelben Elemente zeigen die Position des Elements, wenn der Keyframe from angewendet wird – also beim Fortschrittspunkt 0% des Animationsbereichs. Rot zeigt die Position des animierten Elements relativ zum Scrollport, wenn der Keyframe to angewendet wird. Dies entspricht dem Ende der Animation beziehungsweise dem Fortschrittspunkt 100%. Grau stellt den Scrollport dar.
Standardmäßig wird das Element animiert, während es „im Sichtbereich“ ist. Diese Standarddefinition passt jedoch möglicherweise nicht zu Ihren Anforderungen. Sie können festlegen, welche Kanten den Animationsbereich begrenzen, und anschließend seinen Anfang und sein Ende mit den Eigenschaften für den Animationsbereich verschieben.
Eigenschaften für den Animationsbereich
Mit den animation-range-Eigenschaften können Sie einen benannten Timeline-Bereich wie contain oder exit-crossing angeben. Dadurch wird statt des standardmäßigen cover-Bereichs ein anderer Bereich verwendet. Sie können außerdem einen <length-percentage>-Wert angeben, der den Animationsbereich von seinem Anfang aus einrückt. Prozentwerte beziehen sich auf den benannten oder standardmäßigen Timeline-Bereich.
Benannte Timeline-Bereiche legen fest, welche Abschnitte einer ViewTimeline den Bereich einer Animation bilden. Sie bestimmen damit Anfang und Ende des Animationsbereichs.
Die Eigenschaft animation-range ist eine Kurzschreibweise für animation-range-start und animation-range-end. animation-range-start legt die Position des animierten Elements beim Beginn der Animation fest. animation-range-end legt seine Position beim Ende der Animation fest.
Weitere Informationen zu den verschiedenen benannten Timeline-Bereichen finden Sie im Leitfaden zu Timeline-Bereichsnamen. Dieser Leitfaden konzentriert sich darauf, wie Inset-Werte vom Typ <length-percentage> funktionieren.
Insets mit Längen festlegen
Die Eigenschaften animation-range-start und animation-range-end akzeptieren jeweils einen benannten Animationsbereich, einen <length-percentage>-Offset oder beides. Längen- und Prozent-Offsets werden vom Anfang des Animationsbereichs aus gemessen.
Bei einem <length>-Wert ist der Offset recht anschaulich. Hier verwenden wir animation-range-start und animation-range-end, um die Animations-Timeline einzurücken. Damit definieren wir einen Teil des vollständigen Animationsbereichs des Elements als aktives Intervall. Die <length>-Werte geben Abstände vom Anfang des standardmäßigen Animationsbereichs normal an.
.animated_element {
animation-range-start: 1em;
animation-range-end: 125px;
}
Anfang und Ende des Animationsbereichs liegen 1em beziehungsweise 125px vom Anfang des Animationsbereichs entfernt. Da der Timeline-Bereich standardmäßig normal ist und damit cover entspricht, liegt der Anfang des Animationsbereichs an der Block-Endkante des Containers.
Wir haben Linien im Abstand von 1em und 125px von der Block-Endkante des Scroll-Containers hinzugefügt. Die Animation beginnt, wenn die Block-Anfangskante des animierten Elements die 1em-Linie erreicht, und endet, wenn sie die 125px-Linie erreicht.
Da der Animationsbereich sowohl für den Start- als auch für den End-Inset cover entspricht, lässt sich die Position der Insets hier leicht nachvollziehen.
Einfluss benannter Bereiche auf Längen-Offsets
Der Offset wird immer vom Anfang des zugehörigen Animationsbereichs aus gemessen. In diesem Beispiel liegt animation-range-start 50px vom Anfang des standardmäßigen Bereichs normal entfernt. animation-range-end liegt 100px vom Anfang des ausdrücklich festgelegten Bereichs entry entfernt:
.animated_element {
animation-range-start: 50px;
animation-range-end: entry 100px;
}
Da sowohl normal als auch entry an der Endkante des Containers beginnen, startet die Animation, wenn die Anfangskante des animierten Elements 50px vom unteren Rand des Scrollports entfernt ist. Sie endet bei 100% Fortschritt, wenn diese Kante 100px vom unteren Rand entfernt ist – unabhängig von der Größe des Elements. Obwohl der Bereich entry bei den drei Elementgrößen unterschiedlich groß ist, spielt seine Größe in diesem Fall keine Rolle.
Längen-Offsets bei unterschiedlichen Bereichen
Die Größe des Bereichs ist wichtig, wenn der Bereich nicht an der Endkante des Elements beginnt – wie bei exit und exit-crossing – oder wenn der Offset als Prozentwert angegeben wird. Zusammen mit der Möglichkeit, verschiedene Animationsbereichsnamen zu kombinieren, macht dies Offsets bei View-Progress-Timelines etwas schwieriger verständlich als Timeline-Bereichsnamen ohne Offsets.
Wird beispielsweise exit als Timeline-Bereichsname festgelegt, ist die Größe des animierten Elements wichtig, weil sie die Position der Endkante des Bereichs bestimmt.
.animated_element {
animation-range-start: entry 60px;
animation-range-end: exit 75px;
}
Bei entry und exit entspricht der Bereich der Größe des animierten Elements, ist jedoch auf die Größe des Scrollports begrenzt. In den Beispielen mit 50px und 250px entspricht die Höhe der Bereiche entry und exit daher der Höhe des Elements. Im Beispiel mit 500px wird der Bereich dagegen auf die Höhe des 250px hohen Scrollports begrenzt.
Zur Veranschaulichung haben wir einige Linien hinzugefügt: Die untere blaue Linie liegt 60px von der Endkante des Scrollports entfernt, die obere rote Linie 75px von derselben Kante. An diesen Positionen beginnen beziehungsweise enden die Animationsbereiche.
Dieses Beispiel verdeutlicht mehrere wichtige Eigenschaften, die wir im Folgenden genauer erläutern:
- Offsets werden von ihren jeweiligen benannten Bereichen aus gemessen.
- Offsets können jenseits der Kanten des Scrollports liegen.
- Bereiche können begrenzt werden, wenn das animierte Element größer als der Scrollport ist.
Messung ab der Anfangskante des Bereichs
Da sich ein Offset immer auf den Anfang des in der Deklaration angegebenen Animationsbereichs bezieht, beginnt die Animation bei allen drei Elementen, wenn ihre Anfangskante den Punkt kreuzt, der 60px vom Anfang des Bereichs entry entfernt liegt.
Der Wert von animation-range-end legt die Position fest, an der die Animation endet. exit 75px bedeutet im Wesentlichen: „wenn 75px des animierten Elements die Anfangskante des Scrollports passiert haben“. Diese Position ist für jedes Element anders. Beim 50px hohen Element tritt dies erst 25px nach dem Verlassen des Scrollports ein, wenn das Element nicht mehr sichtbar ist. Bei den 250px und 500px hohen Elementen endet die Animation, wenn ihre untere Endkante die obere blaue Linie schneidet – 75px von der Endkante des Scrollports entfernt. Warum sind ihre End-Offsets gleich? Wegen der Begrenzung! Die maximale Größe des benannten Animationsbereichs ist auf die Größe des Scrollports begrenzt. Der Bereich exit ist für beide Elemente gleich, weshalb auch die End-Offsets gleich sind.
Jenseits der Scrollport-Kanten
Für unser 50px hohes Element ist der Bereich exit ebenfalls 50px hoch und schließt an die Anfangskante des Scrollports an. Wenn animation-range-end: exit 75px für ein Element festgelegt wird, das weniger als 75px hoch ist, liegt das Ende des Bereichs außerhalb des Scrollports: Der Punkt 75px vom Anfang des Bereichs exit entfernt liegt jenseits der Anfangskante des Scrollports. In unserem Beispiel wird das Ende des Animationsbereichs für das 50px hohe Element erreicht, wenn seine Anfangskante 75px über die Anfangskante des Scrollports hinausgewandert ist. Die Animation endet und erreicht den Keyframe to sowie das Ereignis animationend erst dann – sofern überhaupt –, wenn das Element 25px aus dem Sichtbereich herausgescrollt wurde.
Die Animation endet auch dann, wenn das Ende ihres Bereichs außerhalb des Scrollports liegt, sofern genügend Platz vorhanden ist, um bis zu diesem Punkt zu scrollen. Hätten wir animation-range-end: exit 250px festgelegt, würde die Animation für die mittleren und hohen Elemente enden, sobald deren Endkante den Scrollport an der Anfangskante des Containers verlässt.
Bei exit 250px als Endwert könnte die Animation des kleinen Elements dagegen möglicherweise nicht enden: Nach dem Element sind unter Umständen keine 450px Inhalt vorhanden, durch die bis zum Endpunkt gescrollt werden könnte.
Auswirkungen der Begrenzung
Bei unserem 250px hohen Container entspricht der Bereich exit für 250px oder 500px hohe Elemente der Größe des Containers und beginnt an dessen Endkante. Bei einem Offset von 75px endet die Animation, wenn die Endkante des animierten Elements 75px von der Endkante des Scroll-Containers entfernt ist. Diese Position ist durch die obere rote Linie markiert.
Da sich der Offset immer auf den Anfang des benannten oder standardmäßigen Animationsbereichs bezieht, wirkt sich die Begrenzung in unserem Beispiel auf animation-range-end des großen Elements aus. Wir haben das Bereichsende auf exit 75px gesetzt, also 75px vom Anfang des Bereichs exit entfernt. Ist das animierte Element genauso groß wie der Scrollport (unser 250px hohes Element) oder größer (unser 500px hohes Element), liegt das Ende des Animationsbereichs 75px von der Endkante des Scrollports entfernt. Das entspricht 75px vom Anfang des auf die Scrollport-Größe begrenzten Bereichs exit.
Negative Längen
Bisher waren alle Offsets größer als null. Auch negative Längen sind zulässig. Ein negativer Offset für animation-range-start verlängert den Bereich, während ein negativer Offset für animation-range-end ihn verkürzt.
Vergleichen wir negative Insets mit den Werten 0:
#A {
animation-range-start: contain -25px;
animation-range-end: exit -25px;
}
#B {
animation-range-start: contain 0;
animation-range-end: exit 0;
}
Der erste Animationsbereich ist um 25px in Richtung der Endkante des Containers verschoben.
Insets mit Prozentwerten festlegen
Wie Längenwerte definieren Prozentwerte Offsets vom Anfang des Animationsbereichs aus. Prozent-Offsets beziehen sich auf die Ausdehnung des Timeline-Bereichs, nicht auf den Scrollport. Deshalb sind Prozentwerte für die meisten Menschen weniger anschaulich als Längenwerte – auch wenn Längenwerte nicht immer leicht nachzuvollziehen sind.
Hier verwenden wir animation-range-start und animation-range-end, um die Animations-Timeline einzurücken. Die Eigenschaften bleiben gleich, aber statt <length>-Werten legen wir <percentage>-Werte fest:
.animated_element {
animation-range-start: 20%;
animation-range-end: 60%;
}
Dadurch beginnt das aktive Intervall bei 20% des standardmäßigen Animationsbereichs und endet bei 60% desselben Bereichs. Der standardmäßige Animationsbereich normal, der sich wie cover verhält, umfasst die Höhe des Scroll-Containers plus die Höhe des animierten Elements. Seine Größe hängt daher davon ab, welcher Radio-Button ausgewählt ist.
Zur Veranschaulichung verlaufen zwei dunkle Linien bei 20% und 60% des vollständigen Animationsbereichs durch den Container. Die Animation beginnt, wenn die Block-Anfangskante den 20%-Punkt erreicht, der durch die untere grüne Linie markiert ist. Sie endet, wenn die Block-Anfangskante 60% des Bereichs normal durchlaufen hat, bei der oberen roten Linie.
Nur bei einem 50px hohen Element befindet sich dessen Oberkante beim Ende der Animation noch im Scrollport. Wenn 250px oder 500px ausgewählt sind, ist keine obere rote Linie zu sehen, weil das Ende des Animationsbereichs außerhalb des Scrollports liegt.
Je nach Höhe des animierten Elements liegt die 20%-Marke 60px, 100px oder 150px von der Endkante des Scrollports entfernt. Sie wird durch die grüne Linie markiert, die immer im Scrollport liegt. Die 60%-Marke liegt 180px, 300px oder 450px von derselben Kante entfernt. Die rote Markierung ist nur beim 50px hohen Element sichtbar.
Zur Veranschaulichung verlaufen außerdem zwei hellgraue Linien bei 20% und 60% der Scrollport-Höhe durch den Container. Sie liegen 50px beziehungsweise 150px vom unteren Rand des Scrollports entfernt. Da sich die Prozentwerte von animation-range-* auf den Timeline-Bereich und nicht auf den Scrollport beziehen, zeigen diese Linien lediglich, dass die Prozentmarken nicht übereinstimmen. Zusätzlich verlaufen durch jedes animierte Element zwei horizontale hellgraue Linien an dessen eigenen 20%- und 60%-Marken. Diese Linien stimmen mit den hellgrauen Linien des Scrollports überein, wenn die Animation des jeweiligen Elements beginnt und endet.
Die folgende Abbildung zeigt, wo sich die animierten Elemente beim Beginn der Animation (Keyframe 0%) und bei ihrem Ende (Keyframe 100%) befinden. Zum Vergleich zeigt sie sowohl die Insets aus dem vorherigen Beispiel als auch die Timeline ohne Insets.
Wie zuvor zeigt Gelb die Position des Elements beim Keyframe from, Rot seine Position beim Keyframe to und Grau den Scrollport. In den schraffierten Bereichen überlappen die roten und gelben Darstellungen der Elemente. Zur Veranschaulichung haben wir gestrichelte schwarze horizontale Linien hinzugefügt, die vom unteren Rand aus bei 20% und 60% der Scrollport-Höhe liegen.
Die Animation beginnt erst, wenn das Element die 20%-Marke innerhalb des Animationsbereichs erreicht. Abhängig von seiner Größe liegt dieser Punkt 60px, 100px oder 150px vom unteren Rand des Scrollports entfernt. Die Position des Elements zu diesem Zeitpunkt – also bei Anwendung des Keyframes from beziehungsweise 0% – ist gelb dargestellt.
Rot zeigt die Position des animierten Elements relativ zum Scrollport beim Keyframe to beziehungsweise 100%, also am Ende der Animation. Je nach Elementgröße liegt dieser Punkt 180px, 300px oder 450px vom unteren Rand des Scrollports entfernt. Die Animation läuft, während sich das Element zwischen den Positionen from und to befindet.
Vielleicht ist Ihnen an den gestrichelten horizontalen Linien etwas aufgefallen: Zu Beginn der Animation liegt die Linie, die 20% von der Endkante des Scrollports entfernt ist, zugleich 20% von der Oberkante des animierten Elements entfernt. Am Ende der Animation liegt die Linie bei 60% des Scrollports zugleich bei 60% des animierten Elements, jeweils von oben gemessen. Die sehr hellgrauen Linien im interaktiven Beispiel veranschaulichen diesen Zusammenhang.
Die Größe des animierten Elements ist wichtig
Wie bereits beim Festlegen von Insets mit Längen gezeigt, kann die Größe des animierten Elements einen Unterschied machen. Prozentwerte für Animationsbereiche beziehen sich auf die Größe des Animationsbereichs, nicht auf den Scrollport. Bei den meisten benannten Bereichen hängt diese Größe teilweise von der Größe des animierten Elements ab. Da Prozentwerte anhand der Bereichsgröße berechnet werden, beeinflusst der benannte Bereich die tatsächliche Größe der Insets. Je nach Bereichsname kann sich auch die Anfangsposition ändern. Das beeinflusst die Lage des Bereichs und damit die Position seiner Fortschrittspunkte.
In diesem Beispiel definieren wir einen aktiven Bereich, der 40% der Größe des animierten Elements entspricht:
.animated_element {
animation-range-start: exit-crossing -20%;
animation-range-end: exit-crossing 20%;
}
Die Animation erstreckt sich über 40% des Animationsbereichs. Achten Sie beim Scrollen darauf, dass der Bereich mit der Größe des animierten Elements wächst. Bei exit-crossing wird der Animationsbereich nicht beschnitten: Er entspricht der Größe des Elements, selbst wenn dieses größer als der Scrollport ist. Der Bereich schließt an die Anfangskante des Scrollports an und reicht bei größeren Elementen über dessen Endkante hinaus.
Bei den Insets -20% und 20% wird das 50px hohe Element über eine Strecke von 20px animiert: Die Animation beginnt, wenn seine Endkante -10px vom Bereichsanfang entfernt ist beziehungsweise noch 60px bis zum Verlassen des Bildschirms zurücklegen muss. Sie endet, wenn seine Endkante noch 40px vom Verlassen des Bildschirms entfernt ist. Das mittlere Element wird über 100px animiert: Die Animation beginnt, wenn seine Endkante -50px vom Bereichsanfang entfernt ist und damit 50px jenseits der Endkante des Scrollports liegt. Sie endet, wenn seine Endkante 50px innerhalb des Scrollports liegt. Das große Element wird über 200px animiert. Die Animation beginnt, wenn seine Unterkante 600px von der Anfangskante des Containers entfernt ist und nur 150px sichtbar sind. Sie endet, wenn die Unterkante 400px von dieser Kante entfernt ist und 100px bereits über die Anfangskante hinausgescrollt wurden.
Prozentwerte bezogen auf den Scrollport
Für prozentuale Offsets ist contain der am einfachsten nachzuvollziehende benannte Timeline-Bereich. Bei contain entspricht die Größe des Animationsbereichs der Größe des Scrollports. Anfangs- und End-Prozentwerte beziehen sich damit auf den Scrollport. Wenn Sie Offsets verwenden, kann es daher sinnvoll sein, contain festzulegen, statt den Bereich beim Standardwert zu belassen, der cover entspricht.
Der Bereich contain umfasst die Animation vollständig innerhalb des Scrollports. Er bezeichnet den Abschnitt, in dem die Hauptbox entweder vollständig innerhalb ihres sichtbaren View-Progress-Bereichs im Scrollport liegt oder diesen vollständig bedeckt. Bei contain kann ein animiertes Element vollständig sichtbar sein, wenn es höchstens so groß wie der Scrollport ist. Ist das Element allerdings genauso groß wie der Container, erstreckt sich die Animation über 0px. Sie läuft zwar ab, ist für Benutzer jedoch nicht sichtbar.
Anders gesagt: Ohne die Größe des Containers oder der animierten Elemente kennen zu müssen, können wir die Animation auf die Mitte des Scrollports begrenzen. Ist das Element genauso groß wie der Scrollport, erstreckt sich die Animation allerdings über 0px.
.animated_element {
animation-range-start: contain 25%;
animation-range-end: contain 75%;
}
Die horizontalen Linien markieren die mittlere Hälfte des Scrollports und die mittlere Hälfte jedes animierten Elements.