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

La query supporti prefers-reduced-motion rileva se l'utente ha richiesto al sistema operativo di ridurre al minimo la quantità di animazioni o movimenti utilizzati.

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

Supporto dei browser

  • 74
  • 79
  • 63
  • 10.1

Fonte

Troppo movimento nella vita reale e sul web

L'altro giorno pattinavo sul ghiaccio con i miei figli. Era una giornata bellissima, il sole splendeva e la pista di pattinaggio era piena di persone ⛸. L'unico problema: non gestisco bene le folle. Con così tanti bersagli in movimento, non mi concentrerò su nulla e mi perdo con la sensazione di un completo sovraccarico visivo, quasi come guardare un formichiere 🐜.

Tanti piedi di persone che pattinano sul ghiaccio.
Sovraccarico visivo nella vita reale.

Occasionalmente, lo stesso può succedere sul web: con annunci lampeggianti, effetti di parallasse fantasiosi, animazioni sorprendenti di rivelazione, video con riproduzione automatica e così via, il web a volte può essere piuttosto complesso... Per fortuna, a differenza del mondo reale, c'è una soluzione. La query supporti CSS prefers-reduced-motion consente agli sviluppatori di creare una variante di una pagina per gli utenti che, meglio, preferiscono un movimento ridotto. Ciò può includere l'assenza di video con riproduzione automatica, la disattivazione di alcuni effetti puramente decorativi o la 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 per "volare" in un carrello degli acquisti virtuale, rappresentato da un'icona nell'angolo in alto a destra del sito.

Un altro caso d'uso prevede l'uso del movimento per violare la percezione degli utenti, utilizzando una combinazione di scheletri, metadati contestuali e anteprime delle immagini di bassa qualità per occupare molto tempo all'utente e rendere l'intera esperienza più veloce. L'idea è dare contesto all'utente dei contenuti in arrivo e, allo stesso tempo, caricare i contenuti il più rapidamente possibile.

Infine, ci sono effetti decorativi come gradienti animati, scorrimento parallasse, video di sfondo e molti altri. Anche se a molti utenti piacciono queste animazioni, alcuni non le piacciono perché si sentono distratte o rallentate. Nel peggiore dei casi, gli utenti possono anche soffrire di mal d'auto come se fosse un'esperienza reale, quindi ridurre le animazioni per questi utenti è una necessità medica.

Disturbo dello spettro vestibolare causato dal movimento

Alcuni utenti provano distrazione o nausea a causa dei contenuti animati. Ad esempio, le animazioni a scorrimento possono causare disturbi vestibolari quando elementi diversi dall'elemento principale associati allo scorrimento si muovono 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 dei disturbi vestibolari (orecchio interno) includono vertigini, nausea ed emicrania e talvolta richiedono il riposo a letto per recuperare.

Rimuovi movimento sui sistemi operativi

Molti sistemi operativi avevano impostazioni di accessibilità per specificare una preferenza per il movimento ridotto per un lungo periodo. Gli screenshot di seguito mostrano la preferenza Riduci movimento di macOS Mojave e quella di Rimuovi le 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 possono e devono rispettare questa impostazione e rimuovere tutte le animazioni non necessarie.

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

Rimuovi movimento sul web

Media Queries Level 5 porta anche sul web le preferenze dell'utente con movimento ridotto. Le query supporti consentono agli autori di testare ed eseguire query su valori o funzionalità dello user agent o di visualizzazione del dispositivo indipendentemente dal documento sottoposto a rendering. La query supporti prefers-reduced-motion viene utilizzata per rilevare se l'utente ha impostato una preferenza del sistema operativo per ridurre al minimo la quantità di animazioni o movimenti utilizzati. Può assumere due valori possibili:

  • no-preference: indica che l'utente non ha effettuato alcuna preferenza nel sistema operativo sottostante. Questo valore della parola chiave restituisce 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 il movimento o l'animazione, preferibilmente fino al punto in cui tutti i movimenti non essenziali vengono rimossi.

Lavorare con la query supporti da contesti CSS e JavaScript

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

Per illustrare entrambi i casi, supponiamo di avere un importante pulsante di registrazione su cui voglio che l'utente faccia clic. Potrei definire un'animazione "vibrata" che catturi l'attenzione, ma da buon cittadino del web la userò solo per gli utenti che sono esplicitamente a posto con le animazioni, ma non per tutti gli altri, che possono essere utenti che hanno disattivato le animazioni o utenti di browser che non comprendono la query sui contenuti multimediali.

/*
  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 lavorare con prefers-reduced-motion in JavaScript, supponiamo di aver definito un'animazione complessa con l'API Web Animations. Sebbene le regole CSS vengano attivate dinamicamente dal browser quando le preferenze dell'utente cambiano, per le animazioni JavaScript devo ascoltare personalmente le modifiche e quindi interrompere manualmente le animazioni potenzialmente in corso (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 intorno all'effettiva query supporti sono obbligatorie:

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

Utilizzo della query supporti da <picture> contesti

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

Di seguito sono riportati alcuni esempi. Prova ad attivare/disattivare le preferenze di movimento del dispositivo per vedere la differenza.

Gatto Nyan

Scoprire le preferenze dell'utente al momento della richiesta

L'intestazione del suggerimento 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 incorporare il CSS corretto per motivi legati alle prestazioni.

Demo

Ho creato una piccola demo basata sui 🐈 HTTP status cats di Rogério Vicente. Per prima cosa, dedica un momento ad apprezzare la barzelletta, è esilarante e aspetto. Ora che torniamo, vediamo le demo. Scorrendo verso il basso, ogni cat di stato HTTP viene visualizzato alternatamente dal lato destro o sinistro. È un'animazione fluida a 60 FPS ma, come spiegato in precedenza, alcuni utenti potrebbero non apprezzarla o persino ammalarsi dai movimenti, quindi la demo è programmata in modo da rispettare prefers-reduced-motion. Questa funzionalità è anche dinamica, quindi gli utenti possono modificare la preferenza all'istante, senza dover ricaricare la pagina. Se un utente preferisce un movimento ridotto, le animazioni non necessarie vengono rimosse e viene lasciato solo il normale movimento di scorrimento. Lo screencast di seguito mostra la demo in azione:

Video dell'app prefers-reduced-motion app

Conclusioni

Rispettare le 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 leggere tutto su prefers-color-scheme nel mio articolo Hello Darkness, My Old Friend 🌒.

Il CSS Working Group sta attualmente standardizzando più query supporti con preferenze degli utenti 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 colori adiacenti) e inverted-colors (rileva se l'utente preferisce colori invertiti).

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

Non tutti i siti utilizzeranno prefers-reduced-motion, o forse non abbastanza per i tuoi gusti. Se, per qualsiasi motivo, vuoi interrompere il movimento su tutti i siti web, in realtà puoi farlo. Un modo per far sì che ciò avvenga è inserire un foglio di stile con il seguente CSS in ogni pagina web che visiti. Sono disponibili diverse estensioni del browser (utilizzale a tuo rischio!) 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;
  }
}

In questo modo, il codice CSS riportato sopra sostituisce le durate di tutte le animazioni e le transizioni a un intervallo di tempo così breve da non essere più visibili. Poiché alcuni siti web dipendono dall'esecuzione di un'animazione per funzionare correttamente (probabilmente perché un determinato passaggio dipende dall'attivazione dell' evento animationend), l'approccio più radicale di animation: none !important; non funzionerebbe. Anche la compromissione di cui sopra non è garantita per avere successo su tutti i siti web (ad esempio, non può interrompere il movimento avviato tramite l'API Web Animations), quindi assicurati di disattivarlo quando noti un'interruzione.

Ringraziamenti

Un ringraziamento speciale 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.