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

La query supporti di movimento prefers-ridotto rileva se l'utente ha richiesto al sistema operativo di ridurre al minimo la quantità di animazione o movimento utilizzato.

Non a tutti piacciono le transizioni o le animazioni decorative e alcuni utenti provano addirittura il mal di movimento quando si trovano di fronte allo scorrimento con parallasse, agli effetti di zoom e così via. La query multimediale prefers-reduced-motion per le preferenze utente ti consente di progettare una variante del tuo sito con minore movimento per gli utenti che hanno espresso questa preferenza.

Supporto dei browser

  • 74
  • 79
  • 63
  • 10.1

Origine

Troppo movimento nella vita reale e sul web

L'altro giorno stavo pattinando su ghiaccio con i miei figli. È stata una bella giornata, il sole splendeva e la pista di pattinaggio era piena di gente ⛸. L'unico problema: non reagisco bene alla folla. Con così tanti bersagli mobili non riesco a concentrarmi su niente e finisco per perdermi e avere la sensazione di un completo sovraccarico visivo, quasi come guardare un formicaio 🐜.

Numero di piedi di persone che pattinano sul ghiaccio.
Sovraccarico visivo nel mondo reale.

Talvolta, la stessa cosa può accadere sul web: con annunci lampeggianti, effetti parallasse fantasiosi, animazioni sorprese, video con riproduzione automatica e così via, il web a volte può essere piuttosto faticoso... Per fortuna, a differenza del mondo reale, c'è una soluzione. La query multimediale CSS prefers-reduced-motion consente agli sviluppatori di creare una variante di una pagina per gli utenti che preferiscono il movimento ridotto. Può trattarsi di qualsiasi cosa, dall'assenza di video con riproduzione automatica, alla disattivazione di alcuni effetti puramente decorativi o alla riprogettazione completa di una pagina per determinati utenti.

Prima di approfondire la funzionalità, facciamo un passo indietro e pensiamo a quali animazioni vengono utilizzate sul web. Se vuoi, puoi anche saltare le informazioni di base e passare direttamente ai dettagli tecnici di seguito.

Animazione sul web

L'animazione viene spesso utilizzata per fornire feedback all'utente, ad esempio per informarlo che un'azione è stata ricevuta ed è in fase di elaborazione. Ad esempio, su un sito web di shopping, un prodotto potrebbe essere animato in modo da "volare" verso 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 compromettere la percezione degli utenti utilizzando una combinazione di scheletri, 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 un contesto all'utente in merito a ciò che sta per accadere e, nel frattempo, caricare i contenuti il più rapidamente possibile.

Infine, ci sono effetti decorativi come sfumature animate, scorrimento con parallasse, video sullo sfondo e molti altri. Anche se a molti utenti piacciono le animazioni, ad alcuni non piacciono perché si sentono distratte o rallentate. Nel peggiore dei casi, gli utenti potrebbero anche soffrire di chinetosi come se si trattasse di un'esperienza di vita reale, quindi per questi utenti ridurre le animazioni è una necessità medica.

Disturbo dello spettro vestibolare attivato dal movimento

Alcuni utenti riscontrano nausea o distrazioni per i contenuti animati. Ad esempio, le animazioni di scorrimento possono causare disturbi vestibolari quando elementi diversi dall'elemento principale associato allo scorrimento si muovono molto spesso. 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 al disturbo vestibolare (orecchio interno) includono vertigini, nausea ed emicrania e a volte richiedono il riposo a letto per riprendersi.

Rimuovi il movimento sui sistemi operativi

Molti sistemi operativi dispongono da molto tempo di impostazioni di accessibilità che consentono di specificare una preferenza per i movimenti ridotti. I seguenti screenshot mostrano la preferenza Riduci il movimento di macOS Mojave e la preferenza Rimuovi animazioni di Android Pie. Quando sono selezionate, queste preferenze fanno sì che il sistema operativo non utilizzi effetti decorativi come l'avvio di animazioni di app. Anche le applicazioni possono e devono rispettare questa impostazione e rimuovere tutte le animazioni non necessarie.

Uno screenshot della schermata delle impostazioni di macOS con la casella di controllo "Riduci il movimento" selezionata.
Uno screenshot della schermata delle impostazioni di Android in cui è selezionata la casella di controllo "Rimuovi le animazioni".

Rimuovi il movimento sul web

Il livello 5 delle query multimediali introduce anche sul web la preferenza dell'utente di movimento ridotto. Le query supporti consentono agli autori di testare ed eseguire query su valori o funzionalità dello user agent o del dispositivo di visualizzazione, indipendentemente dal documento visualizzato. La query supporti prefers-reduced-motion viene utilizzata per rilevare se l'utente ha impostato una preferenza di sistema operativo per ridurre al minimo la quantità di animazioni o animazioni che utilizza. Possono avere due valori possibili:

  • no-preference: indica che l'utente non ha espresso preferenze nel sistema operativo sottostante. Il valore di questa parola chiave viene valutato come false nel contesto booleano.
  • reduce: indica che l'utente ha impostato una preferenza di sistema operativo che indica che le interfacce devono ridurre al minimo i movimenti o l'animazione, preferibilmente al punto in cui vengono rimossi tutti i movimenti non essenziali.

Lavorare con la query multimediale da contesti CSS e JavaScript

Come per tutte le query supporti, è possibile verificare prefers-reduced-motion da un contesto CSS e da un contesto JavaScript.

Per illustrare entrambi, supponiamo di avere un importante pulsante di registrazione su cui voglio che l'utente faccia clic. Potrei definire un'animazione con vibrazione che catturi l'attenzione, ma come bravo cittadino del Web la riproduzione solo per quegli utenti che sono esplicitamente d'accordo con le animazioni e non per tutti gli altri, ad esempio utenti che hanno disattivato le animazioni o utenti di browser che non comprendono la query multimediale.

/*
  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 spiegare come utilizzare prefers-reduced-motion con JavaScript, immaginiamo di aver definito un'animazione complessa con l'API Web Animations. Mentre le regole CSS verranno attivate dinamicamente dal browser quando cambia la preferenza dell'utente, per le animazioni JavaScript devo ascoltare le modifiche manualmente e poi interrompere manualmente le mie animazioni potenziali in corso (o riavviarle, se l'utente 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 all'interno della query supporti effettiva sono obbligatorie:

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

Utilizzo della query multimediale da <picture> contesti

Un caso d'uso interessante è quello di far dipendere la riproduzione di un file AVIF, WebP o GIF animato dall'attributo media. Se (prefers-reduced-motion: no-preference) restituisce true, puoi 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>

Di seguito è riportato un esempio. Prova a modificare le preferenze di movimento del dispositivo per vedere la differenza.

Gatto Nyan

Scopri le preferenze dell'utente al momento della richiesta

L'intestazione del suggerimento del client Sec-CH-Prefers-Reduced-Motion consente ai siti di ottenere le preferenze di movimento dell'utente facoltativamente al momento della richiesta, consentendo ai server di incorporare il CSS corretto per motivi legati alle prestazioni.

Demo

Ho creato una piccola demo basata sui fantastici 🐈 gatti con stato HTTP di Rogério Vicente. Prima di tutto, prenditi un momento per apprezzare la battuta, è esilarante e ti aspetto. Ora che sei tornato, vediamo la demo. Quando scorri verso il basso, ogni gatto di stato HTTP viene visualizzato in alternativa dal lato destro o sinistro. È un'animazione fluida e fluida a 60 f/s ma, come descritto sopra, ad alcuni utenti potrebbe non piacere o addirittura soffrire di mal di movimento, quindi la demo è programmata per rispettare prefers-reduced-motion. Questo funziona anche in modo dinamico, quindi gli utenti possono modificare le preferenze all'istante, senza necessità di ricarica. Se l'utente preferisce la riduzione del movimento, le animazioni di rivelazione non necessarie non saranno più disponibili e rimarrà solo il regolare movimento di scorrimento. Lo screencast seguente mostra la demo in azione:

Video della demo dell'app prefers-reduced-motion

Conclusioni

Il rispetto delle preferenze dell'utente è 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 chiari o scuri. Puoi leggere tutto su prefers-color-scheme nel mio articolo Hello Darkness, My Old Friend 🌒.

Al momento il CSS Working Group sta standardizzando un maggior numero di query multimediali preferite dall'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).

(Bonus) Forzare la riduzione del movimento su tutti i siti web

Non tutti i siti utilizzeranno prefers-reduced-motion o forse non in modo sufficiente per i tuoi gusti. Se, per qualsiasi motivo, desideri 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 visitata. Esistono diverse estensioni del browser (utilizzabili a tuo rischio e pericolo) che consentono questa operazione.

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

Questo meccanismo è dovuto al fatto che il codice CSS riportato sopra sostituisce la durata di tutte le animazioni e le transizioni a un lasso di tempo così breve da non essere più percettibile. Poiché alcuni siti web dipendono da un'animazione da eseguire per poter funzionare correttamente (forse perché un determinato passaggio dipende dall'attivazione dell'evento animationend), l'approccio più radicale animation: none !important; non funzionerebbe. Anche l'attacco di cui sopra non è garantito che abbia successo su tutti i siti web (ad esempio, non è possibile interrompere il movimento avviato tramite l'API Web Animations), quindi assicurati di disattivarlo quando noti un malfunzionamento.

Ringraziamenti

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