Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Beide Seiten der vorigen Revision Vorhergehende Überarbeitung
de:modul:m291:learningunits:lu06:theorie:a_transistions [2026/03/15 22:58] – gelöscht - Externe Bearbeitung (Unbekanntes Datum) 127.0.0.1de:modul:m291:learningunits:lu06:theorie:a_transistions [2026/03/15 22:58] (aktuell) – ↷ Seite von de:modul:m291:learningunits:lu05:theorie:b_transistions nach de:modul:m291:learningunits:lu06:theorie:a_transistions verschoben und umbenannt gkoch
Zeile 1: Zeile 1:
 +====== LU06a – CSS Transitions ======
  
 +{{:de:modul:m291:learningunits:lu05:theorie:faq-toggle-transistion.gif?nolink|}}
 +
 +===== CSS Transitions – Grundprinzip =====
 +
 +Eine CSS Transition animiert den Übergang zwischen zwei Zuständen eines Elements. Sie definieren, **welche Eigenschaft** animiert wird, **wie lange** die Animation dauert und nach welcher **Timing-Kurve**.
 +<WRAP center round box 80%>
 +{{:de:modul:m291:learningunits:lu05:theorie:transition_hover_rect.gif?nolink|}}
 +\\
 +//Hover-Transition der Hintergrundfarbe//
 +
 +<code css>
 +.element {
 +  background-color: blue;
 +  transition: background-color 400ms ease-in-out;
 +}
 +
 +.element:hover {
 +  background-color: red;
 +}
 +</code>
 +</WRAP>
 +
 +Beim Hovern wechselt die Hintergrundfarbe nun nicht abrupt, sondern gleitend über 400 ms von Blau zu Rot.
 +
 +Mehrere Eigenschaften gleichzeitig animieren:
 +<WRAP center round box 80%>
 +<code css>
 +.panel {
 +  opacity: 0;
 +  height: 0;
 +  transition:
 +    opacity  600ms ease-in-out,
 +    height   600ms ease-in-out;
 +}
 +</code>
 +</WRAP>
 +
 +
 +===== Trigger: Was löst eine Transition aus? =====
 +
 +Damit eine Transition aktiviert wird, braucht es zwei Dinge: eine **Eigenschaft, die sich ändert**, und ein **Ereignis, das diese Änderung auslöst**. Die häufigsten Trigger in CSS:
 +<WRAP center round box 80%>
 +^ Trigger ^ Beschreibung ^
 +| '':hover'' | Cursor befindet sich über dem Element |
 +| '':focus'' | Element ist fokussiert (z.B. per Tab-Taste) |
 +| '':focus-within'' | Element oder eines seiner Kind-Elemente ist fokussiert |
 +| '':active'' | Element wird gerade aktiviert (Maustaste gedrückt) |
 +| '':target'' | URL-Fragment stimmt mit der ''id'' des Elements überein |
 +| **Klasse via JavaScript** | Eine CSS-Klasse wird per ''classList.add/remove/toggle'' geändert |
 +\\
 +{{:de:modul:m291:learningunits:lu05:theorie:focus_transition_input.gif?nolink| Focus-within Transition}}
 +\\
 +//Durch Klicken ins Formular-Feld erhält das Element den Fokus -> Ein Trigger für eine Transition der Transparenz.//
 +</WRAP>
 +
 +Der letzte Punkt ist für unser Accordion entscheidend: Wir setzen per JavaScript die Klasse ''open'' – und CSS übernimmt die Animation vollständig. JavaScript steuert den **Zustand**, CSS steuert die **Animation**.
 +
 +===== Was kann (und was kann nicht) animiert werden? =====
 +
 +Nicht jede CSS-Eigenschaft lässt sich animieren. Die Grundregel: Eine Eigenschaft ist animierbar, wenn zwischen Start- und Endwert ein **Zwischenwert berechnet werden kann**.
 +
 +<WRAP round box 80%>
 +**Beispiel:** ''font-size: 12px'' → ''font-size: 24px'' ✅ – jeder Pixelwert dazwischen ist berechenbar.
 +
 +**Gegenbeispiel:** ''font-family: serif'' → ''font-family: monospace'' ❌ – was wäre eine Schriftart-Mitte?
 +</WRAP>
 +
 +==== Gut animierbare Eigenschaften ====
 +
 +=== transform ===
 +
 +''transform'' ist die am häufigsten eingesetzte Eigenschaft für Transitions. Sie wird direkt von der **GPU** berechnet – das ergibt flüssigere Animationen und belastet den Browser weniger als Layout-Eigenschaften.
 +
 +<WRAP center round box 80%>
 +{{:de:modul:m291:learningunits:lu05:theorie:rotate_scale_rect.gif?nolink|}}
 +
 +<code css>
 +.box {
 +  transition: transform 400ms ease-out;
 +}
 +
 +.box:hover {
 +  transform: scale(1.2) rotate(5deg) translateY(-8px);
 +}
 +</code>
 +</WRAP>
 +
 +Einzelne Transform-Eigenschaften können auch separat animiert werden:
 +
 +<WRAP center round box 80%>
 +<code css>
 +.box {
 +  transition:
 +    scale     300ms ease-out,
 +    rotate    300ms ease-in-out,
 +    translate 300ms ease-out;
 +}
 +
 +.box:hover {
 +  scale: 1.2;
 +  rotate: 5deg;
 +  translate: 0 -8px;
 +}
 +</code>
 +</WRAP>
 +
 +=== Farbe ===
 +
 +''color'', ''background-color'' und ''border-color'' sind häufige Transition-Kandidaten – sie geben bei Interaktion visuelles Feedback, z.B. wenn ein Button beim Hovern die Farbe wechselt.
 +
 +<WRAP center round box 80%>
 +<code css>
 +.btn {
 +  background-color: steelblue;
 +  transition: background-color 250ms ease-in-out;
 +}
 +
 +.btn:hover {
 +  background-color: royalblue;
 +}
 +</code>
 +</WRAP>
 +
 +=== opacity ===
 +
 +Sanftes Ein- und Ausblenden – das Element **bleibt aber im Layout** (es nimmt weiterhin Platz ein).
 +
 +=== Weitere animierbare Eigenschaften ===
 +<WRAP center round box 80%>
 +^ Eigenschaft ^ Einsatz ^
 +| ''width'', ''height'' | Zwischen zwei fixen Werten (z.B. ''0'' → ''200px'') |
 +| ''margin'', ''padding'' | Layout-Animationen |
 +| ''border-radius'' | Formen weich überblenden |
 +| ''box-shadow'' | Elevation-Effekte (z.B. bei Fokus) |
 +| ''filter'' | ''blur()'', ''brightness()'', ''saturate()'' etc. |
 +| ''font-size'', ''letter-spacing'' | Typografische Animationen |
 +</WRAP>
 +
 +==== Nicht animierbar ====
 +
 +<WRAP center round box 80%>
 +^ Eigenschaft ^ Warum nicht? ^
 +| ''display'' | Kein Mittelwert zwischen ''none'' und ''block'' möglich |
 +| ''font-family'' | Kein Mittelwert zwischen Schriftarten möglich |
 +| ''position'' | Kategoriewechsel, kein kontinuierlicher Übergang |
 +| ''visibility'' | Binärer Wert (sichtbar/unsichtbar) |
 +</WRAP>
 +
 +
 +<WRAP round tip 80%>
 +Eine vollständige Liste animierbarer Eigenschaften: [[https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_animated_properties|MDN – Animatable CSS properties]]
 +</WRAP>
 +
 +===== Antworten Ein- und Ausblenden mit 'display' =====
 +
 +Im ersten Schritt haben wir die Panels mit ''display: none'' / ''display: block'' ein- und ausgeblendet. Das funktioniert – aber es gibt **keinen Übergang**, das Element erscheint und verschwindet abrupt.
 +
 +**Warum lässt sich ''display'' nicht animieren?** CSS Transitions interpolieren zwischen zwei Zahlenwerten. ''display: none'' bedeutet: das Element **existiert im Layout nicht**. Zwischen "existiert nicht" und "existiert" kann kein Mittelwert berechnet werden – eine Transition ist daher logisch nicht möglich.
 +<WRAP center round box 80%>
 +<code css>
 +/* ❌ Kein Übergang möglich */
 +.panel {
 +  display: none;
 +  transition: display 400ms; /* wirkungslos */
 +}
 +.panel.open {
 +  display: block; /* schaltet sofort um */
 +}
 +</code>
 +</WRAP>
 +
 +
 +===== Das Problem: height von 0 zu auto =====
 +
 +Der einfachste und natürlichste Ansatz wäre: ''height: 0'' → ''height: auto'' (-> auto: der Browser berechnet selbst die Höhe des Elements anhand der Inhalte). Leider funktioniert das **nicht** mit einer Transition:
 +<WRAP center round box 80%>
 +<code css>
 +/* ❌ Funktioniert NICHT – Browser kann nicht interpolieren */
 +.panel {
 +  height: 0;
 +  overflow: hidden;
 +  transition: height 600ms ease-in-out;
 +}
 +.panel.open {
 +  height: auto; /* Browser weiss nicht, was das in px bedeutet */
 +}
 +</code>
 +</WRAP>
 +
 +Der Browser kann zwischen einem fixen Pixelwert (''0'') und dem Schlüsselwort ''auto'' nicht interpolieren – ''auto'' ist kein Zahlenwert, sondern eine Anweisung: "berechne die Höhe selbst".
 +
 +
 +===== Die moderne Lösung: interpolate-size: allow-keywords =====
 +
 +Seit 2024 unterstützen moderne Browser eine neue CSS-Eigenschaft, die genau dieses Problem löst: ''interpolate-size: allow-keywords''.
 +
 +Sie erlaubt dem Browser, Übergänge zwischen einem Pixel-Wert und einem CSS-Schlüsselwort wie ''auto'', ''min-content'' oder ''max-content'' zu berechnen.
 +<WRAP center round box 80%>
 +<code css>
 +:root {
 +  interpolate-size: allow-keywords; /* einmal global definieren */
 +}
 +</code>
 +</WRAP>
 +
 +Damit funktioniert ''height: 0'' → ''height: auto'' mit einer Transition wie erwartet.
 +
 +==== CSS-Transitions: Ein- und Ausblenden der Antworten ====
 +<WRAP center round box 80%>
 +<code css>
 +:root {
 +  interpolate-size: allow-keywords;
 +}
 +
 +/* Standardmässig versteckt */
 +.panel {
 +  height: 0;
 +  opacity: 0;
 +  overflow: hidden;
 +  transition:
 +    height  800ms ease-in-out,
 +    opacity 800ms ease-in-out;
 +}
 +
 +/* Sichtbar wenn Klasse 'open' gesetzt */
 +.panel.open {
 +  height: auto;
 +  opacity: 1;
 +}
 +</code>
 +</WRAP>
 +
 +Das Öffnen und Schliessen wird weiterhin per JavaScript durch ''classList.add('open')'' / ''classList.remove('open')'' gesteuert – die Animation läuft vollständig in CSS.
 +
 +<WRAP important round center 80%>
 +**Browser-Support:** ''interpolate-size: allow-keywords'' wird aktuell **nur von Chrome/Edge** unterstützt – Safari und Firefox kennen sie noch nicht. In diesen Browsern springt das Panel beim Öffnen abrupt auf ''height: auto'', ohne Animation.
 +
 +Aktuellen Support prüfen: [[https://caniuse.com/mdn-css_properties_interpolate-size|caniuse.com – interpolate-size]]
 +</WRAP>
 +
 +
 +===== Timing-Funktionen =====
 +
 +Der dritte Parameter von ''transition'' steuert die Beschleunigungskurve der Animation:
 +
 +<WRAP center round box 80%>
 +^ Wert ^ Beschreibung ^
 +| ''ease'' | Langsam starten, beschleunigen, langsam enden (Standard) |
 +| ''ease-in'' | Langsam starten, schnell enden |
 +| ''ease-out'' | Schnell starten, langsam enden – oft natürlicher |
 +| ''ease-in-out'' | Langsam starten und enden, in der Mitte schnell |
 +| ''linear'' | Konstante Geschwindigkeit |
 +| ''cubic-bezier(x,x,x,x)'' | Vollständig selbst definierte Kurve |
 +</WRAP>
 +
 +Im Accordion-Projekt verwenden wir ''ease-in-out'' – das Panel öffnet und schliesst sich jeweils mit einer leichten Verzögerung am Anfang und Ende, was natürlicher wirkt.
 +
 +<WRAP center round box 80%>
 +Interaktives Beispiel mit Beispiel-Code: [[https://css-transitions.vercel.app|Externe Seite erkunden.]]
 +[[https://css-transitions.vercel.app|{{ :de:modul:m291:learningunits:lu05:theorie:screenshot_2026-03-09_at_00.26.55.png?600 |}}]]
 +</WRAP>