Verwendung von CSS-Animationen
CSS-Animationen ermöglichen es, Übergänge von einer CSS-Stilkonfiguration zu einer anderen zu animieren. Animationen bestehen aus zwei Komponenten: einem Stil, der die CSS-Animation beschreibt, und einer Reihe von Keyframes, die die Start- und Endzustände des Animationsstils sowie mögliche Zwischenpunkte angeben.
Es gibt drei Hauptvorteile von CSS-Animationen im Vergleich zu traditionellen skriptgesteuerten Animationstechniken:
- Sie können einfache Animationen mit nur wenigen Zeilen CSS erstellen, ganz ohne JavaScript.
- Die Animationen laufen gut, auch bei mäßiger Systemauslastung. Einfache Animationen können in JavaScript oft schlecht performen. Die Rendering-Engine kann Frame-Skipping und andere Techniken verwenden, um die Leistung so reibungslos wie möglich zu gestalten.
- Wenn der Browser die Animationssequenz steuert, kann er die Leistung und Effizienz optimieren, indem er zum Beispiel die Aktualisierungsfrequenz von Animationen reduziert, die in Tabs ausgeführt werden, die derzeit nicht sichtbar sind.
Konfigurieren einer Animation
Um eine CSS-Animationssequenz zu erstellen, stylen Sie das Element, das Sie animieren möchten, mit der animation-Eigenschaft oder deren Untereigenschaften. Damit können Sie das Timing, die Dauer und andere Details konfigurieren, wie sich die Animationssequenz entwickeln soll. Dies konfiguriert nicht das tatsächliche Aussehen der Animation, das mithilfe der @keyframes-At-Regel, wie im Abschnitt Definieren einer Animationssequenz mit Keyframes unten beschrieben, festgelegt wird.
Die Untereigenschaften der animation-Eigenschaft sind:
animation-composition-
Gibt die Kompositionsoperation an, die verwendet werden soll, wenn mehrere Animationen dieselbe Eigenschaft gleichzeitig beeinflussen. Diese Eigenschaft ist nicht Teil der
animation-Kurzschreibweise. animation-delay-
Gibt die Verzögerung zwischen dem Laden eines Elements und dem Start einer Animationssequenz an und ob die Animation sofort von Anfang an oder mitten in der Animation beginnen soll.
animation-direction-
Gibt an, ob die erste Iteration einer Animation vorwärts oder rückwärts verlaufen soll und ob nachfolgende Iterationen die Richtung bei jedem Durchlauf der Sequenz wechseln oder zum Startpunkt zurücksetzen und wiederholen sollen.
animation-duration-
Gibt die Zeitdauer an, in der eine Animation einen Zyklus abschließt.
animation-fill-mode-
Gibt an, wie eine Animation Stile auf ihr Ziel anwendet, bevor und nachdem sie ausgeführt wird.
Hinweis: Im Fall des Animations-Fill-Modus forwards verhalten sich animierte Eigenschaften, als ob sie in einem
will-change-Eigenschaftswert enthalten wären. Wenn ein neuer Stacking-Kontext während der Animation erstellt wurde, behält das Zielelement den Stacking-Kontext bei, nachdem die Animation beendet ist. animation-iteration-count-
Gibt die Anzahl der Wiederholungen einer Animation an.
animation-name-
Gibt den Namen der
@keyframes-At-Regel an, die die Keyframes einer Animation beschreibt. animation-play-state-
Gibt an, ob eine Animationssequenz angehalten oder abgespielt werden soll.
animation-timeline-
Gibt die Zeitachse an, die verwendet wird, um den Fortschritt einer CSS-Animation zu steuern.
animation-timing-function-
Gibt an, wie eine Animation durch Keyframes über Beschleunigungskurven verläuft.
Definieren einer Animationssequenz mit Keyframes
Nachdem Sie das Timing der Animation konfiguriert haben, müssen Sie das Aussehen der Animation definieren. Dies geschieht durch die Erstellung von einem oder mehreren Keyframes mithilfe der @keyframes-At-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 ist, der die Animation konfiguriert, verwenden Keyframes einen <percentage>, um den Zeitpunkt in der Animationssequenz anzugeben, zu dem sie stattfinden. 0% gibt den ersten Moment der Animationssequenz an, während 100% den Endzustand der Animation darstellen. 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 unter Verwendung der berechneten Werte aller Attribute.
Sie können optional zusätzliche Keyframes einfügen, die Zwischenschritte zwischen dem Beginn und dem Ende der Animation beschreiben.
Verwendung der Animation-Kurzschreibweise
Die animation-Kurzschreibweise ist nützlich, um Platz zu sparen. Zum Beispiel können einige der Regeln, die wir in diesem Artikel verwendet haben:
p {
animation-duration: 3s;
animation-name: slide-in;
animation-iteration-count: infinite;
animation-direction: alternate;
}
...mithilfe der animation-Kurzschreibweise ersetzt werden.
p {
animation: 3s infinite alternate slide-in;
}
Um mehr über die Reihenfolge zu erfahren, in der verschiedene Animations-Eigenschaftswerte mithilfe der animation-Kurzschreibweise angegeben werden können, siehe die animation-Referenzseite.
Festlegen mehrerer Animations-Eigenschaftswerte
Die CSS-Animations-Langschreibeigenschaften können mehrere Werte akzeptieren, die durch Kommas getrennt sind. Diese Funktion kann verwendet werden, wenn Sie mehrere Animationen innerhalb einer Regel anwenden und unterschiedliche Dauer, Iterationsanzahlen usw. für jede der Animationen festlegen möchten. Werfen wir einen kurzen Blick auf einige Beispiele, um die verschiedenen Permutationen zu erklären.
In diesem ersten Beispiel gibt es drei Dauer- und drei Iterationsanzahlwerte. Also wird jeder Animation ein Wert für Dauer und Iterationsanzahl mit der gleichen Position wie der Animationsname zugewiesen. Die fadeInOut-Animation erhält eine Dauer von 2.5s und eine Iterationsanzahl von 2, und die bounce-Animation erhält eine Dauer von 1s und eine Iterationsanzahl von 5.
animation-name: fadeInOut, moveLeft300px, bounce;
animation-duration: 2.5s, 5s, 1s;
animation-iteration-count: 2, 1, 5;
In diesem zweiten Beispiel sind drei Animationsnamen festgelegt, aber es gibt nur eine Dauer und eine Iterationsanzahl. In diesem Fall erhalten alle drei Animationen die gleiche Dauer und Iterationsanzahl.
animation-name: fadeInOut, moveLeft300px, bounce;
animation-duration: 3s;
animation-iteration-count: 1;
In diesem dritten Beispiel sind drei Animationen angegeben, aber nur zwei Dauern und Iterationsanzahlen. In solchen Fällen, in denen es in der Liste nicht genügend Werte gibt, um jeder Animation einen separaten Wert zuzuweisen, erfolgt die Wertzuweisung von dem ersten zum letzten Element in der verfügbaren Liste und dann erneut vom 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 Zuweisung des Dauerwerts wird nun auf den ersten Wert zurückgesetzt; bounce erhält daher eine Dauer von 2.5s. Die Iterationsanzahlwerte (und alle anderen von Ihnen spezifizierten Eigenschaftswerte) werden auf die gleiche Weise zugewiesen.
animation-name: fadeInOut, moveLeft300px, bounce;
animation-duration: 2.5s, 5s;
animation-iteration-count: 2, 1;
Wenn das Missverhältnis in der Anzahl der Animationen und Animations-Eigenschaftswerte umgekehrt ist, das heißt, es gibt fünf animation-duration-Werte für drei animation-name-Werte, dann finden die zusätzlichen oder ungenutzten Animations-Eigenschaftswerte, in diesem Fall zwei animation-duration-Werte, keine Anwendung auf eine Animation und werden ignoriert.
Beispiele
>Text über das Browserfenster gleiten lassen
Dieses grundlegende Beispiel stylt ein <p>-Element mithilfe der translate- und scale-Übergangseigenschaften so, dass der Text von außerhalb des rechten Randes des Browserfensters hereingleitet.
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, indem die animation-duration-Eigenschaft verwendet wird, und dass der Name der @keyframes-At-Regel, die die Keyframes für die Animationssequenz definiert, slide-in ist.
In diesem Fall haben wir nur zwei Keyframes. Das erste tritt bei 0% auf (unter Verwendung des Aliases 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 Standardgröße), sodass der Absatz doppelt so breit ist wie sein <body>-Block. Dies führt dazu, dass der erste Frame der Animation die Überschrift außerhalb des rechten Randes des Browserfensters zeichnet.
Das zweite Keyframe tritt bei 100% auf (unter Verwendung des Aliases to). Die translate-Eigenschaft wird auf 0% gesetzt und die scale des Elements auf 1, was 100% entspricht. Dies führt dazu, dass die Überschrift ihre Animation in ihrem Standardzustand, bündig am linken Rand des Inhaltsbereichs, beendet.
<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: Laden Sie die Seite neu, um die Animation zu sehen.
Hinzufügen einer weiteren Keyframe-Animation
Fügen wir der Animation aus dem vorherigen Beispiel ein weiteres Keyframe hinzu. Angenommen, wir möchten, dass Alices Name rosa wird, wächst und dann zurück zu seiner ursprünglichen Größe und Farbe schrumpft, während er sich von rechts nach links bewegt. Zwar könnten wir die font-size ändern, aber das Ändern von Eigenschaften, die das Boxmodell betreffen, wirkt sich negativ auf die Leistung aus. Stattdessen umschließen wir ihren Namen mit einem <span> und skalieren und weisen diesem separat eine Farbe zu. Das erfordert das Hinzufügen einer zweiten Animation, die nur das <span> beeinflusst:
@keyframes grow-shrink {
25%,
75% {
scale: 100%;
}
50% {
scale: 200%;
color: magenta;
}
}
Der vollständige Code sieht jetzt so 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 sagt dem Browser, dass der Name für die ersten und letzten 25% der Animation normal sein soll, aber in der Mitte rosa wird und vergrößert und wieder verkleinert. Wir setzen die display-Eigenschaft des Span-Elements auf inline-block, da die transform-Eigenschaften nicht die nicht-ersetzte inline-level content beeinflussen.
Hinweis: Laden Sie die Seite neu, um die Animation zu sehen.
Die Animation wiederholen
Um die Animation so zu gestalten, dass sie sich selbst wiederholt, 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 her bewegen
Das ließ die Animation sich wiederholen, aber es ist sehr seltsam, dass sie jedes Mal, wenn sie zu animieren beginnt, abrupt zum Anfang zurückspringt. Was wir wirklich wollen, ist, dass sie sich hin und her über den Bildschirm bewegt. Das lässt sich leicht erreichen, indem man animation-direction auf alternate setzt:
p {
animation-duration: 3s;
animation-name: slide-in;
animation-iteration-count: infinite;
animation-direction: alternate;
}
Verwendung von Animationsereignissen
Sie können zusätzliche Kontrolle über Animationen erlangen — sowie nützliche Informationen über sie — indem Sie Animationsereignisse nutzen. Diese Ereignisse, dargestellt durch das AnimationEvent-Objekt, können verwendet werden, um zu erkennen, wann Animationen beginnen, enden und eine neue Iteration starten. Jedes Ereignis umfasst die Zeit, zu der es aufgetreten ist, sowie den Namen der Animation, die das Ereignis ausgelöst hat.
Wir werden das Beispiel mit dem gleitenden Text ändern, um einige Informationen über jedes Animationsereignis auszugeben, wenn es auftritt, damit wir sehen können, wie sie funktionieren.
Wir haben die gleiche Keyframe-Animation wie im vorherigen Beispiel eingebaut. Diese Animation wird 3 Sekunden dauern, "slide-in" genannt, 3-mal wiederholt und jedes Mal in einer alternativen Richtung reisen. In den @keyframes werden die Skalierung und die Verschiebung 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 Animation-Event-Listener
Wir werden JavaScript-Code verwenden, um auf alle drei möglichen Animationsereignisse zu hören. Dieser Code konfiguriert unsere Event-Listener; wir rufen ihn auf, wenn das Dokument erstmals geladen wird, um alles 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 ein ziemlich Standardcode; Sie können Details dazu in der Dokumentation zu eventTarget.addEventListener() erhalten. Das letzte, was dieser Code tut, ist, die class auf dem Element, das wir animieren werden, auf "slide-in" zu setzen; wir tun dies, um die Animation zu starten.
Warum? Weil das animationstart-Ereignis sofort ausgelöst wird, sobald die Animation beginnt, und in unserem Fall passiert das, bevor unser Code ausgeführt wird. Also starten wir die Animation selbst, indem wir die Klasse des Elements nachträglich auf den Stil setzen, der animiert wird.
Empfangen der Ereignisse
Die Ereignisse werden an die listener()-Funktion geliefert, 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 Animationsereignis aufgetreten ist, und fügt dann eine entsprechende Notiz zu der <ul> (ungeordneten Liste) hinzu, die wir verwenden, um diese Ereignisse zu protokollieren.
Die Ausgabe, wenn alles gesagt und getan ist, sieht etwa so aus:
- Gestartet: verstrichene Zeit ist 0
- Neue Schleife gestartet um Zeit 3.01200008392334
- Neue Schleife gestartet um Zeit 6.00600004196167
- Beendet: verstrichene Zeit ist 9.234000205993652
Beachten Sie, dass die Zeiten sehr nahe an, aber nicht genau denjenigen entsprechen, die aufgrund des Timings erwartet werden würden, das bei der Konfiguration der Animation festgelegt wurde. Beachten Sie auch, dass nach der letzten Iteration der Animation das animationiteration-Ereignis nicht gesendet wird, sondern stattdessen das animationend-Ereignis gesendet wird.
Nur der Vollständigkeit halber hier ist das HTML, das den Seiteninhalt anzeigt, einschließlich der Liste, in die das Skript Informationen zu den empfangenen Ereignissen 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 ist die Live-Ausgabe.
Hinweis: Laden Sie die Seite neu, um die Animation zu sehen.
Animation von Anzeige und content-visibility
Dieses Beispiel zeigt, wie display und content-visibility animiert werden können. Dieses Verhalten ist nützlich für die Erstellung von Ein-/Ausblend-Animationen, bei denen Sie zum Beispiel einen Container mit display: none aus dem DOM entfernen, aber stattdessen mit opacity sanft ausblenden möchten, anstatt sofort zu verschwinden.
Unterstützende Browser animieren display und content-visibility mit einer Variation des diskreten Animationstyps. Das bedeutet im Allgemeinen, dass Eigenschaften etwa 50% des Weges durch die Animation zwischen zwei Werten wechseln.
Es gibt jedoch eine Ausnahme, nämlich wenn von/auf display: none oder content-visibility: hidden zu einem sichtbaren Wert animiert wird. In diesem Fall wird der Browser zwischen den beiden Werten umschalten, sodass der animierte Inhalt für die gesamte Animationsdauer sichtbar ist.
Zum Beispiel:
- Beim Animieren von
displayvonnonezublock(oder einem anderen sichtbarendisplay-Wert) wird der Wert zublock, bei0%der Animationsdauer umgeschaltet, sodass er die gesamte Dauer über sichtbar ist. - Beim Animieren von
displayvonblock(oder einem anderen sichtbarendisplay-Wert) zunonewird der Wert bei100%der Animationsdauer zunoneumgeschaltet, sodass er die gesamte Dauer über sichtbar ist.
HTML
Das HTML enthält zwei <p>-Elemente mit einem dazwischenliegenden <div>, das von display none zu block animiert wird.
<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 Aufnahme 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 zum <div> hinzu, wenn wir möchten, dass es erscheint, 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: