préfère-réduire-le-mouvement: parfois, il suffit de moins bouger

La requête multimédia prefers-reduced-motion détecte si l'utilisateur a demandé au système d'exploitation de réduire la quantité d'animation ou de mouvement qu'il utilise.

Tout le monde n'aime pas les animations ou les transitions décoratives, et certains utilisateurs souffrent carrément du mal des transports lorsqu'ils sont confrontés au défilement parallaxe, aux effets de zoom, etc. La requête multimédia de préférences utilisateur prefers-reduced-motion vous permet de concevoir une variante de votre site avec des mouvements réduits pour les utilisateurs qui ont exprimé cette préférence.

Navigateurs pris en charge

  • Chrome: 74.
  • Edge: 79.
  • Firefox: 63.
  • Safari: 10.1.

Source

Trop de mouvement dans la vie réelle et sur le Web

L'autre jour, j'étais en train de patiner avec mes enfants. C'était une belle journée, le soleil brillait et la patinoire était bondée de monde ⛸. Le seul problème: je ne m'entends pas bien avec les foules. Avec autant de cibles mobiles, je n'arrive pas à me concentrer sur quoi que ce soit. Je me sens perdu et j'ai le sentiment d'une surcharge visuelle complète, comme si je fixais une fourmilière 🐜.

Foule de patineurs à glace.
Surcharge visuelle dans la vie réelle.

Il arrive parfois que la même chose se produise sur le Web: avec des annonces clignotantes, des effets de parallaxe sophistiqués, des animations de révélation surprenantes, des vidéos en lecture automatique, etc., le Web peut parfois être assez débordant. Heureusement, contrairement à la vie réelle, il existe une solution à ce problème. La requête média CSS prefers-reduced-motion permet aux développeurs de créer une variante d'une page pour les utilisateurs qui préfèrent un mouvement réduit. Il peut s'agir de ne pas diffuser de vidéos en lecture automatique, de désactiver certains effets purement décoratifs ou de repenser complètement une page pour certains utilisateurs.

Avant de me plonger dans cette fonctionnalité, je vais faire un pas en arrière et réfléchir à l'utilité des animations sur le Web. Si vous le souhaitez, vous pouvez également ignorer les informations générales et passer directement aux détails techniques.

Animation sur le Web

Les animations sont souvent utilisées pour fournir des commentaires à l'utilisateur, par exemple pour l'informer qu'une action a été reçue et est en cours de traitement. Par exemple, sur un site Web d'achat, un produit peut être animé pour "voler" dans un panier virtuel, représenté par une icône en haut à droite du site.

Un autre cas d'utilisation consiste à utiliser le mouvement pour pirater la perception de l'utilisateur en combinant des écrans squelettes, des métadonnées contextuelles et des aperçus d'images de mauvaise qualité pour occuper une grande partie du temps de l'utilisateur et donner l'impression que l'ensemble de l'expérience est plus rapide. L'idée est de donner à l'utilisateur un contexte sur ce qui va se passer, tout en chargeant les éléments aussi rapidement que possible.

Enfin, il existe des effets décoratifs tels que les dégradés animés, le défilement en parallaxe, les vidéos en arrière-plan et bien d'autres. Bien que de nombreux utilisateurs apprécient ces animations, certains les détestent, car elles les distraient ou les ralentissent. Dans le pire des cas, les utilisateurs peuvent même souffrir du mal des transports comme s'il s'agissait d'une expérience réelle. Pour ces utilisateurs, réduire les animations est une nécessité médicale.

Trouble du spectre vestibulaire déclenché par le mouvement

Certains utilisateurs ressentent une distraction ou des nausées en raison de contenus animés. Par exemple, les animations de défilement peuvent provoquer des troubles vestibulaires lorsque des éléments autres que l'élément principal associé au défilement se déplacent beaucoup. Par exemple, les animations de défilement parallaxe peuvent provoquer des troubles vestibulaires, car les éléments d'arrière-plan se déplacent à un rythme différent de celui des éléments de premier plan. Les réactions liées aux troubles vestibulaires (oreille interne) incluent les vertiges, les nausées et les migraines, et nécessitent parfois un repos au lit pour s'en remettre.

Supprimer le mouvement sur les systèmes d'exploitation

De nombreux systèmes d'exploitation proposent depuis longtemps des paramètres d'accessibilité permettant de spécifier une préférence pour une réduction des mouvements. Les captures d'écran suivantes montrent la préférence Réduire le mouvement de macOS Mojave et la préférence Supprimer les animations d'Android Pie. Lorsque ces préférences sont activées, le système d'exploitation n'utilise pas d'effets décoratifs tels que les animations de lancement d'application. Les applications elles-mêmes peuvent et doivent également respecter ce paramètre et supprimer toutes les animations inutiles.

Écran des paramètres macOS avec la case "Réduire le mouvement" cochée.
Écran des paramètres Android avec la case "Supprimer les animations" cochée.

Supprimer le mouvement sur le Web

Les requêtes multimédias de niveau 5 apportent également la préférence utilisateur de réduction du mouvement sur le Web. Les requêtes multimédias permettent aux auteurs de tester et d'interroger les valeurs ou les fonctionnalités de l'agent utilisateur ou de l'appareil d'affichage indépendamment du document affiché. La requête multimédia prefers-reduced-motion permet de détecter si l'utilisateur a défini une préférence de système d'exploitation pour réduire la quantité d'animation ou de mouvement qu'il utilise. Il peut prendre deux valeurs possibles:

  • no-preference: indique que l'utilisateur n'a pas défini de préférence dans le système d'exploitation sous-jacent. La valeur de ce mot clé est évaluée comme false dans le contexte booléen.
  • reduce: indique que l'utilisateur a défini une préférence de système d'exploitation indiquant que les interfaces doivent réduire au maximum les mouvements ou les animations, de préférence au point où tous les mouvements non essentiels sont supprimés.

Utiliser la requête multimédia à partir de contextes CSS et JavaScript

Comme pour tous les requêtes multimédias, prefers-reduced-motion peut être vérifié à partir d'un contexte CSS et d'un contexte JavaScript.

Pour illustrer les deux, supposons que j'ai un bouton d'inscription important sur lequel je souhaite que l'utilisateur clique. Je pourrais définir une animation "vibration" attrayante, mais en tant que bon citoyen du Web, je ne la diffuserai que pour les utilisateurs qui acceptent explicitement les animations, et non pour tous les autres, qui peuvent être des utilisateurs qui ont désactivé les animations ou des utilisateurs sur des navigateurs qui ne comprennent pas la requête multimédia.

/*
  If the user has expressed their preference for
  reduced motion, then don't use animations on buttons.
*/
@media (prefers-reduced-motion: reduce) {
  button {
    animation: none;
  }
}

/*
  If the browser understands the media query and the user
  explicitly hasn't set a preference, then use animations on buttons.
*/
@media (prefers-reduced-motion: no-preference) {
  button {
    /* `vibrate` keyframes are defined elsewhere */
    animation: vibrate 0.3s linear infinite both;
  }
}

Pour illustrer comment utiliser prefers-reduced-motion avec JavaScript, imaginez que j'ai défini une animation complexe avec l'API Web Animations. Bien que les règles CSS soient déclenchées de manière dynamique par le navigateur lorsque les préférences de l'utilisateur changent, pour les animations JavaScript, je dois écouter les modifications moi-même, puis arrêter manuellement mes animations en cours d'exécution (ou les redémarrer si l'utilisateur me le permet):

const mediaQuery = window.matchMedia('(prefers-reduced-motion: reduce)');
mediaQuery.addEventListener('change', () => {
  console.log(mediaQuery.media, mediaQuery.matches);
  // Stop JavaScript-based animations.
});

Notez que les parenthèses autour de la requête multimédia sont obligatoires:

À éviter
window.matchMedia('prefers-reduced-motion: reduce');
À faire
window.matchMedia('(prefers-reduced-motion: reduce)');

Utiliser la requête multimédia à partir de contextes <picture>

Un cas d'utilisation intéressant consiste à faire dépendre la lecture d'un AVIF, d'un WebP ou d'un GIF animé de l'attribut media. Si (prefers-reduced-motion: no-preference) renvoie true, vous pouvez afficher la version animée, sinon la version statique:

<picture>
  <!-- Animated versions. -->
  <source
    srcset="nyancat.avifs"
    type="image/avif"
    media="(prefers-reduced-motion: no-preference)"
  />
  <source
    srcset="nyancat.gif"
    type="image/gif"
    media="(prefers-reduced-motion: no-preference)"
  />
  <!-- Static versions. -->
  <img src="nyancat.png" alt="Nyan cat" width="250" height="250" />
</picture>

Vous pouvez consulter l'exemple suivant. Essayez d'activer ou de désactiver les préférences de mouvement de votre appareil pour voir la différence.

Le célèbre chat Nyan.

Découvrir les préférences de l'utilisateur au moment de la requête

L'en-tête d'indice client Sec-CH-Prefers-Reduced-Motion permet aux sites d'obtenir les préférences de mouvement de l'utilisateur au moment de la requête, ce qui permet aux serveurs d'intégrer le CSS approprié pour des raisons de performances.

Démo

J'ai créé une petite démonstration basée sur les incroyables 🐈 chats d'état HTTP de Rogério Vicente. Tout d'abord, prenez le temps d'apprécier la blague, elle est hilarante. Je vais vous laisser le temps. Maintenant que vous êtes de retour, laissez-moi vous présenter la démonstration. Lorsque vous faites défiler la page, chaque catégorie d'état HTTP s'affiche alternativement à droite ou à gauche. Il s'agit d'une animation fluide à 60 FPS, mais comme indiqué précédemment, certains utilisateurs peuvent ne pas l'apprécier ou même souffrir de la cinétose. La démo est donc programmée pour respecter prefers-reduced-motion. Cela fonctionne même de manière dynamique, ce qui permet aux utilisateurs de modifier leurs préférences instantanément, sans avoir à actualiser la page. Si un utilisateur préfère réduire les mouvements, les animations de révélation inutiles sont supprimées, et il ne reste que le mouvement de défilement normal. L'enregistrement d'écran suivant montre la démonstration en action:

Vidéo de l'application de démonstration prefers-reduced-motion

Conclusions

Le respect des préférences des utilisateurs est essentiel pour les sites Web modernes, et les navigateurs exposent de plus en plus de fonctionnalités pour permettre aux développeurs Web de le faire. prefers-color-scheme est un autre exemple de lancement, qui détecte si l'utilisateur préfère un jeu de couleurs clair ou sombre. Vous pouvez tout savoir sur prefers-color-scheme dans mon article Hello Darkness, My Old Friend 🌒.

Le groupe de travail CSS standardise davantage de requêtes multimédias en fonction des préférences de l'utilisateur, comme prefers-reduced-transparency (détecte si l'utilisateur préfère une transparence réduite), prefers-contrast (détecte si l'utilisateur a demandé au système d'augmenter ou de diminuer le contraste entre les couleurs adjacentes) et inverted-colors (détecte si l'utilisateur préfère les couleurs inversées).

(Bonus) Forcer les mouvements réduits sur tous les sites Web

Tous les sites n'utilisent pas prefers-reduced-motion, ou peut-être pas suffisamment à votre goût. Si vous souhaitez désactiver le mouvement sur tous les sites Web, vous pouvez le faire. Pour ce faire, vous pouvez injecter une feuille de style avec le code CSS suivant dans chaque page Web que vous consultez. Plusieurs extensions de navigateur (à utiliser à vos risques et périls) permettent de le faire.

@media (prefers-reduced-motion: reduce) {
  *,
  ::before,
  ::after {
    animation-delay: -1ms !important;
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
    background-attachment: initial !important;
    scroll-behavior: auto !important;
    transition-duration: 1ms !important;
    transition-delay: -1ms !important;
  }
}

Le CSS précédent remplace les durées de toutes les animations et transitions par une durée si courte qu'elles ne sont plus visibles. Étant donné que certains sites Web nécessitent l'exécution d'une animation pour fonctionner correctement (par exemple, parce qu'une étape dépend du déclenchement de l'événement animationend), l'approche animation: none !important; plus radicale ne fonctionnerait pas. Même le piratage précédent n'est pas garanti de fonctionner sur tous les sites Web (par exemple, il ne peut pas arrêter le mouvement lancé à l'aide de l'API Web Animations). Veillez donc à le désactiver lorsque vous constatez un dysfonctionnement.

Remerciements

Un grand merci à Stephen McGruer, qui a implémenté prefers-reduced-motion dans Chrome et qui, avec Rob Dodson, a également examiné ce document. Image héros par Hannah Cauhepe sur Unsplash.