Animation Praxis

Zuletzt aktualisiert am 15. Februar 2026

Theorie ist das eine, echte Animationen bauen das andere. In diesem Artikel findest du die häufigsten Animations-Patterns, die du in realen Projekten brauchst: Loading-Spinner, Fade-In-Effekte, Slide-Animationen, Hover-Kombinationen und Skeleton-Loading. Jedes Beispiel kannst du direkt kopieren und anpassen. Am Ende findest du die wichtigsten Performance-Regeln, damit deine Animationen auch auf schwächeren Geräten flüssig laufen.

Syntax
animation: <name> <duration> <timing> <delay> <count> <direction> <fill-mode>
Initialwert
(siehe Einzeleigenschaften)
Vererbt
Nein
Animierbar
Nein

Loading Spinner

Kreis-Spinner

Kreis-Spinner
@keyframes spin {
  to { transform: rotate(360deg); }
}

.circle-spinner {
  width: 36px;
  height: 36px;
  border: 3px solid #e2e8f0;
  border-top-color: #1a56db;
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
}

Der klassische Spinner: Ein Kreis mit transparentem Border, nur die obere Kante ist farbig. Die linear Timing-Function sorgt für konstante Drehgeschwindigkeit ohne Beschleunigung oder Verzögerung.

Punkt-Spinner (Dots)

Punkt-Spinner mit gestaffeltem Delay
@keyframes dot-bounce {
  0%, 80%, 100% {
    transform: scale(0.6);
    opacity: 0.4;
  }
  40% {
    transform: scale(1);
    opacity: 1;
  }
}

.dot {
  animation: dot-bounce 1.4s ease-in-out infinite;
}

.dot:nth-child(2) { animation-delay: 0.16s; }
.dot:nth-child(3) { animation-delay: 0.32s; }

Die drei Punkte springen nacheinander hoch. Das gestaffelte animation-delay sorgt für den Welleneffekt. Dieser Spinner wirkt verspielter und eignet sich gut für Consumer-Apps.

Fade-In-Effekte

Einfaches Einblenden

Einfaches Einblenden
@keyframes fade-in {
  from { opacity: 0; }
  to { opacity: 1; }
}

.fade-card {
  animation: fade-in 1.5s ease both;
}

Der einfachste Effekt: Das Element blendet von unsichtbar zu sichtbar ein. Das both als fill-mode sorgt dafür, dass das Element vor der Animation unsichtbar bleibt und nach der Animation sichtbar.

Fade-In mit Versatz nach oben

Fade-In mit Versatz nach oben
@keyframes fade-up {
  from {
    opacity: 0;
    transform: translateY(20px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.fade-up-card {
  animation: fade-up 0.6s ease both;
}

.fade-up-card:nth-child(2) { animation-delay: 0.15s; }
.fade-up-card:nth-child(3) { animation-delay: 0.3s; }

Dieser Effekt kombiniert Opacity mit vertikaler Bewegung. Die Elemente starten 20 Pixel tiefer und bewegen sich nach oben während sie einblenden. Das gestaffelte Delay lässt sie nacheinander erscheinen, ein sehr beliebter Effekt für Landing Pages.

Slide-Animationen

Einfahrende Cards mit gestaffeltem Delay

Einfahrende Cards mit Delay
@keyframes slide-in {
  from {
    transform: translateX(-30px);
    opacity: 0;
  }
  to {
    transform: translateX(0);
    opacity: 1;
  }
}

.slide-card {
  animation: slide-in 0.5s ease both;
}

.slide-card:nth-child(1) { animation-delay: 0s; }
.slide-card:nth-child(2) { animation-delay: 0.1s; }
.slide-card:nth-child(3) { animation-delay: 0.2s; }
.slide-card:nth-child(4) { animation-delay: 0.3s; }

Die Cards fahren von links ein. Mit 100ms Delay zwischen den Elementen entsteht ein eleganter Kaskadeneffekt. Du kannst die Richtung auch umkehren mit translateX(30px) für eine Einfahrt von rechts.

Hover-Effekte

Card mit kombinierten Effekten

Transition + Animation kombiniert
@keyframes subtle-glow {
  0%, 100% { box-shadow: 0 0 0 rgba(26, 86, 219, 0); }
  50% { box-shadow: 0 0 20px rgba(26, 86, 219, 0.15); }
}

.hover-card {
  transition: transform 0.3s ease, border-color 0.3s ease;
}

.hover-card:hover {
  transform: translateY(-4px);
  border-color: #93c5fd;
  animation: subtle-glow 2s ease-in-out infinite;
}

Hier siehst du, wie transition und animation zusammenarbeiten: Die Transition steuert den Lift-Effekt und die Border-Farbe beim Hover. Die Animation lässt einen subtilen Glow-Effekt pulsieren. Diese Kombination wirkt sehr hochwertig und zieht Aufmerksamkeit.

Skeleton-Loading

Shimmer-Effekt

Skeleton-Loading mit Shimmer
@keyframes shimmer {
  0%   { background-position: -200% 0; }
  100% { background-position: 200% 0; }
}

.skeleton {
  background: linear-gradient(
    90deg,
    #e2e8f0 25%,
    #f1f5f9 50%,
    #e2e8f0 75%
  );
  background-size: 200% 100%;
  animation: shimmer 1.5s ease-in-out infinite;
}

Der Shimmer-Effekt ist das Erkennungsmerkmal moderner Apps. Ein Gradient wandert über die Fläche und suggeriert Aktivität. Der Trick: Der Gradient ist doppelt so breit wie das Element (background-size: 200% 100%), und die Animation verschiebt nur die Position. Dadurch entsteht der sanfte Lichtschein-Effekt.

Performance Best Practices

Nur transform und opacity animieren

Diese beiden Properties werden auf der GPU gerendert und lösen weder Layout-Neuberechnungen noch Repaint-Vorgänge aus. Alles andere (width, height, margin, padding, top, left, background-color) ist deutlich teurer. Wenn du z.B. eine Box größer machen willst, verwende transform: scale(1.2) statt width: 120%.

will-change sparsam einsetzen

Mit will-change: transform sagst du dem Browser, dass sich ein Element bald verändern wird. Der Browser kann dann optimieren und z.B. das Element auf eine eigene Layer legen. Aber: Zu viele will-change-Deklarationen verbrauchen GPU-Speicher. Setze will-change nur auf Elemente, die tatsächlich animiert werden, und entferne die Property nach der Animation (per JavaScript). Verwende es nicht als Dauer-Optimierung auf 50 Elementen gleichzeitig.

Layout-Thrashing vermeiden

Wenn du width oder height animierst, muss der Browser für jeden Frame das gesamte Layout neu berechnen. Das führt bei komplexen Seiten zu ruckeligen Animationen. Verwende stattdessen transform: scale() oder transform: translate(), wo immer möglich. Der Browser kann diese Transformationen auf der GPU rendern, ohne den Layout-Prozess zu triggern.

Animation-Events nutzen

JavaScript bietet dir Events wie animationstart, animationend und animationiteration. Damit kannst du Code ausführen, wenn eine Animation startet oder endet, zum Beispiel um Klassen zu entfernen, DOM-Elemente zu löschen oder Follow-up-Animationen zu starten. Das ist deutlich sauberer als mit festen Timeouts zu arbeiten.

Animationen für prefers-reduced-motion deaktivieren

Viele Nutzer haben in ihren Systemeinstellungen aktiviert, dass Bewegungen reduziert werden sollen. Das betrifft Menschen mit vestibulären Störungen, Epilepsie oder Aufmerksamkeitsstörungen. Deaktiviere Animationen für diese Nutzer mit folgendem CSS:

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

Alternativ kannst du in deinen Keyframes zwischen einer vollen Animation und einer statischen Version wechseln.

Barrierefreiheit

Bewegung reduzieren: Nicht alle Menschen vertragen starke Animationen. Nutzer mit vestibulären Störungen, Epilepsie oder Aufmerksamkeitsstörungen können durch ständige Bewegung auf dem Bildschirm überfordert oder sogar krank werden. Die Media Query prefers-reduced-motion: reduce erlaubt es dir, Animationen für diese Nutzer zu deaktivieren oder auf ein Minimum zu reduzieren. Behandle diese Media Query nicht als optional: Sie ist eine Barrierefreiheits-Anforderung.

Endlos-Animationen brauchen Kontrolle: Loading-Spinner und Shimmer-Effekte laufen endlos, bis du sie stoppst. Stelle sicher, dass sie verschwinden, sobald der Ladevorgang abgeschlossen ist. Verwende aria-live-Regionen, um Screenreader-Nutzer über Statusänderungen zu informieren, z.B. <div aria-live="polite">Daten werden geladen...</div>. Wenn die Daten fertig geladen sind, aktualisiere den Text zu “Daten geladen” und entferne den Spinner.

Blinkende Inhalte vermeiden: WCAG 2.3.1 verlangt, dass nichts häufiger als dreimal pro Sekunde blinkt. Sehr schnelle Blink-Effekte können epileptische Anfälle auslösen. Wenn du mit opacity-Animationen arbeitest, stelle sicher, dass die animation-duration lang genug ist. Ein Blinken alle 0.3 Sekunden ist zu schnell, verwende mindestens 0.5 Sekunden.

Häufige Fehler

  • Loading-Spinner bleibt sichtbar nach Ladevorgang: Du hast vergessen, die Animation per JavaScript zu entfernen oder das Element zu verstecken.
  • Skeleton-Loading ohne feste Größe: Wenn die echten Inhalte laden, springt das Layout. Gib den Skeleton-Elementen dieselben Dimensionen wie die späteren Inhalte.
  • Zu viele gleichzeitige Animationen: 50 Elemente, die gleichzeitig einblenden, überfordern die GPU und machen die Seite träge. Reduziere die Anzahl oder staffel die Animationen stärker.
  • Animation auf width/height statt transform: Du animierst width: 100px zu width: 200px. Das löst teure Layout-Neuberechnungen aus. Verwende transform: scale().
  • prefers-reduced-motion vergessen: Barrierefreiheit ist kein Nice-to-Have. Deaktiviere Animationen für Nutzer, die das in ihren Systemeinstellungen aktiviert haben.

Browser-Kompatibilität

Alle in diesem Artikel verwendeten Animations-Eigenschaften werden von allen modernen Browsern vollständig unterstützt.

ClientUnterstützungHinweise
ChromeKomplett
FirefoxKomplett
SafariKomplett
EdgeKomplett
OperaKomplett

Email-Kompatibilität

CSS-Animationen funktionieren in HTML-Emails nur eingeschränkt. Verwende sie nur als Progressive Enhancement.

ClientUnterstützungHinweise
Apple MailTeilweiseEinfache Animationen funktionieren, komplexe werden teilweise ignoriert
GmailKeineCSS-Animationen werden komplett entfernt
OutlookKeineKein Support für animation oder @keyframes
ThunderbirdKomplett
Yahoo MailKeineKein Support für CSS-Animationen

Verwandte Eigenschaften

Bleib auf dem Laufenden

Erhalte neue Inhalte direkt in dein Postfach

Mit der Anmeldung akzeptierst du unsere Datenschutzerklärung. Du kannst dich jederzeit über den Link in den E-Mails wieder abmelden.

Was erwartet dich?

Neue Artikel & Videos

Wenn ich was Neues veröffentliche, erfährst du's hier zuerst.

Plattform & Kurs-Updates

Neue Kurse, Referenz-Updates und gelegentlich Sonderpreise zum Launch.

Einmal die Woche in deinem Postfach

Kurz, auf den Punkt, kein Spam.