Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
| de:modul:m291:learningunits:lu13:theorie:b_general_animations [2026/05/31 22:53] – angelegt gkoch | de:modul:m291:learningunits:lu13:theorie:b_general_animations [2026/05/31 23:20] (aktuell) – gelöscht gkoch | ||
|---|---|---|---|
| Zeile 1: | Zeile 1: | ||
| - | ====== LU13: Keyframe-Animationen & Scroll-Animationen ====== | ||
| - | |||
| - | //(Theorie für Modul M291 – Web Frontend)// | ||
| - | |||
| - | Auf dieser Seite finden Sie die Theorie zu folgenden Themen: | ||
| - | |||
| - | * [[# | ||
| - | * [[# | ||
| - | * [[# | ||
| - | * [[# | ||
| - | * [[# | ||
| - | * [[# | ||
| - | * [[# | ||
| - | * [[# | ||
| - | * [[# | ||
| - | * [[# | ||
| - | * [[# | ||
| - | * [[# | ||
| - | * [[# | ||
| - | |||
| - | ---- | ||
| - | |||
| - | ===== Was ist eine CSS-Animation? | ||
| - | ==== id=" | ||
| - | |||
| - | Ein einzelnes Bild aus einer Animation heisst ein **Frame**. Die Animationstechnik, | ||
| - | |||
| - | {{ : | ||
| - | |||
| - | Eine CSS-Animation besteht aus genau **zwei Teilen**: | ||
| - | |||
| - | - Die **Definition** der Animation mit '' | ||
| - | - Die **Zuweisung** an ein Element mit den '' | ||
| - | |||
| - | Solange nur die Definition vorhanden ist, bewegt sich nichts – erst wenn sie einem Element zugewiesen wird, läuft die Animation. | ||
| - | |||
| - | ---- | ||
| - | |||
| - | ===== @keyframes definieren ===== | ||
| - | ==== id=" | ||
| - | |||
| - | <WRAP center round box 80%> | ||
| - | <code css> | ||
| - | @keyframes einblenden { | ||
| - | from { | ||
| - | opacity: 0; | ||
| - | transform: translateY(20px); | ||
| - | } | ||
| - | to { | ||
| - | opacity: 1; | ||
| - | transform: translateY(0); | ||
| - | } | ||
| - | } | ||
| - | </ | ||
| - | </ | ||
| - | |||
| - | - Die '' | ||
| - | - Danach folgt ein frei wählbarer **Name** – er wird gleich gebraucht, um die Animation zuzuweisen. | ||
| - | - '' | ||
| - | - Im Keyframe stehen CSS-Eigenschaften, | ||
| - | |||
| - | Für mehr als zwei Zustände können beliebig viele Prozent-Schritte angegeben werden: | ||
| - | |||
| - | <WRAP center round box 80%> | ||
| - | <code css> | ||
| - | @keyframes farbwechsel { | ||
| - | from { background-color: | ||
| - | 33% { background-color: | ||
| - | 66% { background-color: | ||
| - | to { background-color: | ||
| - | } | ||
| - | </ | ||
| - | </ | ||
| - | |||
| - | <note tip> | ||
| - | **from / to oder Prozent?** | ||
| - | Geht es nur darum, von Zustand A nach Zustand B zu animieren (z. B. einblenden, verschieben), | ||
| - | </ | ||
| - | |||
| - | ---- | ||
| - | |||
| - | ===== Animation auf ein Element anwenden ===== | ||
| - | ==== id=" | ||
| - | |||
| - | <WRAP center round box 80%> | ||
| - | <code css> | ||
| - | .kachel { | ||
| - | animation-name: | ||
| - | animation-duration: | ||
| - | animation-timing-function: | ||
| - | animation-delay: | ||
| - | animation-iteration-count: | ||
| - | animation-direction: | ||
| - | animation-fill-mode: | ||
| - | } | ||
| - | </ | ||
| - | </ | ||
| - | |||
| - | <WRAP center round box 80%> | ||
| - | ^ Eigenschaft ^ Beispielwert ^ Bedeutung ^ | ||
| - | | '' | ||
| - | | '' | ||
| - | | '' | ||
| - | | '' | ||
| - | | '' | ||
| - | | '' | ||
| - | | '' | ||
| - | | '' | ||
| - | </ | ||
| - | |||
| - | ==== Kurzschreibweise ==== | ||
| - | |||
| - | Alle Eigenschaften lassen sich in einer einzigen Zeile zusammenfassen: | ||
| - | |||
| - | <WRAP center round box 80%> | ||
| - | <code css> | ||
| - | .kachel { | ||
| - | animation: einblenden 0.6s ease 0.2s 1 normal both; | ||
| - | /* | ||
| - | } | ||
| - | </ | ||
| - | </ | ||
| - | |||
| - | <note important> | ||
| - | **Reihenfolge bei zwei Zeitangaben: | ||
| - | '' | ||
| - | </ | ||
| - | |||
| - | ==== Zeitangaben ==== | ||
| - | |||
| - | Zeitangaben können in Sekunden ('' | ||
| - | |||
| - | <WRAP center round box 80%> | ||
| - | <code css> | ||
| - | animation-duration: | ||
| - | animation-duration: | ||
| - | </ | ||
| - | </ | ||
| - | |||
| - | ---- | ||
| - | |||
| - | ===== animation-fill-mode ===== | ||
| - | ==== id=" | ||
| - | |||
| - | Ohne '' | ||
| - | |||
| - | <WRAP center round box 80%> | ||
| - | ^ Wert ^ Bedeutung ^ | ||
| - | | '' | ||
| - | | '' | ||
| - | | '' | ||
| - | | '' | ||
| - | </ | ||
| - | |||
| - | <WRAP center round box 80%> | ||
| - | <code css> | ||
| - | @keyframes hereinschieben { | ||
| - | from { opacity: 0; transform: translateX(-30px); | ||
| - | to { opacity: 1; transform: translateX(0); | ||
| - | } | ||
| - | |||
| - | .element { | ||
| - | opacity: 0; /* Ohne fill-mode wäre das Element vor dem Start kurz sichtbar */ | ||
| - | animation: hereinschieben 0.5s ease 0.3s both; | ||
| - | /* Delay ↑ ↑ fill-mode: both */ | ||
| - | } | ||
| - | </ | ||
| - | </ | ||
| - | |||
| - | Mit '' | ||
| - | |||
| - | ---- | ||
| - | |||
| - | ===== CSS Transforms ===== | ||
| - | ==== id=" | ||
| - | |||
| - | Transformationen sind geometrische Operationen, | ||
| - | |||
| - | <WRAP center round box 80%> | ||
| - | <code css> | ||
| - | /* Verschieben: | ||
| - | transform: translate(20px, | ||
| - | transform: translateX(20px); | ||
| - | transform: translateY(-10px); | ||
| - | |||
| - | /* Skalieren: 1 = Originalgrösse, | ||
| - | transform: scale(1.5); | ||
| - | transform: scale(1.2, 0.8); /* horizontal × vertikal */ | ||
| - | |||
| - | /* Rotieren: positive Werte = im Uhrzeigersinn */ | ||
| - | transform: rotate(45deg); | ||
| - | |||
| - | /* Scheren: Parallelogramm-Effekt */ | ||
| - | transform: skewX(15deg); | ||
| - | transform: skewY(10deg); | ||
| - | </ | ||
| - | </ | ||
| - | |||
| - | ==== Mehrere Transformationen kombinieren ==== | ||
| - | |||
| - | Transformationen können kombiniert werden – die **Reihenfolge beeinflusst das Ergebnis**: | ||
| - | |||
| - | <WRAP center round box 80%> | ||
| - | <code css> | ||
| - | /* Erst rotieren, dann verschieben – Verschiebung erfolgt im rotierten Koordinatensystem */ | ||
| - | transform: rotate(45deg) translate(50px, | ||
| - | |||
| - | /* Erst verschieben, | ||
| - | transform: translate(50px, | ||
| - | </ | ||
| - | </ | ||
| - | |||
| - | ==== transform-origin ==== | ||
| - | |||
| - | Standardmässig liegt der Ursprungspunkt aller Transformationen in der **Mitte des Elements**. Mit '' | ||
| - | |||
| - | <WRAP center round box 80%> | ||
| - | <code css> | ||
| - | /* Rotation um die obere linke Ecke */ | ||
| - | transform-origin: | ||
| - | |||
| - | /* Rotation um die Mitte der Oberkante */ | ||
| - | transform-origin: | ||
| - | |||
| - | /* Rotation um einen Punkt ausserhalb des Elements */ | ||
| - | transform-origin: | ||
| - | </ | ||
| - | </ | ||
| - | |||
| - | <note tip> | ||
| - | '' | ||
| - | </ | ||
| - | |||
| - | ---- | ||
| - | |||
| - | ===== Gestaffelte Animationen mit CSS-Variablen ===== | ||
| - | ==== id=" | ||
| - | |||
| - | Mit einer CSS-Custom-Property lässt sich ein Staffeleffekt erzeugen, ohne für jede Kachel einen eigenen Delay im CSS zu schreiben: | ||
| - | |||
| - | <WRAP center round box 80%> | ||
| - | <code css> | ||
| - | /* CSS: Delay wird aus der CSS-Variable --reihenfolge berechnet */ | ||
| - | .kachel { | ||
| - | animation: einblenden 0.5s ease both; | ||
| - | animation-delay: | ||
| - | } | ||
| - | </ | ||
| - | </ | ||
| - | |||
| - | <WRAP center round box 80%> | ||
| - | <code html> | ||
| - | <!-- HTML: Variable wird pro Element gesetzt --> | ||
| - | <div class=" | ||
| - | <div class=" | ||
| - | <div class=" | ||
| - | </ | ||
| - | </ | ||
| - | |||
| - | In Vue übergibt man den Wert dynamisch über '': | ||
| - | |||
| - | <WRAP center round box 80%> | ||
| - | <code html> | ||
| - | <article : | ||
| - | </ | ||
| - | </ | ||
| - | |||
| - | Das Ergebnis: Kachel 1 startet nach 150 ms, Kachel 2 nach 300 ms, Kachel 3 nach 450 ms – vollständig in CSS gerechnet, ohne JavaScript. | ||
| - | |||
| - | ---- | ||
| - | |||
| - | ===== CSS Transitions vs. @keyframes ===== | ||
| - | ==== id=" | ||
| - | |||
| - | <WRAP center round box 80%> | ||
| - | ^ ^ CSS Transition ^ CSS @keyframes Animation ^ | ||
| - | | **Auslöser** | Benötigt einen Zustandswechsel (Klasse, Hover, Fokus …) | Läuft eigenständig, | ||
| - | | **Zustände** | Von einem Zustand zum nächsten | Beliebig viele Schritte ('' | ||
| - | | **Schleifen** | Nicht vorgesehen | '' | ||
| - | | **Komplexität** | Einfach, direkt auf dem Element | Getrennte '' | ||
| - | | **Geeignet für** | Hover-Effekte, | ||
| - | </ | ||
| - | |||
| - | ==== Transition – Erinnerung ==== | ||
| - | |||
| - | <WRAP center round box 80%> | ||
| - | <code css> | ||
| - | .panel { | ||
| - | height: 0; | ||
| - | opacity: 0; | ||
| - | overflow: hidden; | ||
| - | transition: all 300ms ease-in; | ||
| - | } | ||
| - | |||
| - | .panel.offen { | ||
| - | height: auto; | ||
| - | opacity: 1; | ||
| - | } | ||
| - | </ | ||
| - | </ | ||
| - | |||
| - | Die Transition läuft automatisch, | ||
| - | |||
| - | ---- | ||
| - | |||
| - | ===== CSS Nesting (nativ) ===== | ||
| - | ==== id=" | ||
| - | |||
| - | Seit 2023 unterstützen alle modernen Browser **natives CSS Nesting** – ohne Präprozessor wie SCSS. Regeln können direkt ineinander verschachtelt werden: | ||
| - | |||
| - | <WRAP center round box 80%> | ||
| - | <code css> | ||
| - | /* Ohne Nesting – jede Regel separat */ | ||
| - | .kachel { border-radius: | ||
| - | .kachel img { width: 100%; } | ||
| - | .kachel: | ||
| - | .kachel p { opacity: 0; } | ||
| - | .kachel p.sichtbar { opacity: 1; } | ||
| - | </ | ||
| - | </ | ||
| - | |||
| - | <WRAP center round box 80%> | ||
| - | <code css> | ||
| - | /* Mit Nesting – alles in einem Block */ | ||
| - | .kachel { | ||
| - | border-radius: | ||
| - | |||
| - | img { | ||
| - | width: 100%; /* kompiliert zu: .kachel img */ | ||
| - | } | ||
| - | |||
| - | &:hover { | ||
| - | outline: 2px solid gold; /* kompiliert zu: .kachel: | ||
| - | } | ||
| - | |||
| - | p { | ||
| - | opacity: 0; /* kompiliert zu: .kachel p */ | ||
| - | |||
| - | & | ||
| - | opacity: 1; /* kompiliert zu: .kachel p.sichtbar */ | ||
| - | } | ||
| - | } | ||
| - | } | ||
| - | </ | ||
| - | </ | ||
| - | |||
| - | ==== Das & (Ampersand) ==== | ||
| - | |||
| - | Das ''&'' | ||
| - | |||
| - | <WRAP center round box 80%> | ||
| - | ^ Verschachtelung ^ Kompiliert zu ^ | ||
| - | | '' | ||
| - | | '' | ||
| - | | '' | ||
| - | | '' | ||
| - | </ | ||
| - | |||
| - | < | ||
| - | **Browserunterstützung: | ||
| - | </ | ||
| - | |||
| - | ---- | ||
| - | |||
| - | ===== height: auto animieren (interpolate-size) ===== | ||
| - | ==== id=" | ||
| - | |||
| - | CSS kann normalerweise **nicht** von einer fixen Höhe zu '' | ||
| - | |||
| - | <WRAP center round box 80%> | ||
| - | <code css> | ||
| - | :root { | ||
| - | interpolate-size: | ||
| - | } | ||
| - | </ | ||
| - | </ | ||
| - | |||
| - | Danach funktioniert die Transition auf '' | ||
| - | |||
| - | <WRAP center round box 80%> | ||
| - | <code css> | ||
| - | .beschreibung { | ||
| - | height: 0; | ||
| - | overflow: hidden; | ||
| - | transition: height 300ms ease; | ||
| - | } | ||
| - | |||
| - | .beschreibung.offen { | ||
| - | height: auto; /* jetzt animierbar! */ | ||
| - | } | ||
| - | </ | ||
| - | </ | ||
| - | |||
| - | <note important> | ||
| - | '' | ||
| - | </ | ||
| - | |||
| - | ---- | ||
| - | |||
| - | ===== Scroll-gesteuerte Animationen ===== | ||
| - | ==== id=" | ||
| - | |||
| - | Mit '' | ||
| - | |||
| - | <WRAP center round box 80%> | ||
| - | <code css> | ||
| - | @keyframes aufzoomen { | ||
| - | 0%, 100% { transform: scale(0.7); opacity: 0.4; } | ||
| - | 50% { transform: scale(1); | ||
| - | } | ||
| - | |||
| - | .kachel { | ||
| - | animation: aufzoomen linear; | ||
| - | animation-timeline: | ||
| - | /* ↑ Achse: block = vertikal, inline = horizontal */ | ||
| - | } | ||
| - | </ | ||
| - | </ | ||
| - | |||
| - | * '' | ||
| - | * '' | ||
| - | * '' | ||
| - | |||
| - | ==== Häufige Fehlerquellen ==== | ||
| - | |||
| - | '' | ||
| - | |||
| - | <WRAP center round box 80%> | ||
| - | ^ Problem ^ Lösung ^ | ||
| - | | '' | ||
| - | | '' | ||
| - | | '' | ||
| - | </ | ||
| - | |||
| - | ==== overflow: clip vs. overflow: hidden ==== | ||
| - | ==== id=" | ||
| - | |||
| - | <WRAP center round box 80%> | ||
| - | ^ ^ '' | ||
| - | | **Visuelles Ergebnis** | Inhalt wird abgeschnitten | Inhalt wird abgeschnitten | | ||
| - | | **Scroll-Container** | Ja – erstellt einen neuen Scroll-Container | Nein – kein neuer Scroll-Container | | ||
| - | | **animation-timeline: | ||
| - | | **Scrollbar** | Kann Scrollbar erzeugen (wenn '' | ||
| - | | **Browserunterstützung** | Alle Browser | Chrome 90+, Firefox 102+, Safari 16+ | | ||
| - | </ | ||
| - | |||
| - | **Faustregel: | ||
| - | |||
| - | ---- | ||
| - | |||
| - | ===== UX-Richtlinien für Animationen ===== | ||
| - | ==== id=" | ||
| - | |||
| - | Animationen sollten die User Experience verbessern – nicht ablenken. Die Norman Group (UX-Forschungsinstitut) empfiehlt: | ||
| - | |||
| - | <note tip> | ||
| - | **Norman Group:** „Wenn UI-Animationen subtil, unauffällig und kurz sind, können sie die Benutzererfahrung verbessern, Feedback und Zustandsänderungen kommunizieren, | ||
| - | </ | ||
| - | |||
| - | ==== Empfohlene Animationsdauern ==== | ||
| - | |||
| - | <WRAP center round box 80%> | ||
| - | ^ Interaktion ^ Empfohlene Dauer ^ | ||
| - | | Kleine Interaktionen (Toggle, Button-Feedback) | 100 ms | | ||
| - | | Mittlere Interaktionen (Panels, Chips, Dropdowns) | 200–300 ms | | ||
| - | | Grosse Übergänge (Dialog öffnen, Seiten-Transition) | 300 ms | | ||
| - | | Schliessen / Ausblenden (kürzer als Öffnen!) | 200–250 ms | | ||
| - | </ | ||
| - | |||
| - | **Wahrnehmung nach Dauer:** | ||
| - | |||
| - | <WRAP center round box 80%> | ||
| - | ^ Dauer ^ Wahrnehmung ^ | ||
| - | | 0 ms | Sofort (wird nicht als Animation wahrgenommen) | | ||
| - | | 100 ms | Unmittelbar | | ||
| - | | 200 ms | Schnell | | ||
| - | | 300 ms | Normal | | ||
| - | | 400 ms | Langsam | | ||
| - | </ | ||
| - | |||
| - | ==== Easing-Empfehlungen ==== | ||
| - | |||
| - | <WRAP center round box 80%> | ||
| - | ^ Easing ^ Wann einsetzen ^ | ||
| - | | '' | ||
| - | | '' | ||
| - | | '' | ||
| - | | '' | ||
| - | </ | ||
| - | |||
| - | < | ||
| - | **Material Design Motion Guidelines: | ||
| - | </ | ||
| - | |||
| - | ==== Reduzierte Bewegung (Barrierefreiheit) ==== | ||
| - | |||
| - | Manche Nutzer reagieren empfindlich auf Bewegung (Vestibularis-Störungen, | ||
| - | |||
| - | <WRAP center round box 80%> | ||
| - | <code css> | ||
| - | @keyframes einblenden { | ||
| - | from { opacity: 0; transform: translateY(12px); | ||
| - | to { opacity: 1; transform: translateY(0); | ||
| - | } | ||
| - | |||
| - | .kachel { | ||
| - | animation: einblenden 0.6s ease both; | ||
| - | } | ||
| - | |||
| - | /* Animationen für Nutzer mit reduzierter Bewegung deaktivieren */ | ||
| - | @media (prefers-reduced-motion: | ||
| - | .kachel { | ||
| - | animation: none; | ||
| - | } | ||
| - | } | ||
| - | </ | ||
| - | </ | ||
| - | |||
| - | ---- | ||
| - | |||
| - | ===== Weiterführende Informationen ===== | ||
| - | ==== id=" | ||
| - | |||
| - | ==== Referenzen ==== | ||
| - | |||
| - | * [[https:// | ||
| - | * [[https:// | ||
| - | * [[https:// | ||
| - | * [[https:// | ||
| - | * [[https:// | ||
| - | * [[https:// | ||
| - | * [[https:// | ||
| - | * [[https:// | ||
| - | |||
| - | ==== Video: Web Animations Today and Tomorrow ==== | ||
| - | |||
| - | [[https:// | ||
| - | |||
| - | **Web animations today and tomorrow** – Chrome for Developers / Google I/O 2025\\ | ||
| - | Sprecher: Bramus Van Damme | Dauer: bis 14:12 min (danach fortgeschrittene Themen) | ||
| - | |||
| - | Themen im Video: | ||
| - | * '' | ||
| - | * '' | ||
| - | * Scroll-gesteuerte Animationen mit '' | ||
| - | * View Transitions API | ||
| - | * UX-Richtlinien für Animationsdauern (Norman Group, Material Design) | ||
| - | |||
| - | ---- | ||
| - | |||
| - | //(Seite erstellt für LU13 – M291 Web Frontend · BZZ)// | ||