CSS Animation – @keyframes
CSS-Animationen ermöglichen es, Eigenschaften von HTML-Elementen über einen bestimmten Zeitraum hinweg zu verändern. Sie sind zeitbasiert und erzeugen Bewegung, Übergänge oder visuelle Effekte.
Eine CSS-Animation startet automatisch, sobald das Element geladen ist. Nach dem letzten Keyframe springt das Element – sofern nichts anderes definiert ist – wieder in seinen Ausgangszustand zurück.
Grundlagen
Die Grundlage dafür bildet die Regel @keyframes. Sie beschreibt einzelne Zustände (Schlüsselbilder), die während der Animation durchlaufen werden.
Eine CSS-Animation besteht immer aus zwei klar getrennten Teilen:
- der Beschreibung der Bewegung mit
@keyframes - der Steuerung der Animation über die
animation-Eigenschaften
Wichtig:
- Animationen laufen automatisch ab
- Sie benötigen keinen Benutzer-Trigger
- Sie können aus beliebig vielen Zwischenstufen bestehen
Typische Einsatzgebiete:
- Loader & Preloader
- Hinweise und Feedback (z. B. Fehleranimationen)
- UI-Microinteractions
- Dekorative Hintergrund- oder Akzentanimationen
Animation Beispiele
Fade In
Das Element wird über die Eigenschaft opacity langsam eingeblendet. Diese Art von Animation ist sehr performant und wird häufig für UI-Elemente verwendet.
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
.anim-fade {
animation-name: fadeIn;
animation-duration: 5s;
}
Slide In
Das Element bewegt sich aus einer Richtung ins Bild. Die Bewegung erfolgt über transform: translate(), da diese Eigenschaft das Layout nicht beeinflusst.
@keyframes slideIn {
from {
transform: translateX(-50px);
}
to {
transform: translateX(0);
}
}
.anim-slide {
animation-name: slideIn;
animation-duration: 3s;
}
Rotate
Das Element wird kontinuierlich um die eigene Achse gedreht. Solche Animationen werden häufig bei Icons oder Ladeindikatoren eingesetzt.
@keyframes rotateBox {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
.anim-rotate {
animation-name: rotateBox;
animation-duration: 2s;
animation-iteration-count: infinite;
animation-timing-function: linear;
}
Bounce
Durch mehrere Keyframes entsteht eine federnde Bewegung. Diese Art von Animation vermittelt Dynamik und Aufmerksamkeit.
@keyframes bounce {
0% {
transform: translateY(0);
}
50% {
transform: translateY(-40px);
}
100% {
transform: translateY(0);
}
}
.anim-bounce {
animation-name: bounce;
animation-duration: 1s;
animation-iteration-count: infinite;
}
@keyframes Syntax
Mit @keyframes definierst du, wie sich ein Element während der Animation verändert.
from entspricht dabei 0%, to entspricht 100%.
@keyframes animationName {
from { /* Startzustand */}
to { /* Endzustand */ }
}
Komplexere Animationen werden mit Prozentwerten aufgebaut. Du kannst beliebig viele Prozentstufen definieren.
@keyframes animationName {
0% { }
50% { }
100% { }
}
Animation auf ein Element anwenden
Damit eine Animation sichtbar wird, muss sie einem Element zugewiesen werden.
Wichtig: Ohne animation-duration wird keine Animation abgespielt.
.box {
animation-name: fadeIn;
animation-duration: 5s;
}
Merksatz: @keyframes beschreibt, was passiert – animation beschreibt, wie und wann.
Animation-Eigenschaften
animation-durationDauer eines Durchlaufs (Zeitangabe).animation-timing-functionZeitlicher Verlauf (Keyword oder cubic-bezier()).animation-delayStartverzögerung (Zeitangabe).animation-iteration-countWiederholungen (Zahl oderinfinite).animation-directionAbspielrichtung (Keyword).animation-fill-modeVerhalten vor/nach Ende (Keyword).
animation-duration – Dauer
Legt fest, wie lange eine Animation für einen vollständigen Durchlauf benötigt.
animation-duration: 500ms;
animation-duration: 2s;
animation-timing-function – Geschwindigkeit
Bestimmt, wie sich die Geschwindigkeit der Animation über die Zeit verhält.
animation-timing-function: ease;
linear– konstante Geschwindigkeitease– langsam → schnell → langsamease-in– langsamer Startease-out– langsames Endecubic-bezier()– individuell definierbar
animation-delay – Verzögerung
Bestimmt, wie lange gewartet wird, bevor die Animation startet.
animation-delay: 1s;
Negative Werte starten die Animation mitten im Ablauf:
animation-delay: -1s;
animation-iteration-count – Wiederholungen
Legt fest, wie oft eine Animation abgespielt wird.
animation-iteration-count: 3;
animation-iteration-count: infinite;
animation-direction – Richtung
Bestimmt, in welcher Reihenfolge die Keyframes abgespielt werden.
animation-direction: normal;
animation-direction: reverse;
animation-direction: alternate;
animation-fill-mode – Zustand vor & nach der Animation
Definiert, welche Styles ausserhalb der eigentlichen Animation gelten.
animation-fill-mode: forwards;
none– Standardforwards– Endzustand bleibt erhaltenbackwards– Startzustand während Delayboth
Kurzschreibweise
Alle Animation-Eigenschaften können in einer Zeile zusammengefasst werden.
animation: slideIn 2s ease-in-out 0.5s infinite alternate forwards;
Mehrere Elemente staffeln
Sollen mehrere Elemente nicht gleichzeitig, sondern nacheinander erscheinen – z. B. Listeneinträge, Karten oder Galerie-Bilder – reicht eine einzige @keyframes-Regel für alle. Der Unterschied entsteht allein über ein versetztes animation-delay pro Element.
Klassisch: :nth-child()
Jedes Element bekommt über :nth-child() ein eigenes Delay. Funktioniert überall, muss aber für jede Position einzeln geschrieben werden. Ein Beispiel für reines Staffeln beim Laden, ohne Scroll-Trigger, gibt es in dieser Animated Gallery auf CodePen.
Diese Demo startet erst, wenn du bis hierhin scrollst – nicht beim Laden der Seite. Sie kombiniert zwei Techniken: das Delay pro Element für die Staffelung (:nth-child()) mit einer scrollbasierten Timeline, die den Start an die Sichtbarkeit koppelt statt an die Ladezeit (animation-timeline: view()). Mehr dazu: Scroll-driven Animations.
Hinweis: Lädst du die Seite neu, während dieser Abschnitt schon im Sichtbereich ist, spielt die Animation nicht nochmal ab – view() zeigt immer den Zustand, der zur aktuellen Scrollposition passt, statt jedes Mal von vorne zu starten. Kein Bug, das ist der Unterschied zu einer zeitbasierten Animation.
@keyframes staggerIn {
from {
opacity: 0;
transform: translateY(70px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.stagger-demo .samp {
animation: staggerIn 0.6s ease forwards;
}
/* Fallback ohne view()-Support: Staffelung über Sekunden-Delay */
@supports not (animation-timeline: view()) {
.stagger-demo .col:nth-child(1) .samp { animation-delay: 0s; }
.stagger-demo .col:nth-child(2) .samp { animation-delay: 0.25s; }
.stagger-demo .col:nth-child(3) .samp { animation-delay: 0.5s; }
.stagger-demo .col:nth-child(4) .samp { animation-delay: 0.75s; }
}
/* Start an Sichtbarkeit statt an Ladezeit koppeln, Staffelung über Range-Offset */
@supports (animation-timeline: view()) {
.stagger-demo .samp {
animation-timeline: view();
animation-range: entry 0% cover 40%;
}
.stagger-demo .col:nth-child(2) .samp { animation-range: entry 5% cover 60%; }
.stagger-demo .col:nth-child(3) .samp { animation-range: entry 10% cover 80%; }
.stagger-demo .col:nth-child(4) .samp { animation-range: entry 15% cover 100%; }
}
Achtung Falle: :nth-child() zählt Geschwister innerhalb des direkten Elternelements. Steckt jede .samp-Box in einem eigenen .col-Wrapper, ist sie dort jeweils das einzige Kind – :nth-child() muss dann auf den Wrapper zielen, nicht auf .samp selbst.
Neu: sibling-index()
Statt jede Position manuell zu adressieren, liefert sibling-index() die Position eines Elements unter seinen Geschwistern direkt als Zahl – nutzbar in calc(). Eine einzige Regel reicht für beliebig viele Elemente, auch wenn später mehr dazukommen.
.stagger-demo .samp {
animation: staggerIn 0.6s ease forwards;
animation-delay: calc(sibling-index() * 0.15s);
}
Browser-Support (Stand 2026): Chrome, Edge, Opera ab Version 120 stabil. Firefox folgt, Safari ist noch offen. Für produktive Projekte deshalb noch mit :nth-child() arbeiten – sibling-index() als Ausblick, wie es bald einfacher geht.
Performance
Für performante Animationen sollten bevorzugt folgende Properties verwendet werden:
transform und opacity.
Diese Eigenschaften beeinflussen nicht den Layoutfluss und können von der GPU verarbeitet werden.
Problematisch sind: top, left und width, height
Animation vs Transition
Animation: läuft automatisch, kann mehrere Zustände haben.
Transition: benötigt einen Trigger (z. B. :hover).
Beide Techniken ergänzen sich und werden häufig gemeinsam eingesetzt.
Beispiele
See the Pen CSS Animation Blob by Intensivstation (@intensivstation) on CodePen.