Keyframe Animations
Jank!! Performance, Link abspeichern!
Syntax
Section titled “Syntax”Keyword @keyframes:
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; }}Jede keyframe animation braucht einen Namen! Diese Namen funktionieren wie globale Variabe. Wir können überall im CSS darauf zurückgreifen. Daher spielt es auch keine Rolle, an welcher Stelle im CSS sie stehen (vg. hoisting in JavaScript).
Keyframe animations ticken ähnlich wie Funktionen in JavaScript. Wir definieren eine Funktion, aber von alleine tut sie erst einmal gar nichts. In JavaScript müssen wir die Funktion aufrufen, in CSS müssen wir die keyframe animation auf ein bestimmtes Element anwenden. Das machen wir mit der animation Eigenschaft:
.element { animation: fadeIn 1000ms;}Die Eigenschaft benötigt mindestens zwei Werte:
- den Namen der keyframe animation
- die Dauer der Animation (angegeben in Millisekunden
ms)
Wenn wir die fadeIn Animation anwenden, wird alles, was im from-Block steht, sofort auf das Element angewendet, und geht dann über die Dauer von einer Sekunde auf das CSS im to-Block über.
Shorthand
Section titled “Shorthand”animation ist eine Shorthand, in Langform würde sie so aussehen:
.element { animation-name: fadeIn; animation-duration: 1000ms;}Die Shorthand ist aber weitaus gebräuchlicher.
Animating multiple properties
Section titled “Animating multiple properties”Wir können mehrere Eigenschaften mit einer Animation ändern.
<div class="box">Hello World!</div>@keyframe fadeIn { from { opacity: 0; background-color: royalblue; color: white; } to { opacity: 1; background-color: darkseagreen; color: black; }}
.box { inline-size: fit-content; padding: 1.5rem 3rem; background-color: darkseagreen; font-weight: bold; font-size: 1.5rem; color: black; animation: fadeIn 2000ms;}Looped animations
Section titled “Looped animations”Keyframe animations laufen immer nur einmal, aber mit dem Keyword infinite können wir sie in einer Schleife abspielen (nützlich z.B. zum laden von Spinnern). Die Langform dazu ist animation-iteration-count.
.element { animation: animationName 1000ms infinite;}Mehrstufige Animationen
Section titled “Mehrstufige Animationen”Mit from-to animieren wir von einem Status zu anderen. Wenn wir eine feiner abgestufte Animation brauchen, können wir das mit Prozentwerten machen (Animation angehalten!!!)
@keyframes fancySpin { 0% { transform: rotate(0deg) scale(1); } 25% { transform: rotate(180deg) scale(1); } 50% { transform: rotate(180deg) scale(1.5); } 75% { transform: rotate(0deg) scale(1.5); } 100% { transform: rotate(0deg) scale(1); }}Timing functions
Section titled “Timing functions”Mit verschiedenen Timing-Funktionen können wir das “Feeling” der Animationen kontrollieren:
.element { animation spin 1000ms infinite linear;}.element { animation spin 1000ms infinite ease-in-out;}Alternierende Animationen
Section titled “Alternierende Animationen”Ein Blinken (also ein oszillieren zwischen zwei Werten) könnten wir als dreistufige Animation erzeugen (0% - opacity: 0, 50% - opacity: 1, 100% - opacity: 0). Die elegantere Variante ist aber, das Keyword alternate zu verwenden. Dann springt die Animation auch hin und her:
<style> @keyframes twinkle { from { opacity: 0; } to { opacity: 1; } }</style>
.element { animation: twinkle 1000ms infinite alternate ease-in-out;}Das Keyword alternate wird von der (Longhand-)Eigenschaft animation-direction verwendet. Sie kann drei verschiedene Werte annehmen:
normal(default): die Animation startet bei 0% und läuft bis 100%reverse: die Animation startet bei 100% und läuft zurück zu 0% (wie wenn wir einen Film rückwärts abspielen)alternate: die Animation läuft vor und zurück und wechselt dabei die Richtung
Stacked Animations
Section titled “Stacked Animations”Wir können einem Element mehrere Animationen zuweisen! Das hat den großen Vorteil, dass wir für jeden Keyframe eigene Werte (z.B. Dauer) definieren können. Dem Element weisen wir eine kommagetrennte Liste mit den Namen der Animationen zu.
.element { animation: fadeIn 1000ms, bounce 500ms infinite alternate ease-out;}Fill mode
Section titled “Fill mode”Wenn wir eine fadeOut-Animation machen, also die opacity von 1 nach 0 animieren, dann fadet das Element aus, springt aber dann wieder in seinen Ursprungszustand zurück. Das passiert deswegen, weil opacity nur während der Dauer der Animation angewendet wird. Eine Möglichkeit, dem entgegenzuwirken, wäre, dem Element den Endzustand per CSS mitzugeben, d.h, wenn es ausgefadet wird, sollte es grundsätzlich ein opacity: 0 bekommen. Während die Animation läuft, kommen die Deklarationen innerhalb des Keyframes zur Anwendung und überschreiben die des Elementselektors. Dieser Ansatz funktioniert, ist aber nicht optimal, da die Deklaration opacity: 0 doppelt vergeben werden muss - im Keyframe und im Style des Elements.
Filling forwards
Section titled “Filling forwards”Statt sich auf Fallback-Deklarationen zu verlassen, können wir animation-fill-mode verwenden.
@keyframes fadeOut { from { opacity: 1; } to { opacity: 0; }}
.box { /* Add the "forwards" keyword: */ animation: fadeOut 1000ms forwards;}animation-fill-mode: forward (default: none) bedeutet, dass das letzte CSS aus der Keyframe-Animation zur Anwendung kommt, selbst wenn im Element selbst etwas anderes deklariert ist.
Animation delay (und filling backwards)
Section titled “Animation delay (und filling backwards)”Wenn wir mit animation-delay: 1000ms eine Verzögerung einbauen, sehen wir denselben Effekt wie beim fadeIn-Beispiel zuvor: Das Element ist da, und erst wenn die Animation beginnt, wird es aus- und dann langsam wieder eingeblendet. Das ist irgendwie sinnlos, aber hier können wir uns mit dem Keyword backwards behelfen. Das sorgt dafür, ähnlich wie forwards, dass das Element den Wert vom Beginn der Animation annimmt. Das Keyword nimmt also das CSS aus dem from-Block und wendet es auf das Element an, sobald es geladen wird.
Es gibt auch noch both, das in speziellen Fällen sinnvoll sein kann. Dabei werden der erste und der letzte Wert auf das Element angewendet. both sollte aber nicht standardmäßig angewendet werden. Der Nachteil von fill-modes ist nämlich, dass sie alle weiteren Änderungen (z.B. mit JavaScript Element.style.opacity) überschreiben.