LU06a – CSS Transitions

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.


Hover-Transition der Hintergrundfarbe

.element {
  background-color: blue;
  transition: background-color 400ms ease-in-out;
}
 
.element:hover {
  background-color: red;
}

Beim Hovern wechselt die Hintergrundfarbe nun nicht abrupt, sondern gleitend über 400 ms von Blau zu Rot.

Mehrere Eigenschaften gleichzeitig animieren:

.panel {
  opacity: 0;
  height: 0;
  transition:
    opacity  600ms ease-in-out,
    height   600ms ease-in-out;
}

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:

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


 Focus-within Transition
Durch Klicken ins Formular-Feld erhält das Element den Fokus → Ein Trigger für eine Transition der Transparenz.

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.

Beispiel: font-size: 12pxfont-size: 24px ✅ – jeder Pixelwert dazwischen ist berechenbar.

Gegenbeispiel: font-family: seriffont-family: monospace ❌ – was wäre eine Schriftart-Mitte?

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.

.box {
  transition: transform 400ms ease-out;
}
 
.box:hover {
  transform: scale(1.2) rotate(5deg) translateY(-8px);
}

Einzelne Transform-Eigenschaften können auch separat animiert werden:

.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;
}

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.

.btn {
  background-color: steelblue;
  transition: background-color 250ms ease-in-out;
}
 
.btn:hover {
  background-color: royalblue;
}

opacity

Sanftes Ein- und Ausblenden – das Element bleibt aber im Layout (es nimmt weiterhin Platz ein).

Weitere animierbare Eigenschaften

Eigenschaft Einsatz
width, height Zwischen zwei fixen Werten (z.B. 0200px)
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

Nicht animierbar

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)

Eine vollständige Liste animierbarer Eigenschaften: MDN – Animatable CSS properties

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.

/* ❌ Kein Übergang möglich */
.panel {
  display: none;
  transition: display 400ms; /* wirkungslos */
}
.panel.open {
  display: block; /* schaltet sofort um */
}

Das Problem: height von 0 zu auto

Der einfachste und natürlichste Ansatz wäre: height: 0height: auto (→ auto: der Browser berechnet selbst die Höhe des Elements anhand der Inhalte). Leider funktioniert das nicht mit einer Transition:

/* ❌ 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 */
}

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.

:root {
  interpolate-size: allow-keywords; /* einmal global definieren */
}

Damit funktioniert height: 0height: auto mit einer Transition wie erwartet.

CSS-Transitions: Ein- und Ausblenden der Antworten

: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;
}

Das Öffnen und Schliessen wird weiterhin per JavaScript durch classList.add('open') / classList.remove('open') gesteuert – die Animation läuft vollständig in CSS.

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: caniuse.com – interpolate-size

Timing-Funktionen

Der dritte Parameter von transition steuert die Beschleunigungskurve der Animation:

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

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.

Interaktives Beispiel mit Beispiel-Code: Externe Seite erkunden.