prefers-reduced-motion: a volte meno movimento è più

La query sui contenuti multimediali prefers-reduced-motion rileva se l'utente ha richiesto al sistema operativo di ridurre al minimo la quantità di animazione o movimento utilizzata.

Non a tutti piacciono le animazioni o le transizioni decorative e alcuni utenti soffrono di cinetosi quando si trovano di fronte a scorrimento parallattico, effetti di zoom e altro ancora. La query media per le preferenze dell'utente prefers-reduced-motion ti consente di progettare una variante del tuo sito con movimenti ridotti per gli utenti che hanno espresso questa preferenza.

Supporto dei browser

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

Origine

Troppo movimento nella vita reale e sul web

L'altro giorno pattinavo con i miei figli. Era una bella giornata, il sole splendeva e la pista di ghiaccio era affollata di gente ⛸. L'unico problema: non so gestire bene la folla. Con così molti obiettivi in movimento, non riesco a concentrarmi su nulla e finisco per sentirmi perso e con una sensazione di completo sovraccarico visivo, quasi come se guardassi una formicaio 🐜.

Una folla di persone che pattinano sul ghiaccio.
Sovraccarico visivo nella vita reale.

A volte può succedere lo stesso sul web: con annunci lampeggianti, effetti di parallasse elaborati, animazioni di rivelazione sorprendenti, video con riproduzione automatica e altro ancora, a volte il web può essere piuttosto opprimente… Fortunatamente, a differenza della vita reale, esiste una soluzione. La query sui media CSS prefers-reduced-motion consente agli sviluppatori di creare una variante di una pagina per gli utenti che preferiscono un movimento ridotto. Può trattarsi di qualsiasi cosa, dall'evitare la riproduzione automatica dei video alla disattivazione di determinati effetti puramente decorativi, fino alla riprogettazione completa di una pagina per determinati utenti.

Prima di approfondire la funzionalità, facciamo un passo indietro e pensiamo a cosa si usano le animazioni sul web. Se vuoi, puoi anche saltare le informazioni di sfondo e passare direttamente ai dettagli tecnici.

Animazione sul web

Le animazioni vengono spesso utilizzate per fornire feedback all'utente, ad esempio per comunicargli che un'azione è stata ricevuta ed è in corso di elaborazione. Ad esempio, su un sito web di shopping, un prodotto potrebbe essere animato in modo da "volare" in un carrello virtuale, rappresentato come un'icona nell'angolo in alto a destra del sito.

Un altro caso d'uso prevede l'utilizzo del movimento per manipolare la percezione dell'utente mediante una combinazione di schermate di scheletro, metadati contestuali e anteprime di immagini di bassa qualità per occupare molto tempo dell'utente e rendere l'intera esperienza più veloce. L'idea è fornire all'utente il contesto di ciò che sta per accadere e nel frattempo caricare le informazioni il più rapidamente possibile.

Infine, ci sono gli effetti decorativi, come gradienti animati, scorrimento parallattico, video in background e molti altri. Sebbene molte persone apprezzino queste animazioni, alcune non le amano perché si sentono distratte o rallentate. Nel peggiore dei casi, gli utenti potrebbero persino soffrire di cinetosi come se si trattasse di un'esperienza reale, quindi per questi utenti la riduzione delle animazioni è una necessità medica.

Disturbo dello spettro vestibolare innescato dal movimento

Alcuni utenti avvertono distrazione o nausea a causa dei contenuti animati. Ad esempio, le animazioni con scorrimento possono causare disturbi vestibolari quando elementi diversi dall'elemento principale associato allo scorrimento si spostano molto. Ad esempio, le animazioni con scorrimento parallasse possono causare disturbi vestibolari perché gli elementi di sfondo si muovono a una velocità diversa rispetto agli elementi in primo piano. Le reazioni relative a disturbi vestibolari (dell'orecchio interno) includono vertigini, nausea e emicrania e a volte richiedono il riposo a letto per il recupero.

Rimuovere il movimento sui sistemi operativi

Molti sistemi operativi dispongono da tempo di impostazioni di accessibilità per specificare una preferenza per le animazioni ridotte. Gli screenshot seguenti mostrano l'opzione Riduci movimento di macOS Mojave e l'opzione Rimuovi animazioni di Android Pie. Se selezionate, queste preferenze impediscono al sistema operativo di utilizzare effetti decorativi come le animazioni di avvio delle app. Anche le applicazioni stesse possono e devono rispettare questa impostazione e rimuovere tutte le animazioni non necessarie.

La schermata delle impostazioni di macOS con la casella di controllo "Riduci movimento" selezionata.
La schermata delle impostazioni di Android con la casella di controllo "Rimuovi animazioni" selezionata.

Rimuovere il movimento sul web

Il livello 5 delle query sui media consente di applicare la preferenza dell'utente per le animazioni ridotte anche al web. Le query sui media consentono agli autori di testare e eseguire query sui valori o sulle funzionalità dell'agente utente o del dispositivo di visualizzazione indipendentemente dal documento visualizzato. La query media prefers-reduced-motion viene utilizzata per rilevare se l'utente ha impostato una preferenza del sistema operativo per ridurre al minimo la quantità di animazione o movimento utilizzata. Può assumere due valori possibili:

  • no-preference: indica che l'utente non ha impostato alcuna preferenza nel sistema operativo di base. Questo valore della parola chiave viene valutato come false nel contesto booleano.
  • reduce: indica che l'utente ha impostato una preferenza del sistema operativo che indica che le interfacce devono ridurre al minimo i movimenti o le animazioni, preferibilmente fino a quando tutti i movimenti non essenziali vengono rimossi.

Utilizzo della query sui media dai contesti CSS e JavaScript

Come per tutte le query sui media, prefers-reduced-motion può essere controllato da un contesto CSS e da un contesto JavaScript.

Per illustrare entrambi, supponiamo che io abbia un pulsante di registrazione importante su cui voglio che l'utente faccia clic. Potrei definire un'animazione "vibrante" che attira l'attenzione, ma da buon cittadino del web la mostrerò solo agli utenti che accettano esplicitamente le animazioni, ma non a tutti gli altri, ad esempio agli utenti che hanno disattivato le animazioni o a quelli che utilizzano browser che non comprendono la query sui media.

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

Per illustrare come utilizzare prefers-reduced-motion con JavaScript, immagina di aver definito un'animazione complessa con l'API delle animazioni web. Mentre le regole CSS vengono attivate dinamicamente dal browser quando le preferenze dell'utente cambiano, per le animazioni JavaScript devo rilevare le modifiche autonomamente e interrompere manualmente le animazioni potenzialmente in esecuzione (o riavviarle se l'utente me lo consente):

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

Tieni presente che le parentesi che circondano la query sui contenuti multimediali effettiva sono obbligatorie:

Cosa non fare
window.matchMedia('prefers-reduced-motion: reduce');
Cosa fare
window.matchMedia('(prefers-reduced-motion: reduce)');

Utilizzo della query sui contenuti multimediali dai contesti <picture>

Un caso d'uso interessante è rendere la riproduzione di un'animazione AVIF, WebP o GIF dipendente dall'attributo media. Se (prefers-reduced-motion: no-preference) ha il valore true, è possibile visualizzare la versione animata, altrimenti la versione statica:

<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>

Puoi vedere l'esempio seguente. Prova a disattivare e riattivare le preferenze relative al movimento del dispositivo per vedere la differenza.

Il famoso Nyan Cat.

Scoprire le preferenze dell'utente al momento della richiesta

L'intestazione dell'indicazione client Sec-CH-Prefers-Reduced-Motion consente ai siti di ottenere facoltativamente le preferenze di movimento dell'utente al momento della richiesta, consentendo ai server di inserire in linea il CSS corretto per motivi di prestazioni.

Demo

Ho creato una piccola demo basata sui fantastici 🐈 gatti di stato HTTP di Rogério Vicente. Innanzitutto, prenditi un momento per apprezzare la barzelletta, è divertentissima e io aspetterò. Ora che sei tornato, ti presento la demo. Quando scorri, ogni stato HTTP viene visualizzato alternativamente sul lato destro o sinistro. Si tratta di un'animazione fluida a 60 FPS, ma, come indicato in precedenza, alcuni utenti potrebbero non apprezzarla o addirittura soffrire di cinetosi, pertanto la demo è programmata per rispettare prefers-reduced-motion. Questo funziona anche in modo dinamico, quindi gli utenti possono cambiare le proprie preferenze in tempo reale, senza bisogno di ricaricare la pagina. Se un utente preferisce ridurre il movimento, le animazioni di visualizzazione non necessarie vengono rimosse e rimane solo il movimento di scorrimento normale. Il screencast seguente mostra la demo in azione:

Video dell'app prefers-reduced-motion demo

Conclusioni

Il rispetto delle preferenze degli utenti è fondamentale per i siti web moderni e i browser stanno esponendo sempre più funzionalità per consentire agli sviluppatori web di farlo. Un altro esempio lanciato è prefers-color-scheme, che rileva se l'utente preferisce una combinazione di colori chiara o scura. Puoi scoprire di più su prefers-color-scheme nel mio articolo Hello Darkness, My Old Friend 🌒.

Il gruppo di lavoro CSS sta standardizzando altre query sui contenuti multimediali per le preferenze dell'utente come prefers-reduced-transparency (rileva se l'utente preferisce una trasparenza ridotta), prefers-contrast (rileva se l'utente ha richiesto al sistema di aumentare o diminuire la quantità di contrasto tra i colori adiacenti) e inverted-colors (rileva se l'utente preferisce i colori invertiti).

(Extra) Imposizione del movimento ridotto su tutti i siti web

Non tutti i siti utilizzeranno prefers-reduced-motion o forse non in misura sufficiente per i tuoi gusti. Se, per qualsiasi motivo, vuoi interrompere il movimento su tutti i siti web, puoi farlo. Un modo per farlo è inserire un foglio di stile con il seguente CSS in ogni pagina web che visiti. Esistono diverse estensioni del browser (da utilizzare a proprio rischio) che consentono di farlo.

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

Il CSS precedente sostituisce le durate di tutte le animazioni e transizioni in un lasso di tempo così breve che non sono più visibili. Poiché alcuni siti web richiedono l'esecuzione di un'animazione per funzionare correttamente (ad esempio perché un determinato passaggio dipende dall'attivazione dell'evento animationend), l'approccio animation: none !important; più radicale non funzionerebbe. Anche l'hack precedente non garantisce il funzionamento su tutti i siti web (ad esempio, non può interrompere il movimento avviato utilizzando l'API Web Animations), quindi assicurati di disattivarlo quando noti un malfunzionamento.

Ringraziamenti

Un grande ringraziamento a Stephen McGruer, che ha implementatoprefers-reduced-motion in Chrome e, insieme a Rob Dodson, ha anche esaminato questo documento. Immagine hero di Hannah Cauhepe su Unsplash.