Barrierearme Animationen
Empfehlung
Erst ohne Bewegung bauen, Bewegung kommt obendrauf. Alles, was sich bewegt, steht in einer Media Query, die nur greift, wenn jemand keine reduzierte Bewegung eingestellt hat:
/* statische Grundstile */
.hero-image { opacity: 1; }
@media (prefers-reduced-motion: no-preference) {
.hero-image {
animation: slide-in 600ms ease-out both;
}
}↗ Beispiel in neuem Tab öffnen
Dazu drei Regeln:
- Bewegung, die von selbst startet und länger als fünf Sekunden läuft, muss man anhalten können, egal was im System eingestellt ist.1
- Große, raumgreifende Bewegung vermeiden (Parallax, Zoom, Tiefenunschärfe). Kleine, langsame Bewegung ist deutlich harmloser.2
- Nur
transformundopacityanimieren, wo es geht.3
Begründung
- Gesundheit: Bewegung, die über das eigentliche Scrollen hinausgeht, kann bei Menschen mit Störungen des Gleichgewichtssinns (vestibuläre Störungen) Schwindel, Übelkeit und Migräne auslösen, im Extremfall bis zur Bettlägerigkeit.4 Parallax-Scrolling ist das klassische Beispiel.
- Die Einstellung gibt es schon: Betriebssysteme bieten „Bewegung reduzieren“ seit Langem an, und mit
prefers-reduced-motionlässt sie sich in CSS und JavaScript abfragen.5 - WCAG:
- SC 2.3.3 „Animation from Interactions“ (AAA): Durch Interaktion ausgelöste Bewegung muss abschaltbar sein, außer sie ist essenziell.
prefers-reduced-motionist eine anerkannte Technik dafür (C39).46 - SC 2.2.2 „Pause, Stop, Hide“ (A): Bewegung, die von selbst startet, länger als fünf Sekunden läuft und neben anderem Inhalt steht, muss sich anhalten lassen.1
- SC 2.3.3 „Animation from Interactions“ (AAA): Durch Interaktion ausgelöste Bewegung muss abschaltbar sein, außer sie ist essenziell.
- Warum erst ohne Bewegung: C39 nennt beide Wege als gleichwertig: Bewegung bei
reduceabschalten oder nur beino-preferenceeinschalten.6 Der zweite Weg ist robuster, denn wer eine Regel vergisst, erzeugt weniger statt mehr Bewegung. Das ist eigene Einordnung. - Performance ist auch Barrierefreiheit: MDN nennt ruckelnde Elemente mit
stickyoderfixedausdrücklich als Problem für empfindliche Menschen.7
Wann anwenden?
Immer, wenn sich etwas bewegt, das die Person nicht selbst zieht oder scrollt:
- Einblend- und Ausblend-Animationen (Ein- und Ausblenden mit CSS animieren)
- Scroll-getriebene Effekte (Scroll-getriebene Animationen)
- Seiten- und Zustandsübergänge (View Transitions)
- Hover-Effekte mit Verschiebung oder Skalierung
- Karussells, Laufschriften, Endlos-Animationen, hier gilt zusätzlich SC 2.2.2
Ausnahmen / Gegenbeispiele
- Essenzielle Bewegung ist ausgenommen, z. B. die Vorschau in einem Werkzeug zum Erstellen von Animationen.4
- Das Scrollen selbst, bei dem neuer Inhalt ins Bild kommt, ist essenziell, und man hat es selbst in der Hand.4
- „Reduziert“ heißt nicht „keine“. Ein kurzes Überblenden der Deckkraft kann auch bei
reducesinnvoll sein, weil es Zustandswechsel verständlich macht. Bushell weist darauf hin, dass unklar ist, wie viel Reduktion genügt, und dass „keine Bewegung“ die sichere Wahl sei.8 Dass ein Überblenden der Deckkraft unproblematisch ist, ist eigene Einschätzung. Sie stützt sich darauf, dass WebKit zwischen kleiner und raumgreifender Bewegung unterscheidet.2 - Kleine Fortschrittsanzeigen hält WebKit für unbedenklich genug, um sie nicht in die Media Query zu legen.2
Checkliste
- Jede Bewegung steht in
@media (prefers-reduced-motion: no-preference)oder hat einereduce-Variante. - Die Seite funktioniert und ist vollständig lesbar, wenn keine einzige Animation läuft (Startzustände wie
opacity: 0nur innerhalb der Media Query). - Bewegung, die von selbst länger als fünf Sekunden läuft, lässt sich anhalten, stoppen oder ausblenden.
- Kein Parallax, keine großen Zoom- oder Tiefeneffekte ohne Abschaltmöglichkeit.
- Animiert werden
transform/opacity; Layout-Eigenschaften nur bewusst. -
will-changenur gezielt, nicht pauschal. - Skript-Animationen reagieren auf
matchMedia('(prefers-reduced-motion: reduce)')und dessen Änderungen.5 - Mit aktivierter Systemeinstellung „Bewegung reduzieren“ getestet (Prüfschritt aus C39).6
JavaScript-Variante für Skript-Animationen:
const reduceMotion = window.matchMedia("(prefers-reduced-motion: reduce)");
function applyMotionPreference() {
document.documentElement.classList.toggle("reduce-motion", reduceMotion.matches);
}
applyMotionPreference();
reduceMotion.addEventListener("change", applyMotionPreference);Das Muster mit dem Listener stammt sinngemäß von web.dev, die Klasse am Wurzelelement habe ich ergänzt. Geprüft ist nur die Syntax: Die Einstellung „Bewegung reduzieren“ ließ sich im Chrome-Test nicht umschalten, deshalb sind die reduce-Zweige aller Notizen ungetestet.
Quellen / Erfahrungen
- Understanding SC 2.3.3 Animation from Interactions (W3C WCAG) — Kriterium, vestibuläre Störungen, Ausnahmen
- Understanding SC 2.2.2 Pause, Stop, Hide (W3C WCAG) — Fünf-Sekunden-Regel
- Technique C39 prefers-reduced-motion (W3C WCAG) — beide Richtungen der Media Query, Testschritte
- prefers-reduced-motion – Sometimes less movement is more (web.dev) — Hintergrund, JavaScript
- A guide to Scroll-driven Animations with just CSS (WebKit) — kleine vs. raumgreifende Bewegung
- David Bushell, „Declarative Dialog Menu with Invoker Commands“ (siehe Fußnote) — „reduziert ist nicht keine“
- How to create high-performance CSS animations (web.dev) — günstige Eigenschaften,
will-change - position CSS-Eigenschaft (MDN) — Ruckeln als Barrierefreiheitsproblem
Eigene Erfahrungen liegen nicht vor. Dass „erst ohne Bewegung“ der bessere Weg ist und dass Übergänge der Deckkraft unproblematisch sind, ist eigene Einschätzung.
Footnotes
-
Understanding SC 2.2.2 Pause, Stop, Hide (W3C WCAG), Wortlaut des Kriteriums. ↩ ↩2
-
A guide to Scroll-driven Animations with just CSS (WebKit), Abschnitte zum Fortschrittsbalken und zu
view(). ↩ ↩2 ↩3 -
Understanding SC 2.3.3 Animation from Interactions (W3C WCAG), Abschnitte „Success Criterion“, „Intent“ und „Examples“. ↩ ↩2 ↩3 ↩4
-
prefers-reduced-motion – Sometimes less movement is more (web.dev). ↩ ↩2
-
position CSS-Eigenschaft (MDN), Abschnitt „Accessibility“. ↩
-
David Bushell, „Declarative Dialog Menu with Invoker Commands“, dbushell.com, 12.02.2026, https://dbushell.com/2026/02/12/declarative-dialog-menu-invoker-commands/, Abschnitt „Fancy styles“. ↩