Motion
Motion
Section titled “Motion”Motion in User Interfaces ist mehr als Dekoration – sie ist ein wesentliches Gestaltungsmittel, das Verständnis fördert, Feedback gibt und emotionale Bindung schafft. Celestia definiert Motion-Prinzipien für subtile, zweckmässige Animationen.
Motion-Philosophie
Section titled “Motion-Philosophie”Zweck vor Dekoration
Section titled “Zweck vor Dekoration”Jede Animation in Celestia hat einen klaren Zweck:
Orientierung:
- Zeigt, woher Elemente kommen und wohin sie gehen
- Macht räumliche Beziehungen verständlich
- Verhindert Desorientierung bei Kontextwechseln
Feedback:
- Bestätigt Benutzeraktionen
- Signalisiert Systemzustände (Laden, Erfolg, Fehler)
- Macht Interfaces reaktionsfreudiger
Hierarchie:
- Lenkt Aufmerksamkeit auf wichtige Elemente
- Unterstützt die Informationsstruktur
- Führt den Blick des Nutzers
Emotion:
- Schafft Freude bei der Interaktion
- Verleiht der Marke Persönlichkeit
- Macht technische Abläufe menschlicher
Subtilität
Section titled “Subtilität”Celestia-Animationen sind dezent und nicht aufdringlich:
- Kurze Dauern (meist unter 500ms)
- Sanfte Easing-Funktionen
- Konsistente Bewegungsmuster
- Respekt vor Nutzerpräferenzen (Reduced Motion)
Timing
Section titled “Timing”Durations (Dauern)
Section titled “Durations (Dauern)”Die Dauer einer Animation hängt von ihrer Komplexität und dem Kontext ab:
| Kategorie | Dauer | Verwendung |
|---|---|---|
| Fast | 100-150ms | Micro-interactions (Hover, Focus) |
| Normal | 200-300ms | Standard-Übergänge |
| Slow | 300-500ms | Komplexe Animationen, Page-Transitions |
Design Tokens:
--animation-duration-fast: 150ms;--animation-duration-normal: 250ms;--animation-duration-slow: 400ms;Wann welche Dauer?
Section titled “Wann welche Dauer?”Fast (100-150ms):
- Button-Hover
- Link-Hover
- Focus-States
- Toggle-Switches
- Icon-Animationen
Normal (200-300ms):
- Dropdown-Öffnen
- Modal-Öffnen/Schliessen
- Accordion
- Tabs-Wechsel
- Formular-Validierung
Slow (300-500ms):
- Page-Transitions
- Sidebar ein-/ausblenden
- Loading-Animationen
- Onboarding-Touren
- Toast-Notifications
Easing Functions
Section titled “Easing Functions”Easing-Funktionen bestimmen, wie eine Animation beschleunigt oder verzögert wird. Sie verleihen Bewegungen natürliche Physik.
Standard Easing
Section titled “Standard Easing”Default (ease-out):
--animation-easing-default: cubic-bezier(0.4, 0, 0.2, 1);- Schnell starten, langsam auslaufen
- Für die meisten UI-Animationen
- Natürliches Gefühl
Enter (decelerate):
--animation-easing-enter: cubic-bezier(0, 0, 0.2, 1);- Elemente erscheinen (Enter)
- Modals, Dropdowns, Popovers
- Sanftes Hereingleiten
Exit (accelerate):
--animation-easing-exit: cubic-bezier(0.4, 0, 1, 1);- Elemente verschwinden (Exit)
- Schnelles Entfernen
- Weniger prominent als Enter
Bounce (overshoot):
--animation-easing-bounce: cubic-bezier(0.68, -0.55, 0.265, 1.55);- Spielerisch, aufmerksamkeitsstark
- Für Erfolgszustände
- Sparsam einsetzen
Easing-Anwendung
Section titled “Easing-Anwendung”/* Standard-Übergang */.button { transition: all var(--animation-duration-fast) var(--animation-easing-default);}
/* Element erscheint */.modal { animation: fadeIn var(--animation-duration-normal) var(--animation-easing-enter);}
/* Element verschwindet */.toast.hide { animation: slideOut var(--animation-duration-fast) var(--animation-easing-exit);}Animation Patterns
Section titled “Animation Patterns”Fade (Ein-/Ausblenden)
Section titled “Fade (Ein-/Ausblenden)”Verwendung: Subtile Übergänge, Content-Wechsel
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; }}
@keyframes fadeOut { from { opacity: 1; } to { opacity: 0; }}
.element { animation: fadeIn var(--animation-duration-normal) var(--animation-easing-enter);}Slide (Gleiten)
Section titled “Slide (Gleiten)”Verwendung: Seitliche Bewegungen, Drawers, Toasts
@keyframes slideInRight { from { transform: translateX(100%); opacity: 0; } to { transform: translateX(0); opacity: 1; }}
@keyframes slideInBottom { from { transform: translateY(100%); opacity: 0; } to { transform: translateY(0); opacity: 1; }}Scale (Skalieren)
Section titled “Scale (Skalieren)”Verwendung: Modals, Popovers, Hervorhebungen
@keyframes scaleIn { from { transform: scale(0.95); opacity: 0; } to { transform: scale(1); opacity: 1; }}
.modal { animation: scaleIn var(--animation-duration-normal) var(--animation-easing-enter);}Rotate (Drehen)
Section titled “Rotate (Drehen)”Verwendung: Loading-Indikatoren, Icons
@keyframes spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); }}
.loading-spinner { animation: spin 1s linear infinite;}Shake (Schütteln)
Section titled “Shake (Schütteln)”Verwendung: Fehler, Invalid Input
@keyframes shake { 0%, 100% { transform: translateX(0); } 10%, 30%, 50%, 70%, 90% { transform: translateX(-4px); } 20%, 40%, 60%, 80% { transform: translateX(4px); }}
.input-error { animation: shake var(--animation-duration-normal) var(--animation-easing-default);}Micro-Interactions
Section titled “Micro-Interactions”Micro-Interactions sind subtile Animationen bei einzelnen UI-Elementen:
Hover States
Section titled “Hover States”Buttons:
.button { background: var(--color-primary); transform: translateY(0); transition: background var(--animation-duration-fast) var(--animation-easing-default), transform var(--animation-duration-fast) var(--animation-easing-default);}
.button:hover { background: var(--color-primary-hover); transform: translateY(-1px);}
.button:active { transform: translateY(0);}Links:
.link { position: relative; text-decoration: none;}
.link::after { content: ""; position: absolute; bottom: -2px; left: 0; width: 0; height: 2px; background: currentColor; transition: width var(--animation-duration-fast) var(--animation-easing-default);}
.link:hover::after { width: 100%;}Focus States
Section titled “Focus States”Sichtbare Fokus-Indikatoren mit Animation:
.interactive-element:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--color-focus-ring); transition: box-shadow var(--animation-duration-fast) var(--animation-easing-default);}Loading States
Section titled “Loading States”Button Loading:
.button--loading { position: relative; color: transparent;}
.button--loading::after { content: ""; position: absolute; width: 16px; height: 16px; border: 2px solid transparent; border-top-color: currentColor; border-radius: 50%; animation: spin 0.8s linear infinite;}Skeleton Loading:
.skeleton { background: linear-gradient( 90deg, var(--color-bg-muted) 25%, var(--color-bg-subtle) 50%, var(--color-bg-muted) 75% ); background-size: 200% 100%; animation: shimmer 1.5s infinite;}
@keyframes shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; }}Toggle Switches
Section titled “Toggle Switches”.toggle { width: 48px; height: 24px; background: var(--color-bg-muted); border-radius: 12px; position: relative; cursor: pointer; transition: background var(--animation-duration-fast) var(--animation-easing-default);}
.toggle-handle { width: 20px; height: 20px; background: white; border-radius: 50%; position: absolute; top: 2px; left: 2px; transition: transform var(--animation-duration-fast) var(--animation-easing-bounce);}
.toggle-active { background: var(--color-primary);}
.toggle-active .toggle-handle { transform: translateX(24px);}Page Transitions
Section titled “Page Transitions”View Transitions API
Section titled “View Transitions API”Moderner Ansatz für Page Transitions in Astro:
<!DOCTYPE html><html lang="de"> <head> <style> @view-transition { navigation: auto; } </style> </head> <body> <slot /> </body></html>Custom Page Transitions
Section titled “Custom Page Transitions”.page-transition-enter { opacity: 0; transform: translateY(20px);}
.page-transition-enter-active { opacity: 1; transform: translateY(0); transition: opacity var(--animation-duration-slow) var(--animation-easing-enter), transform var(--animation-duration-slow) var(--animation-easing-enter);}
.page-transition-exit { opacity: 1;}
.page-transition-exit-active { opacity: 0; transition: opacity var(--animation-duration-fast) var(--animation-easing-exit);}Performance
Section titled “Performance”60fps Ziel
Section titled “60fps Ziel”Animationen müssen flüssig sein:
- Verwenden Sie
transformundopacity(GPU-beschleunigt) - Vermeiden Sie Animationen von
width,height,top,left - Nutzen Sie
will-changesparsam
Gut (GPU-beschleunigt):
.element { transform: translateX(100px); opacity: 0.5;}Schlecht (Layout-Trigger):
.element { left: 100px; width: 200px;}Will-Change
Section titled “Will-Change”/* Vor der Animation */.element { will-change: transform, opacity;}
/* Nach der Animation */.element { will-change: auto;}Reduced Motion
Section titled “Reduced Motion”Respektieren Sie Nutzerpräferenzen:
@media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; }}Alternative für Reduced Motion:
@media (prefers-reduced-motion: reduce) { .modal { animation: none; opacity: 1; }
.dropdown { transition: none; }}Accessibility
Section titled “Accessibility”Prefers-Reduced-Motion
Section titled “Prefers-Reduced-Motion”Celestia respektiert prefers-reduced-motion:
- Alle Animationen werden bei Aktivierung deaktiviert
- Instant-States statt Übergänge
- Keine automatisch abspielenden Animationen
Focus Management
Section titled “Focus Management”Animationen dürfen den Fokus nicht beeinträchtigen:
- Fokus muss sichtbar bleiben
- Fokus-Verlust bei Animationen vermeiden
- Fokus-Trap in Modals mit Animation
Cognitive Load
Section titled “Cognitive Load”Zu viel Animation kann ablenken:
- Maximal eine Animation gleichzeitig
- Keine dauerhaft animierenden Elemente (ausser Loading)
- Vermeidung von blinkenden oder flackernden Effekten
Don’ts
Section titled “Don’ts”Vermeiden Sie:
Section titled “Vermeiden Sie:”Zu lange Animationen:
- ❌ Animationen über 500ms (ausser Page Transitions)
- ❌ Unnötige Verzögerungen
Zu viele gleichzeitige Animationen:
- ❌ Mehrere Elemente, die gleichzeitig animieren
- ❌ Kaskadierende Animationen ohne Nutzen
Ablenkende Animationen:
- ❌ Autoplay-Animationen, die nicht stoppen
- ❌ Blinkende oder flackernde Effekte
- ❌ Übertriebene Bounce-Effekte
Performance-Probleme:
- ❌ Animation von Layout-Eigenschaften
- ❌ Animation während Scroll-Events
- ❌ Zu viele parallele Animationen
Inkonsistenz:
- ❌ Verschiedene Dauern für ähnliche Animationen
- ❌ Gemischte Easing-Funktionen ohne Konzept
Best Practices
Section titled “Best Practices”- Definierte Dauern und Easing verwenden
- Konsistente Animationen für ähnliche Aktionen
- Reduced Motion respektieren
- Performance-Optimierung (transform, opacity)
- Natürliche Physik (Easing-Funktionen)
- Zweckmässigkeit prüfen
- Subtilität bevorzugen
Don’ts
Section titled “Don’ts”- Animation um der Animation willen
- Lange Dauern (> 500ms für UI)
- Layout-Properties animieren
- Reduced Motion ignorieren
- Kognitive Überlastung durch Bewegung
- Autoplay ohne Pause-Möglichkeit
Beispiel: Vollständige Motion-Implementation
Section titled “Beispiel: Vollständige Motion-Implementation”:root { /* Durations */ --animation-duration-fast: 150ms; --animation-duration-normal: 250ms; --animation-duration-slow: 400ms;
/* Easings */ --animation-easing-default: cubic-bezier(0.4, 0, 0.2, 1); --animation-easing-enter: cubic-bezier(0, 0, 0.2, 1); --animation-easing-exit: cubic-bezier(0.4, 0, 1, 1); --animation-easing-bounce: cubic-bezier(0.68, -0.55, 0.265, 1.55);}
/* Button mit Hover-Animation */.button { transition: background-color var(--animation-duration-fast) var(--animation-easing-default), transform var(--animation-duration-fast) var(--animation-easing-default), box-shadow var(--animation-duration-fast) var(--animation-easing-default);}
.button:hover { transform: translateY(-2px); box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);}
.button:active { transform: translateY(0); transition-duration: 100ms;}
/* Modal mit Scale-Animation */.modal { animation: scaleIn var(--animation-duration-normal) var(--animation-easing-enter);}
@keyframes scaleIn { from { opacity: 0; transform: scale(0.95); } to { opacity: 1; transform: scale(1); }}
/* Reduced Motion Support */@media (prefers-reduced-motion: reduce) { .button, .modal { transition: none; animation: none; }}Motion ist ein mächtiges Werkzeug im Design-Toolkit. Wenn sie subtil, zweckmässig und respektvoll eingesetzt wird, verbessert sie das Nutzererlebnis erheblich. Die Kunst liegt in der Zurückhaltung.