Verwendung von CSS-Animationen
CSS-Animationen ermöglichen den Übergang von einer CSS-Stilkonfiguration zu einer anderen. Animationen bestehen aus zwei Komponenten: einem Stil, der die CSS-Animation beschreibt, und einem Satz von Keyframes, die den Anfangs- und Endzustand des Animationsstils sowie mögliche Zwischenpunkte angeben.
Es gibt drei Hauptvorteile von CSS-Animationen gegenüber traditionellen, skriptgesteuerten Animationstechniken:
- Sie sind einfach für grundlegende Animationen zu verwenden; Sie können sie erstellen, ohne JavaScript kennen zu müssen.
- Die Animationen laufen gut, selbst bei moderater Systembelastung. Einfache Animationen können in JavaScript oft schlecht performen. Die Rendering-Engine kann Techniken wie Frame-Skipping verwenden, um die Leistung so flüssig wie möglich zu halten.
- Wenn der Browser die Animationssequenz steuert, kann er die Leistung und Effizienz optimieren, indem er z. B. die Aktualisierungsfrequenz von Animationen in nicht sichtbaren Tabs reduziert.
Konfigurieren einer Animation
Um eine CSS-Animationssequenz zu erstellen, gestalten Sie das zu animierende Element mit der animation
-Eigenschaft oder deren Untereigenschaften. Dies ermöglicht Ihnen, das Timing, die Dauer und andere Details der Abfolge der Animationssequenz zu konfigurieren. Dies konfiguriert nicht das tatsächliche Erscheinungsbild der Animation, welches mit der @keyframes
-Regel konfiguriert wird, wie im Abschnitt Definieren einer Animationssequenz mit Keyframes unten beschrieben.
Die Untereigenschaften der animation
-Eigenschaft sind:
animation-composition
-
Legt die Zusammensetzungsoperation fest, die verwendet wird, wenn mehrere Animationen gleichzeitig dieselbe Eigenschaft beeinflussen. Diese Eigenschaft ist nicht Teil der
animation
-Kurzform-Eigenschaft. animation-delay
-
Bestimmt die Verzögerung zwischen dem Laden eines Elements und dem Beginn einer Animationssequenz und ob die Animation sofort von Anfang an oder in der Mitte beginnen soll.
animation-direction
-
Bestimmt, ob die erste Iteration einer Animation vorwärts oder rückwärts sein soll und ob nachfolgende Iterationen die Richtung bei jeder Ausführung wechseln oder zum Ausgangspunkt zurückkehren und wiederholen sollen.
animation-duration
-
Gibt die Zeitspanne an, in der eine Animation einen Zyklus abschließt.
animation-fill-mode
-
Bestimmt, wie eine Animation Stile auf ihr Ziel vor und nach ihrer Ausführung anwendet.
Hinweis: Im Fall des Animations-forwards-Fill-Modus verhalten sich animierte Eigenschaften, als ob sie in einer Menge von
will-change
-Eigenschaftswerten enthalten wären. Wenn während der Animation ein neuer Stacking-Kontext erstellt wurde, behält das Ziel-Element nach Beendigung der Animation den Stacking-Kontext. animation-iteration-count
-
Gibt an, wie oft eine Animation wiederholt werden soll.
animation-name
-
Gibt den Namen der
@keyframes
-Regel an, die die Keyframes einer Animation beschreibt. animation-play-state
-
Gibt an, ob eine Animationssequenz pausiert oder abgespielt werden soll.
animation-timeline
-
Bestimmt die Zeitleiste, die verwendet wird, um den Fortschritt einer CSS-Animation zu steuern.
animation-timing-function
-
Bestimmt, wie eine Animation durch Keyframes über Beschleunigungskurven hinweg übergeht.
Definieren einer Animationssequenz mit Keyframes
Nachdem Sie das Timing der Animation konfiguriert haben, müssen Sie das Erscheinungsbild der Animation definieren. Dies geschieht durch das Erstellen von einem oder mehreren Keyframes mit der @keyframes
-Regel. Jedes Keyframe beschreibt, wie das animierte Element zu einem bestimmten Zeitpunkt während der Animationssequenz gerendert werden soll.
Da das Timing der Animation im CSS-Stil definiert wird, der die Animation konfiguriert, verwenden Keyframes eine <percentage>
, um die Zeit während der Animationssequenz anzugeben, zu der sie stattfinden. 0 % gibt den ersten Moment der Animationssequenz an, während 100 % den Endzustand der Animation angibt. Da diese beiden Zeiten so wichtig sind, haben sie spezielle Aliase: from
und to
. Beide sind optional. Wenn from
/0%
oder to
/100%
nicht angegeben ist, startet oder beendet der Browser die Animation mit den berechneten Werten aller Attribute.
Sie können optional zusätzliche Keyframes einfügen, die Zwischenschritte zwischen dem Anfang und dem Ende der Animation beschreiben.
Verwendung der Kurzform animation
Die animation
-Kurzform ist nützlich, um Platz zu sparen. Zum Beispiel können einige der Regeln, die wir im Verlauf dieses Artikels verwendet haben:
p {
animation-duration: 3s;
animation-name: slide-in;
animation-iteration-count: infinite;
animation-direction: alternate;
}
... durch die Verwendung der animation
-Kurzform ersetzt werden.
p {
animation: 3s infinite alternate slide-in;
}
Um mehr über die Reihenfolge zu erfahren, in der verschiedene Animations-Eigenschaftswerte mit der animation
-Kurzform angegeben werden können, sehen Sie sich die animation
-Referenzseite an.
Festlegen mehrerer Animations-Eigenschaftswerte
Die langen CSS-Animations-Eigenschaften können mehrere Werte akzeptieren, die durch Kommas getrennt sind. Diese Funktion kann verwendet werden, wenn Sie mehrere Animationen in einer einzigen Regel anwenden und unterschiedliche Dauern, Iterationszahlen usw. für jede der Animationen festlegen möchten. Sehen wir uns einige schnelle Beispiele an, um die verschiedenen Permutationen zu erklären.
Im ersten Beispiel gibt es drei Dauer- und drei Iterationszahlwerte. So wird jeder Animation ein Dauer- und ein Iterationszahlenwert mit der gleichen Position wie der Animationsname zugewiesen. Der fadeInOut
-Animation wird eine Dauer von 2.5s
und eine Iterationszahl von 2
zugewiesen, und der bounce
-Animation wird eine Dauer von 1s
und eine Iterationszahl von 5
zugewiesen.
animation-name: fadeInOut, moveLeft300px, bounce;
animation-duration: 2.5s, 5s, 1s;
animation-iteration-count: 2, 1, 5;
Im zweiten Beispiel sind drei Animationsnamen festgelegt, aber es gibt nur eine Dauer und Iterationszahl. In diesem Fall erhalten alle drei Animationen die gleiche Dauer und Iterationszahl.
animation-name: fadeInOut, moveLeft300px, bounce;
animation-duration: 3s;
animation-iteration-count: 1;
Im dritten Beispiel sind drei Animationen angegeben, aber es gibt nur zwei Dauern und Iterationszahlen. In solchen Fällen, in denen nicht genügend Werte in der Liste vorhanden sind, um jedem Animation eine separate zuzuweisen, erfolgt die Wertzuweisung ausgehend vom ersten bis zum letzten Element in der verfügbaren Liste und dann wieder zurück zum ersten Element. So erhält fadeInOut
eine Dauer von 2.5s
, und moveLeft300px
erhält eine Dauer von 5s
, was der letzte Wert in der Liste der Dauerwerte ist. Die Zuordnung der Dauerwerte wird nun auf den ersten Wert zurückgesetzt; daher erhält bounce
eine Dauer von 2.5s
. Die Iterationszahlen (und alle anderen angegebenen Eigenschaftswerte) werden in der gleichen Weise zugewiesen.
animation-name: fadeInOut, moveLeft300px, bounce;
animation-duration: 2.5s, 5s;
animation-iteration-count: 2, 1;
Wenn das Ungleichgewicht in der Anzahl der Animationen und Animations-Eigenschaftswerte umgekehrt ist, sagen wir es gibt fünf animation-duration
-Werte für drei animation-name
-Werte, dann gelten die zusätzlichen oder unbenutzten Animations-Eigenschaftswerte, in diesem Fall zwei animation-duration
-Werte, für keine Animation und werden ignoriert.
Beispiele
Text über das Browser-Fenster gleiten lassen
Dieses einfache Beispiel stylt ein <p>
-Element, das die translate
- und scale
-Übergangseigenschaften verwendet, so dass der Text von der rechten Kante des Browserfensters herein gleitet.
p {
animation-duration: 3s;
animation-name: slide-in;
}
@keyframes slide-in {
from {
translate: 150vw 0;
scale: 200% 1;
}
to {
translate: 0 0;
scale: 100% 1;
}
}
In diesem Beispiel gibt der Stil für das <p>
-Element an, dass die Animation 3 Sekunden dauern soll, um von Anfang bis Ende ausgeführt zu werden, wobei die animation-duration
-Eigenschaft verwendet wird, und dass der Name der @keyframes
-Regel, die die Keyframes der Animationssequenz definiert, slide-in
ist.
In diesem Fall haben wir nur zwei Keyframes. Das erste tritt bei 0%
auf (mit dem Alias from
). Hier konfigurieren wir die translate
-Eigenschaft des Elements auf 150vw
(das heißt, jenseits des rechten Randes des enthaltenen Elements) und die scale
des Elements auf 200% (oder das Doppelte seiner standardmäßigen Inline-Größe), was dazu führt, dass der Absatz doppelt so breit wie sein <body>
-Enthaltender-Block ist. Dies führt dazu, dass das erste Frame der Animation den Header außerhalb der rechten Kante des Browserfensters zieht.
Das zweite Keyframe tritt bei 100%
auf (mit dem Alias to
). Die translate
-Eigenschaft wird auf 0%
gesetzt und die scale
des Elements auf 1
gesetzt, was 100%
entspricht. Dies führt dazu, dass der Header seine Animation in seinem Standardzustand, bündig mit der linken Kante des Inhaltsbereichs, abschließt.
<p>
The Caterpillar and Alice looked at each other for some time in silence: at
last the Caterpillar took the hookah out of its mouth, and addressed her in a
languid, sleepy voice.
</p>
Hinweis: Seite neu laden, um die Animation zu sehen.
Hinzufügen einer weiteren Keyframe-Animation
Lassen Sie uns dem vorherigen Beispiel eine weitere Keyframe-Animation hinzufügen. Nehmen wir an, wir möchten, dass Alices Name pink wird und größer wird und dann zu seiner ursprünglichen Größe und Farbe schrumpft, während er von rechts nach links wandert. Während wir die font-size
ändern könnten, wirkt sich die Änderung von Eigenschaften, die das Boxmodell beeinflussen, negativ auf die Leistung aus. Stattdessen umschließen wir ihren Namen mit einem <span>
und skalieren dies und weisen separat eine Farbe zu. Das erfordert das Hinzufügen einer zweiten Animation, die nur das <span>
betrifft:
@keyframes grow-shrink {
25%,
75% {
scale: 100%;
}
50% {
scale: 200%;
color: magenta;
}
}
Der vollständige Code sieht nun folgendermaßen aus:
p {
animation-duration: 3s;
animation-name: slide-in;
}
p span {
display: inline-block;
animation-duration: 3s;
animation-name: grow-shrink;
}
@keyframes slide-in {
from {
translate: 150vw 0;
scale: 200% 1;
}
to {
translate: 0 0;
scale: 100% 1;
}
}
@keyframes grow-shrink {
25%,
75% {
scale: 100%;
}
50% {
scale: 200%;
color: magenta;
}
}
Wir haben ein <span>
um "Alice" hinzugefügt:
<p>
The Caterpillar and <span>Alice</span> looked at each other for some time in
silence: at last the Caterpillar took the hookah out of its mouth, and
addressed her in a languid, sleepy voice.
</p>
Dies teilt dem Browser mit, dass der Name für die ersten und letzten 25% der Animation normal sein soll, in der Mitte jedoch pink wird und vergrößert und dann zurückvergrößert werden soll. Wir setzen die display
-Eigenschaft des Spans auf inline-block
, da die transform
-Eigenschaften keine nicht-ersetzte inline-level content betreffen.
Hinweis: Seite neu laden, um die Animation zu sehen.
Wiederholung der Animation
Um die Animation sich wiederholen zu lassen, verwenden Sie die animation-iteration-count
-Eigenschaft, um anzugeben, wie oft die Animation wiederholt werden soll. In diesem Fall verwenden wir infinite
, um die Animation unendlich oft wiederholen zu lassen:
p {
animation-duration: 3s;
animation-name: slide-in;
animation-iteration-count: infinite;
}
Die Animation hin- und herbewegen
Das ließ sie sich wiederholen, aber es ist sehr seltsam, das jedes Mal zum Startpunkt zurückspringen zu lassen, wenn sie beginnt zu animieren. Was wir wirklich wollen, ist, dass sie sich hin- und her über den Bildschirm bewegt. Das ist leicht zu erreichen, indem Sie animation-direction
auf alternate
setzen:
p {
animation-duration: 3s;
animation-name: slide-in;
animation-iteration-count: infinite;
animation-direction: alternate;
}
Verwendung von Animationsevents
Sie können zusätzliche Kontrolle über Animationen erlangen – sowie nützliche Informationen über sie – indem Sie Animationsevents nutzen. Diese Events, dargestellt durch das AnimationEvent
-Objekt, können verwendet werden, um zu erkennen, wann Animationen beginnen, enden und eine neue Iteration beginnen. Jedes Event enthält die Zeit, zu der es auftrat, sowie den Namen der Animation, die das Event auslöste.
Wir werden das schiebbare Textbeispiel so modifizieren, dass einige Informationen über jedes Animationsevent ausgegeben werden, wenn es auftritt, damit wir sehen können, wie sie funktionieren.
Wir haben die gleiche Keyframe-Animation wie im vorherigen Beispiel aufgenommen. Diese Animation dauert 3 Sekunden, wird "slide-in" genannt, wiederholt sich dreimal und bewegt sich bei jeder Wiederholung in eine andere Richtung. Im @keyframes
werden das Skalieren und das Übersetzen entlang der x-Achse manipuliert, um das Element über den Bildschirm gleiten zu lassen.
.slide-in {
animation-duration: 3s;
animation-name: slide-in;
animation-iteration-count: 3;
animation-direction: alternate;
}
Hinzufügen der Animationsevent-Listener
Wir werden JavaScript-Code verwenden, um auf alle drei möglichen Animationsevents zu lauschen. Dieser Code konfiguriert unsere Event-Listener; wir rufen ihn auf, wenn das Dokument zum ersten Mal geladen wird, um die Dinge einzurichten.
const element = document.getElementById("watch-me");
element.addEventListener("animationstart", listener);
element.addEventListener("animationend", listener);
element.addEventListener("animationiteration", listener);
element.className = "slide-in";
Dies ist ziemlich standardmäßiger Code; Sie können Details dazu, wie er funktioniert, in der Dokumentation zu eventTarget.addEventListener()
finden. Das Letzte, was dieser Code tut, ist, die class
-Eigenschaft auf dem Element zu setzen, das wir animieren werden, auf "slide-in"; wir machen das, um die Animation selbst zu starten.
Warum? Weil das animationstart
-Event sofort nach dem Start der Animation ausgelöst wird, und in unserem Fall passiert das, bevor unser Code ausgeführt wird. Also starten wir die Animation selbst, indem wir die Klasse des Elements auf den Stil setzen, der nachträglich animiert wird.
Empfang der Events
Die Events werden der listener()
-Funktion übergeben, die unten gezeigt wird.
function listener(event) {
const l = document.createElement("li");
switch (event.type) {
case "animationstart":
l.textContent = `Started: elapsed time is ${event.elapsedTime}`;
break;
case "animationend":
l.textContent = `Ended: elapsed time is ${event.elapsedTime}`;
break;
case "animationiteration":
l.textContent = `New loop started at time ${event.elapsedTime}`;
break;
}
document.getElementById("output").appendChild(l);
}
Dieser Code ist ebenfalls sehr einfach. Er prüft den event.type
, um zu bestimmen, welche Art von Animationsevent aufgetreten ist, und fügt dann eine entsprechende Notiz zu der <ul>
(ungeordnete Liste) hinzu, die wir zur Protokollierung dieser Events verwenden.
Das Ergebnis sieht am Ende etwa so aus:
- Gestartet: vergangene Zeit ist 0
- Neue Schleife gestartet um 3.01200008392334
- Neue Schleife gestartet um 6.00600004196167
- Beendet: vergangene Zeit ist 9.234000205993652
Beachten Sie, dass die Zeiten sehr nahe an, aber nicht genau die erwarteten sind, die beim Konfigurieren der Animation festgelegt wurden. Beachten Sie auch, dass nach der letzten Iteration der Animation das animationiteration
-Event nicht gesendet wird; stattdessen wird das animationend
-Event gesendet.
Nur der Vollständigkeit halber hier der HTML-Code, der den Seiteninhalt anzeigt, einschließlich der Liste, in die das Skript Informationen über die empfangenen Events einfügt:
<h1 id="watch-me">Watch me move</h1>
<p>
This example shows how to use CSS animations to make <code>H1</code>
elements move across the page.
</p>
<p>
In addition, we output some text each time an animation event fires, so you
can see them in action.
</p>
<ul id="output"></ul>
Und hier sind die Live-Ergebnisse.
Hinweis: Seite neu laden, um die Animation zu sehen.
Animation von display
und content-visibility
Dieses Beispiel demonstriert, wie display
und content-visibility
animiert werden können. Dieses Verhalten ist nützlich für das Erstellen von Ein- und Ausstiegsanimationen, bei denen Sie z. B. einen Container aus dem DOM mit display: none
entfernen möchten, ihn jedoch sanft mit opacity
ausblenden lassen möchten, anstatt sofort zu verschwinden.
Unterstützende Browser animieren display
und content-visibility
mit einer Variation des diskreten Animationstyps. In der Regel bedeutet dies, dass Eigenschaften zwischen zwei Werten 50% des Weges durch das Animieren zwischen den beiden umschalten.
Es gibt jedoch eine Ausnahme, die beim Animieren von/zu display: none
oder content-visibility: hidden
zu einem sichtbaren Wert auftritt. In diesem Fall schaltet der Browser zwischen den beiden Werten um, sodass der animierte Inhalt die gesamte Dauer der Animation sichtbar ist.
Zum Beispiel:
- Beim Animieren von
display
vonnone
zublock
(oder einem anderen sichtbarendisplay
-Wert) schaltet der Wert bei0%
der Animationsdauer zublock
, sodass er während der gesamten Dauer sichtbar ist. - Beim Animieren von
display
vonblock
(oder einem anderen sichtbarendisplay
-Wert) zunone
schaltet der Wert bei100%
der Animationsdauer zunone
, sodass er die gesamte Dauer sichtbar ist.
HTML
Das HTML enthält zwei <p>
-Elemente mit einem <div>
dazwischen, das wir vom display
none
zu block
animieren.
<p>
Click anywhere on the screen or press any key to toggle the
<code><div></code> between hidden and showing.
</p>
<div>
This is a <code><div></code> element that animates between
<code>display: none; opacity: 0</code> and
<code>display: block; opacity: 1</code>. Neat, huh?
</div>
<p>
This is another paragraph to show that <code>display: none;</code> is being
applied and removed on the above <code><div> </code>. If only its
<code>opacity</code> was being changed, it would always take up the space in
the DOM.
</p>
CSS
html {
height: 100vh;
}
div {
font-size: 1.6rem;
padding: 20px;
border: 3px solid red;
border-radius: 20px;
width: 480px;
opacity: 0;
display: none;
}
/* Animation classes */
div.fade-in {
display: block;
animation: fade-in 0.7s ease-in forwards;
}
div.fade-out {
animation: fade-out 0.7s ease-out forwards;
}
/* Animation keyframes */
@keyframes fade-in {
0% {
opacity: 0;
display: none;
}
100% {
opacity: 1;
display: block;
}
}
@keyframes fade-out {
0% {
opacity: 1;
display: block;
}
100% {
opacity: 0;
display: none;
}
}
Beachten Sie die Einbeziehung der display
-Eigenschaft in die Keyframe-Animationen.
JavaScript
Schließlich fügen wir ein wenig JavaScript hinzu, um Event-Listener einzurichten, die die Animationen auslösen. Insbesondere fügen wir die fade-in
-Klasse dem <div>
hinzu, wenn es erscheinen soll, und fade-out
, wenn es verschwinden soll.
const divElem = document.querySelector("div");
const htmlElem = document.querySelector(":root");
htmlElem.addEventListener("click", showHide);
document.addEventListener("keydown", showHide);
function showHide() {
if (divElem.classList[0] === "fade-in") {
divElem.classList.remove("fade-in");
divElem.classList.add("fade-out");
} else {
divElem.classList.remove("fade-out");
divElem.classList.add("fade-in");
}
}
Ergebnis
Der Code wird wie folgt gerendert: