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.
animation: <name> <duration> <timing> <delay> <count> <direction> <fill-mode> (siehe Einzeleigenschaften) Loading 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;
}<div class="spinner-demo">
<div class="circle-spinner"></div>
<span>Daten werden geladen...</span>
</div>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)
@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; }<div class="dots-demo">
<div class="dots">
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
</div>
<span>Einen Moment...</span>
</div>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
@keyframes fade-in {
from { opacity: 0; }
to { opacity: 1; }
}
.fade-card {
animation: fade-in 1.5s ease both;
}<div class="fade-demo">
<div class="fade-card"><strong>Erfolgreich gespeichert</strong><br>Deine Änderungen wurden übernommen.</div>
</div>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
@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; }<div class="fade-up-demo">
<div class="fade-up-card"><h3>Schritt 1</h3><p>Planen</p></div>
<div class="fade-up-card"><h3>Schritt 2</h3><p>Umsetzen</p></div>
<div class="fade-up-card"><h3>Schritt 3</h3><p>Testen</p></div>
</div>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
@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; }<div class="slide-cards">
<div class="slide-card">Posteingang (12 neue)</div>
<div class="slide-card">Entwürfe (3)</div>
<div class="slide-card">Gesendet (47)</div>
<div class="slide-card">Archiv (231)</div>
</div>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
@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;
}<div class="hover-demo">
<div class="hover-card">
<h3>Feature-Card</h3>
<p>Hover kombiniert transition für den Lift-Effekt und animation für den Glow.</p>
<span class="tag">Neu</span>
</div>
</div>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
@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;
}<div class="skeleton-demo">
<div class="skeleton-avatar"></div>
<div class="skeleton-line skeleton-title"></div>
<div class="skeleton-line"></div>
<div class="skeleton-line"></div>
<div class="skeleton-line skeleton-short"></div>
</div>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: 100pxzuwidth: 200px. Das löst teure Layout-Neuberechnungen aus. Verwendetransform: 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.
| Client | Unterstützung | Hinweise |
|---|---|---|
| Chrome | Komplett | — |
| Firefox | Komplett | — |
| Safari | Komplett | — |
| Edge | Komplett | — |
| Opera | Komplett | — |
Email-Kompatibilität
CSS-Animationen funktionieren in HTML-Emails nur eingeschränkt. Verwende sie nur als Progressive Enhancement.
| Client | Unterstützung | Hinweise |
|---|---|---|
| Apple Mail | Teilweise | Einfache Animationen funktionieren, komplexe werden teilweise ignoriert |
| Gmail | Keine | CSS-Animationen werden komplett entfernt |
| Outlook | Keine | Kein Support für animation oder @keyframes |
| Thunderbird | Komplett | — |
| Yahoo Mail | Keine | Kein Support für CSS-Animationen |
Verwandte Eigenschaften
Bleib auf dem Laufenden
Erhalte neue Inhalte direkt in dein Postfach
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.