Respektieren der Bewegungspräferenzen der Benutzer
Veröffentlicht: 2022-03-10prefers-reduced-motion
wird seit einigen Jahren in allen modernen Browsern hervorragend unterstützt. In diesem Artikel erklärt Michelle Barker, warum es keinen Grund gibt, es heute nicht zu verwenden, um Ihre Websites zugänglicher zu machen.Bei der Arbeit mit Bewegung im Web ist es wichtig zu bedenken, dass nicht jeder sie auf die gleiche Weise erlebt. Was sich für einige glatt und glatt anfühlt, kann für andere lästig oder ablenkend sein – oder schlimmer noch, Übelkeit hervorrufen oder sogar Anfälle verursachen. Websites mit viel Bewegung können sich auch stärker auf die Akkulaufzeit von Mobilgeräten auswirken oder dazu führen, dass mehr Daten verwendet werden (zum Beispiel erfordert die automatische Wiedergabe von Videos mehr Daten eines Benutzers als ein statisches Bild). Dies sind nur einige der Gründe, warum bewegungsintensive Websites möglicherweise nicht für alle wünschenswert sind.
Die meisten neuen Betriebssysteme ermöglichen es dem Benutzer, seine Bewegungspräferenzen in seinen Einstellungen auf Systemebene festzulegen. Die Präferenzen prefers-reduced-motion
Medienabfrage (Teil der Level 5 Media Queries-Spezifikation) ermöglicht es uns, die Bewegungspräferenzen der Benutzer auf Systemebene zu erkennen und CSS-Stile anzuwenden, die dies berücksichtigen.
Die beiden Optionen für Bevorzugt prefers-reduced-motion
sind reduce
oder no-preference
. Wir können es auf folgende Weise in unserem CSS verwenden, um die Animation eines Elements auszuschalten, wenn der Benutzer explizit eine Präferenz für reduzierte Bewegung festgelegt hat:
.some-element { animation: bounce 1200ms; } @media (prefers-reduced-motion: reduce) { .some-element { animation: none; } }
Umgekehrt könnten wir die Animation nur einstellen, wenn der Benutzer keine Bewegungspräferenz hat. Dies hat den Vorteil, dass wir weniger Code schreiben müssen, und es ist weniger wahrscheinlich, dass wir vergessen, die Bewegungspräferenzen der Benutzer zu berücksichtigen:
@media (prefers-reduced-motion: no-preference) { .some-element { animation: bounce 1200ms; } }
Ein zusätzlicher Vorteil besteht darin, dass ältere Browser, die prefers-reduced-motion
nicht unterstützen, die Regel ignorieren und nur unser ursprüngliches, bewegungsfreies Element anzeigen.
Welche Regel?
Im Gegensatz zu Medienabfragen mit minimaler min-width
und max-width
, bei denen der mehr oder weniger etablierte Konsens Mobile-First ist (und daher minimale min-width
bevorzugt), gibt es keinen einzigen „richtigen“ Weg , um Ihre Stile mit reduzierter Bewegung zu schreiben. Aus den oben aufgeführten Gründen bevorzuge ich tendenziell das zweite Beispiel (Animationen nur anwenden, wenn prefers-reduced-motion: no-preference
wird als wahr bewertet). Tatiana Mac hat diesen ausgezeichneten Artikel geschrieben, der einige der Ansätze behandelt, die Entwickler in Betracht ziehen könnten, sowie viele andere wichtige Punkte, einschließlich wichtiger Fragen, die beim Designen mit Bewegung im Web zu stellen sind.
Wie immer sind Teamkommunikation und eine konsistente Strategie der Schlüssel, um sicherzustellen, dass alle Grundlagen in Bezug auf die Barrierefreiheit im Internet abgedeckt sind.
Praktische Anwendung: Anwenden von prefers-reduced-motion
auf das Scrollverhalten
prefers-reduced-motion
hat viele Anwendungen, die über das Anwenden (oder Nicht-Anwenden) von Keyframe-Animationen oder Übergängen hinausgehen. Ein Beispiel ist das reibungslose Scrollen. Wenn wir scroll-behaviour: smooth
für unser html
-Element festlegen, wird ein Benutzer, wenn er auf einen In-Page-Anchor-Link klickt, reibungslos an die entsprechende Position auf der Seite gescrollt ( derzeit nicht in Safari unterstützt ):
html { scroll-behavior: smooth; }
Leider haben wir in CSS derzeit nicht viel Kontrolle über dieses Verhalten. Wenn wir eine lange Inhaltsseite haben, scrollt die Seite sehr schnell, was für jemanden mit Bewegungsempfindlichkeit eine ziemlich unangenehme Erfahrung sein kann. Indem wir es in eine Medienabfrage einschließen, können wir verhindern, dass dieses Verhalten in Fällen angewendet wird, in denen der Benutzer eine reduced-motion
hat:
@media (prefers-reduced-motion: no-preference) { html { scroll-behavior: smooth; } }
Catering für Bewegungseinstellungen in Javascript
Manchmal müssen wir Bewegung in JavaScript statt in CSS anwenden. Wir können auf ähnliche Weise die Bewegungspräferenzen eines Benutzers mit JS erkennen, indem matchMedia
verwenden. Mal sehen, wie wir ein reibungsloses Scrollverhalten in unserem JS-Code bedingt implementieren können:
/* Set the media query */ const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)') button.addEventListener('click', () => { /* If the media query matches, set scroll behavior variable to 'auto', otherwise set it to 'smooth' */ const behavior = prefersReducedMotion.matches ? 'auto' : 'smooth' /* When the button is clicked, the user will be scrolled to the top */ window.scrollTo({ x: 0, y: 0, behavior }) })
Das gleiche Prinzip kann verwendet werden, um zu erkennen, ob bewegungsreiche Benutzeroberflächen mit JS-Bibliotheken implementiert werden sollen – oder sogar, ob die Bibliotheken selbst geladen werden sollen.
Im folgenden Codeausschnitt kehrt die Funktion frühzeitig zurück, wenn der Benutzer eine reduzierte Bewegung bevorzugt, wodurch der unnötige Import einer großen Abhängigkeit vermieden wird – ein Leistungsgewinn für den Benutzer. Wenn sie keine Bewegungspräferenz festgelegt haben, können wir die Greensock-Animationsbibliothek dynamisch importieren und unsere Animationen initialisieren.
const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)') const loadGSAPAndInitAnimations = () => { /* If user prefers reduced motion, do nothing */ if (prefersReducedMotion.matches) return /* Otherwise, import the GSAP module and initialize animations */ import('gsap').then((object) => { const gsap = object.default /* Initialize animations with GSAP here */ }) } loadGSAPAndInitAnimations()
reduced-motion
bedeutet nicht keine Bewegung
Beim Styling für reduzierte Bewegungspräferenzen ist es wichtig, dass wir dem Benutzer immer noch aussagekräftige und zugängliche Indikatoren dafür bieten, wann eine Aktion stattgefunden hat. Wenn wir beispielsweise einen ablenkenden oder bewegungsintensiven Schwebezustand für Benutzer ausschalten, die eine reduzierte Bewegung bevorzugen, müssen wir darauf achten, einen klaren alternativen Stil dafür bereitzustellen, wenn der Benutzer über das Element schwebt.
Die folgende Demo zeigt einen ausgefeilten Übergang, wenn der Benutzer den Mauszeiger bewegt oder sich auf ein Galerieelement konzentriert, wenn er keine Bewegungspräferenz festgelegt hat. Wenn sie eine reduzierte Bewegung bevorzugen, ist der Übergang subtiler, zeigt aber dennoch deutlich den Schwebezustand an:
Reduzierte Bewegung bedeutet auch nicht unbedingt, dass alle Transformationen von unserer Webseite entfernt werden. Beispielsweise verursacht eine Schaltfläche mit einem kleinen Pfeilsymbol, das sich beim Schweben um einige Pixel bewegt, wahrscheinlich keine Probleme für jemanden, der ein Erlebnis mit reduzierter Bewegung bevorzugt, und bietet einen nützlicheren Indikator für eine Zustandsänderung als nur die Farbe.
Ich sehe manchmal Entwickler, die reduzierte Bewegungsstile auf folgende Weise anwenden, wodurch alle Übergänge und Animationen auf allen Elementen eliminiert werden:
@media screen and (prefers-reduced-motion: reduce) { * { animation: none !important; transition: none !important; scroll-behavior: auto !important; } }
Dies ist wohl besser, als die Bewegungspräferenzen der Benutzer zu ignorieren, erlaubt es uns jedoch nicht, Elemente einfach anzupassen, um bei Bedarf subtilere Übergänge bereitzustellen.
Im folgenden Code-Snippet haben wir eine Schaltfläche, die beim Hover größer wird. Wir ändern die Farben und die Skalierung, aber Benutzer mit einer Vorliebe für reduzierte Bewegung erhalten überhaupt keinen Übergang:
button { background-color: hotpink; transition: color 300ms, background-color 300ms, transform 500ms cubic-bezier(.44, .23, .47, 1.27); } button:hover, button:focus { background-color: darkviolet; color: white; transform: scale(1.2); } @media screen and (prefers-reduced-motion: reduce) { * { animation: none !important; transition: none !important; scroll-behavior: auto !important; } button { /* Even though we would still like to transition the colors of our button, the following rule will have no effect */ transition: color 200ms, background-color 200ms; } button:hover, button:focus { /* Preventing the button scaling on hover */ transform: scale(1); } }
Schauen Sie sich diese Demo an, um den Effekt zu sehen. Dies ist vielleicht nicht ideal, da sich der plötzliche Farbwechsel ohne Übergang störender anfühlen könnte als ein Übergang von ein paar hundert Millisekunden. Das ist einer der Gründe, warum ich es generell vorziehe, von Fall zu Fall auf reduzierte Bewegung zu stylen.
Wenn Sie interessiert sind, ist dies dieselbe Demo, die umgestaltet wurde, um bei Bedarf eine Anpassung des Übergangs zu ermöglichen. Es verwendet eine benutzerdefinierte Eigenschaft für die Übergangsdauer, die es uns ermöglicht, den Skalierungsübergang ein- und auszuschalten, ohne die gesamte Deklaration neu schreiben zu müssen.
Wenn das Entfernen von Animationen besser ist
Eric Bailey weist in seinem Artikel „Revisiting Preferreds-Reduced-Motion, the Reduced Motion Media Query“ darauf hin, dass „nicht jedes Gerät, das auf das Internet zugreifen kann, auch Animationen rendern oder Animationen reibungslos rendern kann“. Bei Geräten mit einer niedrigen Bildwiederholfrequenz, die zu ruckeligen Animationen führen kann, ist es möglicherweise sogar vorzuziehen, die Animation zu entfernen . Mit der update
-Media-Funktion kann dies ermittelt werden:
@media screen and (prefers-reduced-motion: reduce), (update: slow) { * { animation-duration: 0.001ms !important; animation-iteration-count: 1 !important; transition-duration: 0.001ms !important; } }
Lesen Sie unbedingt den vollständigen Artikel für Erics Empfehlungen, da er eine erstklassige Person auf dem Gebiet der Barrierefreiheit ist.
Die Summe aller Teile
Es ist wichtig, das gesamte Seitendesign im Auge zu behalten, wenn man sich so stark auf CSS auf Komponentenebene konzentriert. Was auf Komponentenebene als ziemlich harmlose Animation erscheinen mag, könnte eine weitaus größere Wirkung haben, wenn sie auf der gesamten Seite wiederholt wird, und ist einer von vielen beweglichen Teilen.
In Tatianas Artikel schlägt sie vor, Animationen (mit prefers-reduced-motion
) in einer einzigen CSS-Datei zu organisieren, die nur geladen werden kann, wenn (prefers-reduced-motion: no-preference)
als true ausgewertet wird. Die Gesamtsumme aller unserer Animationen zu sehen, könnte den zusätzlichen Vorteil haben, dass es uns hilft, das Erlebnis beim Besuch der Website als Ganzes zu visualisieren und unsere bewegungsreduzierten Stile entsprechend anzupassen.
Explizite Bewegung umschalten
Während prefers-reduced-motion
“ nützlich ist, hat es den Nachteil, dass es nur für Benutzer gedacht ist, die sich der Funktion in ihren Systemeinstellungen bewusst sind. Vielen Benutzern ist diese Einstellung nicht bekannt, während andere möglicherweise einen geliehenen Computer verwenden, ohne Zugriff auf Einstellungen auf Systemebene. Wieder andere mögen mit der Bewegung für die überwiegende Mehrheit der Websites zufrieden sein, finden jedoch Websites mit starkem Einsatz von Bewegung schwer zu ertragen.
Es kann lästig sein, Ihre Systemeinstellungen anpassen zu müssen, nur um eine Seite zu besuchen. Aus diesen Gründen ist es in manchen Fällen vorzuziehen, auf der Website selbst eine explizite Steuerung bereitzustellen, um die Bewegung ein- und auszuschalten . Wir können dies mit JS implementieren.
Die folgende Demo hat mehrere Kreise, die um den Hintergrund treiben. Die anfänglichen Animationsstile werden durch die Systempräferenzen des Benutzers bestimmt (mit prefers-reduced-motion
), der Benutzer hat jedoch die Möglichkeit, die Bewegung über eine Schaltfläche ein- oder auszuschalten. Dies fügt dem body
eine Klasse hinzu, mit der wir je nach ausgewählter Einstellung Stile festlegen können. Als Bonus wird die Wahl der Bewegungspräferenz auch im lokalen Speicher aufbewahrt – so wird sie beim nächsten Besuch des Benutzers „erinnert“.
Benutzerdefinierte Eigenschaften
Eine Funktion in der Demo ist, dass der Schalter eine benutzerdefinierte Eigenschaft festlegt, --playState
, die wir zum Abspielen oder Anhalten von Animationen verwenden können. Dies kann besonders praktisch sein, wenn Sie mehrere Animationen gleichzeitig anhalten oder abspielen müssen. Als erstes setzen wir den Play State auf paused
:
.circle { animation-play-state: var(--playState, paused); }
Wenn der Benutzer in seinen Systemeinstellungen eine Präferenz für reduzierte Bewegung festgelegt hat, können wir den Wiedergabestatus auf running
setzen:
@media (prefers-reduced-motion: no-preference) { body { --playState: running; } }
Hinweis: Wenn Sie dies für den body
festlegen, im Gegensatz zum einzelnen Element, bedeutet dies, dass die benutzerdefinierte Eigenschaft vererbt werden kann.
Wenn der Benutzer auf den Schalter klickt, wird die benutzerdefinierte Eigenschaft im body
aktualisiert, wodurch alle Instanzen, in denen sie verwendet wird, umgeschaltet werden:
// This will pause all animations that use the `--playState` custom property document.body.style.setProperty('--playState', 'paused')
Dies ist möglicherweise nicht in allen Fällen die ideale Lösung, aber ein Vorteil besteht darin, dass die Animation einfach angehalten wird, wenn der Benutzer auf den Schalter klickt, anstatt in den ursprünglichen Zustand zurückzukehren, was ziemlich störend sein könnte.
Besonderer Dank geht an Scott O'Hara für seine Empfehlungen zur Verbesserung der Zugänglichkeit des Umschalters. Er machte mich darauf aufmerksam, dass einige Screenreader den aktualisierten Schaltflächentext nicht ankündigen, der geändert wird, wenn ein Benutzer auf die Schaltfläche klickt, und schlugen stattdessen role="switch"
auf der Schaltfläche vor, wobei aria-checked
beim Klicken on
oder off
.
Videokomponente
In einigen Fällen kann das Umschalten der Bewegung auf Komponentenebene eine bessere Option sein. Nehmen Sie eine Webseite mit einem automatisch abspielenden Videohintergrund. Wir sollten sicherstellen, dass das Video für Benutzer mit einer Vorliebe für reduzierte Bewegung nicht automatisch abgespielt wird, aber wir sollten ihnen dennoch eine Möglichkeit bieten, das Video nur abzuspielen, wenn sie dies wünschen . (Einige mögen argumentieren, dass wir das automatische Abspielen von Videos vermeiden sollten, aber wir gewinnen diesen Kampf nicht immer!) Wenn ein Video für Benutzer ohne festgelegte Präferenz auf automatisches Abspielen eingestellt ist, sollten wir ihnen ebenfalls eine Möglichkeit bieten pausieren Sie das Video.
Diese Demo zeigt, wie wir das Autoplay-Attribut festlegen können, wenn der Benutzer keine Bewegungspräferenz angegeben hat, indem wir eine benutzerdefinierte Wiedergabe-/Pause-Schaltfläche implementieren, mit der er unabhängig von der Präferenz auch die Wiedergabe umschalten kann:
(Ich bin später auf diesen Beitrag von Scott O'Hara gestoßen, der genau diesen Anwendungsfall beschreibt.)
Verwendung des <picture>
-Elements
Chris Coyier hat einen interessanten Artikel geschrieben, in dem er einige Techniken zum Laden verschiedener Medienquellen in Abhängigkeit von den Bewegungspräferenzen des Benutzers kombiniert. Das ist ziemlich cool, denn es bedeutet, dass für Benutzer, die eine reduzierte Bewegung bevorzugen , die viel größere GIF-Datei nicht einmal heruntergeladen wird. Der Nachteil besteht meines Erachtens darin, dass der Benutzer nach dem Herunterladen der Datei nicht mehr zur bewegungsfreien Alternative zurückkehren kann.
Ich erstelle eine modifizierte Version der Demo, die diese Option hinzufügt. (Schalten Sie reduced-motion
in Ihren Systemeinstellungen ein, um sie in Aktion zu sehen.) Leider scheint es beim Umschalten zwischen den animierten und bewegungsfreien Optionen in Chrome, dass die GIF-Datei jedes Mal neu heruntergeladen wird, was nicht der Fall ist andere Browser:
Dennoch scheint diese Technik eine respektvollere Art zu sein, GIFs anzuzeigen, was für Benutzer eine Quelle der Frustration sein kann.
Browserunterstützung und abschließende Gedanken
prefers-reduced-motion
wird seit einigen Jahren in allen modernen Browsern hervorragend unterstützt. Wie wir gesehen haben, erhalten nicht unterstützende Browser durch einen Ansatz mit reduzierter Bewegung zuerst einen Fallback mit reduced-motion
. Es gibt keinen Grund, es heute nicht zu verwenden, um Ihre Websites zugänglicher zu machen.
Benutzerdefinierte Schalter haben definitiv einen Platz und können die Erfahrung für Benutzer erheblich verbessern , die sich dieser Einstellung oder ihrer Wirkung nicht bewusst sind. Der Nachteil für den Benutzer ist die Inkonsistenz – wenn jeder Entwickler gezwungen ist, seine eigene Lösung zu finden, muss der Benutzer an einer anderen Stelle auf jeder Website nach einem Bewegungsumschalter suchen.
Es fühlt sich an, als ob die fehlende Schicht hier Browser sind. Ich würde gerne sehen, dass Browser reduced-motion
Umschalter implementieren, die für den Benutzer leicht zugänglich sind, damit die Leute wissen, wo sie sie finden, unabhängig von der Website, die sie durchsuchen. Es könnte Entwickler dazu ermutigen, auch mehr Zeit für die Gewährleistung der Bewegungszugänglichkeit aufzuwenden.
Ähnliche Resourcen
- Level 5 Media Queries Specification, World Wide Web Consortium (W3C)
-
prefers-reduced-motion
, MDN Web Docs, Mozilla - Design mit reduzierter Bewegung für Bewegungsempfindlichkeit, Val Head, Smashing Magazine
- Einen No-Motion-First-Ansatz für Animationen verfolgen, Tatiana Mac
- Reduzierte Filmtechnik, Take 2, Chris Coyier, CSS-Tricks
- Revisiting
prefers-reduced-motion
, The Reduced Motion Media Query, Eric Bailey, CSS-Tricks - Reduzierung der Bewegung zur Verbesserung der Zugänglichkeit, Lindsey Kopacz