scroll-behavior: smooth und prefers-reduced-motion richtig kombinieren
AI generated
{ }
@
CSS · Barrierefreiheit · Bewegung
scroll-behavior: smooth und prefers-reduced-motion
Eine Scroll-Animation darf niemals den expliziten Wunsch nach weniger Bewegung übersteuern

scroll-behavior: smooth verwandelt Sprünge zu Anker-Zielen in eine animierte Bewegung, aber genau diese Animation kann bei Menschen mit vestibulären Störungen echte körperliche Beschwerden auslösen. Das robuste Pattern aktiviert smooth scrolling ausschließlich innerhalb von @media (prefers-reduced-motion: no-preference), sodass die explizite Entscheidung des Betriebssystems immer gewinnt.

15 Min. Lesezeit scroll-behavior · prefers-reduced-motion matchMedia · scrollIntoView · scrollTo

1. Was scroll-behavior: smooth genau bewirkt und wo es greift

Die CSS-Eigenschaft scroll-behavior: smooth sorgt dafür, dass ein Sprung zu einem Anker-Ziel, etwa über <a href="#abschnitt">, nicht abrupt, sondern als animierter Scrollvorgang über mehrere hundert Millisekunden abläuft. Gesetzt wird die Eigenschaft meist auf html, wodurch sie global für alle nativen Scroll-Auslöser innerhalb des Dokuments gilt, einschließlich Anker-Navigation, Tastatur-Scrolling mit Bild-auf/ab und programmatischem Scrollen über bestimmte JavaScript-APIs.

Der Effekt wirkt auf den ersten Blick rein kosmetisch, hat aber echte Auswirkungen auf die Orientierung: Ein animierter Scrollvorgang zeigt dem Nutzer visuell, wo auf der Seite er sich gerade befindet und wie weit das Ziel entfernt liegt, während ein abrupter Sprung diesen räumlichen Kontext komplett auslässt. Für die meisten Nutzer ist das ein angenehmes, orientierungsförderndes Detail, für eine bestimmte Nutzergruppe aber genau das Gegenteil.

2. Warum smooth scrolling für bewegungsempfindliche Nutzer ein echtes Problem ist

Menschen mit vestibulären Störungen oder allgemeiner Bewegungsempfindlichkeit können durch großflächige, schnelle Scroll-Animationen echte körperliche Symptome bekommen, von Schwindel bis Übelkeit, vor allem wenn die Animation groß, schnell und unerwartet ausgelöst wird. Ein einzelner Klick auf einen Inhaltsverzeichnis-Link, der die gesamte Seite in einer schnellen Bewegung durchscrollt, kann für diese Nutzergruppe ein reales Zugänglichkeitsproblem sein, nicht nur eine ästhetische Vorliebe.

Genau dafür existiert die Betriebssystem-Einstellung Bewegung reduzieren, die Nutzer bewusst aktivieren, um genau solche Animationen systemweit zu unterdrücken, und die Browser über die CSS Media Query prefers-reduced-motion: reduce zugänglich machen. Wer scroll-behavior: smooth ohne Rücksicht auf diese Einstellung global aktiviert, ignoriert eine explizit vom Nutzer getroffene Entscheidung und liefert genau die Erfahrung aus, vor der die Einstellung eigentlich schützen soll.

3. prefers-reduced-motion erkennen und als Schalter nutzen

Die Media Query prefers-reduced-motion kennt zwei Werte: no-preference, wenn der Nutzer keine besondere Einstellung getroffen hat, und reduce, wenn Bewegungsreduzierung im Betriebssystem aktiv ist. Wichtig ist die Reihenfolge der Logik: Statt smooth als Standard zu setzen und bei reduce wieder zu entfernen, ist die robustere Variante, standardmäßig beim Browser-Default auto zu bleiben und smooth ausschließlich innerhalb von @media (prefers-reduced-motion: no-preference) zu aktivieren.

Dieser Unterschied ist mehr als Geschmackssache: Browser ohne Unterstützung für die Media Query ignorieren die gesamte Regel und bleiben beim sicheren auto-Verhalten, während bei der umgekehrten Reihenfolge ein nicht unterstützender, aber trotzdem bewegungsempfindlicher Nutzer versehentlich smooth scrolling bekommen könnte, sobald ein anderer Browser-Fallback greift. no-preference als Aktivierungsbedingung zu verwenden ist damit die sicherere Grundhaltung.


/* Default: browser's native, instant scroll behavior */
html {
  scroll-behavior: auto;
}

/* Only opt in to smooth scrolling when the user has not
   requested reduced motion */
@media (prefers-reduced-motion: no-preference) {
  html {
    scroll-behavior: smooth;
  }
}

4. Das robuste @media-Pattern: smooth nur bei no-preference aktivieren

Das robuste Grundmuster kombiniert die Media Query mit einer bewusst gewählten Standardeinstellung: scroll-behavior: auto ist der sichere Ausgangspunkt für html, weil er dem tatsächlichen Nutzerwunsch entspricht, solange keine explizite Präferenz für Animation vorliegt. Erst innerhalb von @media (prefers-reduced-motion: no-preference) wird smooth nachgerüstet, wodurch das Verhalten sich automatisch an jede Änderung der Betriebssystemeinstellung anpasst, ganz ohne JavaScript oder einen Seiten-Reload.

Für Projekte, die zusätzlich einen manuellen In-App-Schalter für Animationen anbieten wollen, lässt sich dasselbe Muster mit einem Datenattribut koppeln, das per JavaScript umgeschaltet wird, sobald der Nutzer die App-Einstellung ändert. Die Media Query bleibt dabei die primäre, automatische Quelle der Wahrheit, während der manuelle Schalter nur als zusätzliche, bewusste Übersteuerung für Nutzer dient, die eine andere Präferenz als ihr Betriebssystem haben.


html {
  scroll-behavior: auto;
}

@media (prefers-reduced-motion: no-preference) {
  /* data-motion="reduced" lets an in-app toggle override
     the OS preference without touching JavaScript logic elsewhere */
  html:not([data-motion="reduced"]) {
    scroll-behavior: smooth;
  }
}

html[data-motion="reduced"] {
  scroll-behavior: auto;
}

5. Anker-Links und History-Navigation: wo scroll-behavior technisch greift

scroll-behavior: smooth wirkt technisch auf jeden Scrollvorgang, der als Ergebnis einer Navigation innerhalb desselben Dokuments ausgelöst wird: Klick auf einen Anker-Link mit Fragment-Identifier, Vor- und Zurück-Navigation im Browserverlauf, sofern das Ziel-Fragment sich ändert, sowie Tastatur-Navigation mit Bild-auf, Bild-ab, Pos1 und Ende, solange der fokussierte Kontext das Dokument selbst ist. Die Eigenschaft betrifft also nicht nur klickbare Links, sondern das gesamte native Scroll-Verhalten des Dokuments.

Nicht erfasst wird dagegen jedes Scrollen, das rein durch Mausrad, Trackpad-Geste oder Touch-Wischen ausgelöst wird, weil dieses Scrollen bereits kontinuierlich und nutzergesteuert erfolgt und keine diskrete Sprung-Animation braucht. Wer also Sorge hat, scroll-behavior: smooth würde normales Scrollen künstlich verlangsamen, kann beruhigt sein: Die Eigenschaft betrifft ausschließlich programmatisch oder per Navigation ausgelöste Sprünge zu einem bestimmten Ziel.


<nav>
  <a href="#einleitung">Einleitung</a>
  <a href="#hauptteil">Hauptteil</a>
  <a href="#fazit">Fazit</a>
</nav>

<section id="einleitung">...</section>
<section id="hauptteil">...</section>
<section id="fazit">...</section>

<style>
/* These anchor jumps automatically become smooth once
   scroll-behavior: smooth is active on <html> */
html {
  scroll-behavior: auto;
}

@media (prefers-reduced-motion: no-preference) {
  html {
    scroll-behavior: smooth;
  }
}
</style>

6. scrollIntoView() und scrollTo() aus JavaScript korrekt an das Pattern anschließen

Programmatisches Scrollen aus JavaScript über element.scrollIntoView() oder window.scrollTo() respektiert scroll-behavior: smooth auf html nur dann automatisch, wenn kein eigenes behavior-Argument übergeben wird oder wenn behavior: 'auto' explizit gesetzt ist. Wird dagegen im JavaScript-Aufruf hartkodiert behavior: 'smooth' übergeben, überschreibt dieser Aufruf jede CSS-Einstellung und ignoriert damit auch prefers-reduced-motion vollständig, was den ganzen CSS-basierten Schutzmechanismus aushebelt.

Die saubere Lösung ist, das Bewegungsverhalten an genau einer Stelle zu entscheiden, entweder ausschließlich über CSS und JavaScript-Aufrufe ohne explizites behavior, oder, falls JavaScript die Entscheidung treffen muss, die Media Query dort ebenfalls per window.matchMedia('(prefers-reduced-motion: reduce)') abzufragen und das Ergebnis konsistent in den behavior-Wert zu übersetzen, statt zwei parallele, widersprüchliche Quellen der Wahrheit zu pflegen.


const prefersReducedMotion = window.matchMedia(
  "(prefers-reduced-motion: reduce)"
).matches;

document
  .querySelector("#zurueck-nach-oben")
  .addEventListener("click", () => {
    window.scrollTo({
      top: 0,
      behavior: prefersReducedMotion ? "auto" : "smooth",
    });
  });

7. Ausnahmen: wann eine kurze Animation trotzdem sinnvoll ist

Nicht jede Animation muss komplett verschwinden, sobald prefers-reduced-motion: reduce aktiv ist. Die Spezifikation und gängige Praxis unterscheiden zwischen großflächigen, räumlich weitreichenden Bewegungen, etwa das Durchscrollen einer kompletten langen Seite, und kleinen, kurzen Übergängen, etwa das sanfte Ein- und Ausblenden eines Tooltips über wenige Pixel und Millisekunden, die selbst für bewegungsempfindliche Nutzer meist unproblematisch bleiben.

Bei Scroll-Interaktionen empfiehlt sich deshalb eine differenzierte Betrachtung: Ein Sprung zu einem weit entfernten Abschnitt der Seite sollte bei reduzierter Bewegung tatsächlich sofort erfolgen, während ein sehr kurzer, wenige Pixel umfassender Korrektur-Scroll, etwa um ein Formularfeld knapp ins sichtbare Fenster zu rücken, in vielen Fällen auch mit aktivem reduce noch vertretbar ist. Im Zweifel gilt aber: lieber zu vorsichtig als zu sorglos mit der Nutzerpräferenz umgehen.

8. Testen: Betriebssystem-Einstellung, DevTools-Emulation und manuelle Prüfung

Die Einstellung Bewegung reduzieren findet sich unter Windows in den Bedienungshilfen, unter macOS in den Bedienungshilfen-Einstellungen unter Anzeige, und unter den meisten mobilen Betriebssystemen ebenfalls in den Bedienungshilfen-Menüs. Nach dem Aktivieren wertet jeder moderne Browser die CSS Media Query korrekt aus, ohne dass die Seite neu geladen werden muss, weil sich der berechnete Wert der Media Query live mit der Systemeinstellung ändert.

Für die Entwicklung bieten Chromium- und Firefox-DevTools eine Emulation von prefers-reduced-motion direkt im Rendering-Panel, mit der sich das Verhalten testen lässt, ohne die eigene Systemeinstellung dauerhaft zu ändern. Ergänzend lohnt sich ein kurzer manueller Test mit tatsächlich aktivierter Systemeinstellung, weil einzelne Browser-Engines bei der Emulation nicht jeden Edge Case exakt wie die echte Betriebssystem-Einstellung behandeln.


/* Quick visual debug helper: highlights every element whose
   animation/transition is currently suppressed by the OS setting */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}

9. Best Practices für ein barrierefreies Scroll-Verhalten

Ein barrierefreies Scroll-Verhalten braucht am Ende keine komplizierte Logik, sondern konsequente Reihenfolge: Standardmäßig auto, smooth ausschließlich innerhalb von @media (prefers-reduced-motion: no-preference), und jede JavaScript-Stelle, die selbst behavior setzt, an dieselbe Präferenzabfrage anschließen. So bleibt eine einzige, konsistente Quelle der Wahrheit für das gesamte Scroll-Verhalten der Seite erhalten.

Wer dieses Muster einmal global in html beziehungsweise in einer zentralen JavaScript-Utility etabliert, muss es für jede neue Komponente nicht erneut durchdenken, solange neue Scroll-Aufrufe konsequent ohne hartkodiertes behavior: 'smooth' auskommen. Das macht barrierefreies Scrollen zu einer einmaligen Architekturentscheidung statt zu einer wiederkehrenden Fehlerquelle bei jedem neuen Feature.

Auslöser Von scroll-behavior erfasst prefers-reduced-motion beachten Empfehlung
Anker-Link-Klick (#ziel) Ja Ja, automatisch über CSS html { scroll-behavior: smooth } in Media Query
Browser-Vor/Zurück mit Fragment Ja Ja, automatisch über CSS Kein Zusatzcode nötig
Mausrad, Trackpad, Touch-Wischen Nein Nicht relevant Immer nutzergesteuert, keine Animation
scrollIntoView() ohne behavior Ja, erbt CSS-Wert Ja, automatisch über CSS Kein explizites behavior übergeben
scrollTo({behavior:'smooth'}) hartkodiert Nein, überschreibt CSS Nein, muss manuell geprüft werden matchMedia im JS selbst abfragen

Mironsoft

Modernes CSS, Layout-Architektur und Rendering-Performance

CSS, das wartbar bleibt statt mit jeder Änderung zu brechen?

Wir prüfen bestehende Stylesheets auf Spezifitäts-Chaos und Layout-Thrashing und bauen daraus eine CSS-Architektur mit Cascade Layers, Custom Properties und modernen Layout-Primitiven, die auch nach dem zehnten Feature noch verständlich ist.

CSS-Audit

Spezifität, Cascade-Konflikte und ungenutzte Selektoren systematisch aufdecken.

Architektur-Refactoring

Cascade Layers, Custom Properties und Design Tokens sauber einführen.

Performance-Tuning

Layout-Thrashing, teure Selektoren und Rendering-Engpässe gezielt beheben.

10. Zusammenfassung

scroll-behavior: smooth und prefers-reduced-motion: Das Wichtigste auf einen Blick

Grundprinzip

scroll-behavior: smooth animiert Sprünge zu Ankern und programmatische Scrollziele, betrifft aber nicht Mausrad- oder Touch-Scrolling.

Sicheres Pattern

Standardmäßig auto, smooth nur innerhalb @media (prefers-reduced-motion: no-preference) aktivieren, niemals umgekehrt.

JavaScript-Falle

Hartkodiertes behavior: 'smooth' in scrollIntoView oder scrollTo überschreibt CSS und muss die Präferenz selbst über matchMedia abfragen.

Testen

DevTools-Emulation für schnelle Iteration, abschließend echte Systemeinstellung unter Windows, macOS und Mobilgeräten prüfen.

11. FAQ: scroll-behavior: smooth und prefers-reduced-motion: Das Wichtigste auf einen Blick

1Was macht scroll-behavior: smooth genau?
Die Eigenschaft verwandelt Sprünge zu einem Scroll-Ziel, etwa über Anker-Links, in eine animierte Bewegung über mehrere hundert Millisekunden, statt das Ziel abrupt anzuzeigen.
2Warum ist smooth scrolling für manche Nutzer problematisch?
Menschen mit vestibulären Störungen können durch schnelle, großflächige Scroll-Animationen Schwindel oder Übelkeit bekommen. Die Betriebssystem-Einstellung Bewegung reduzieren existiert genau dafür.
3Wie kombiniere ich scroll-behavior: smooth mit prefers-reduced-motion?
Setze html standardmäßig auf scroll-behavior: auto und aktiviere smooth ausschließlich innerhalb von @media (prefers-reduced-motion: no-preference), niemals umgekehrt.
4Betrifft scroll-behavior auch normales Mausrad-Scrollen?
Nein. Die Eigenschaft wirkt nur auf diskrete Sprünge zu einem Ziel, etwa Anker-Links oder programmatisches Scrollen, nicht auf kontinuierliches, nutzergesteuertes Scrollen.
5Warum überschreibt mein JavaScript die CSS-Einstellung?
Ein hartkodiertes behavior: 'smooth' in scrollIntoView() oder scrollTo() ignoriert CSS komplett. Frage die Präferenz dort zusätzlich mit window.matchMedia ab.
6Muss ich jede Animation bei reduzierter Bewegung komplett entfernen?
Nicht zwingend. Große, weiträumige Bewegungen sollten entfallen, sehr kurze, kleine Übergänge sind oft weiterhin vertretbar. Im Zweifel eher vorsichtig reduzieren.
7Wie teste ich prefers-reduced-motion ohne Systemeinstellung zu ändern?
Chromium- und Firefox-DevTools bieten im Rendering-Panel eine Emulation der Media Query, ideal für schnelle Iteration während der Entwicklung.
8Wo finde ich die Einstellung Bewegung reduzieren?
Unter Windows in den Bedienungshilfen, unter macOS in den Bedienungshilfen-Einstellungen unter Anzeige, unter mobilen Betriebssystemen ebenfalls im Bedienungshilfen-Menü.
9Kann ich Nutzern einen eigenen In-App-Schalter zusätzlich zur Systemeinstellung anbieten?
Ja, über ein Datenattribut oder eine CSS Custom Property, das die Media-Query-Entscheidung gezielt übersteuert, während die Systemeinstellung die primäre automatische Quelle bleibt.
10Reicht scroll-behavior: smooth allein für Barrierefreiheit aus?
Nein, ohne die Kopplung an prefers-reduced-motion ignoriert es eine bewusst vom Nutzer getroffene Systemeinstellung und kann bei bewegungsempfindlichen Nutzern echte Beschwerden auslösen.