La media query 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 animazioni o le transizioni decorative e alcuni utenti soffrono di cinetosi quando si trovano di fronte a scorrimento parallasse, effetti di zoom e altro ancora. La query media
delle preferenze dell'utente prefers-reduced-motion ti consente di progettare una variante del tuo sito con movimento ridotto per gli utenti che
hanno espresso questa preferenza.
Troppo movimento nella vita reale e sul web
L'altro giorno pattinavo sul ghiaccio con i miei figli. Era una bella giornata, il sole splendeva e la pista di pattinaggio era piena di gente ⛸. L'unico problema è che non sopporto la folla. Con così tanti obiettivi in movimento, non riesco a concentrarmi su nulla e mi ritrovo perso e con una sensazione di sovraccarico visivo completo, quasi come fissare un formicaio 🐜.
A volte può succedere la stessa cosa sul web: con annunci lampeggianti, effetti di parallasse particolari, animazioni a sorpresa, video in riproduzione automatica e altro ancora, il web a volte può essere piuttosto opprimente…
Fortunatamente, a differenza della vita reale, esiste una soluzione. La media query 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, dal non riprodurre automaticamente i video alla disattivazione di determinati effetti puramente decorativi, fino alla riprogettazione completa di una pagina per determinati utenti.
Prima di entrare nel dettaglio della funzionalità, facciamo un passo indietro e pensiamo a cosa servono le animazioni sul web. Se vuoi, puoi anche saltare le informazioni di base e passare direttamente ai dettagli tecnici.
Animazione sul web
L'animazione viene spesso utilizzata per fornire feedback all'utente, ad esempio per comunicare 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 virtuale, raffigurato 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 utilizzando una combinazione di schermate scheletriche, metadati contestuali e anteprime di immagini di bassa qualità per occupare gran parte del tempo dell'utente e rendere l'intera esperienza più veloce. L'idea è di dare un contesto all'utente di ciò che sta per arrivare e nel frattempo caricare le cose il più rapidamente possibile.
Infine, ci sono effetti decorativi come gradienti animati, scorrimento parallasse, video di sfondo e molti altri. Anche se molti utenti apprezzano queste animazioni, alcuni non le gradiscono perché si sentono distratti o rallentati. Nel peggiore dei casi, gli utenti potrebbero persino soffrire di mal d'auto come se fosse un'esperienza reale, quindi per questi utenti la riduzione delle animazioni è una necessità medica.
Disturbo dello spettro vestibolare scatenato dal movimento
Alcuni utenti provano distrazione o nausea a causa dei contenuti animati. Ad esempio, le animazioni di scorrimento possono causare disturbi vestibolari quando gli elementi diversi da quello principale associato allo scorrimento si muovono molto. Ad esempio, le animazioni di 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 ai disturbi vestibolari (orecchio interno) includono vertigini, nausea ed emicrania e a volte richiedono riposo a letto per recuperare.
Rimuovere il movimento sui sistemi operativi
Molti sistemi operativi dispongono da tempo di impostazioni di accessibilità per specificare una preferenza per la riduzione del movimento. Gli screenshot seguenti mostrano la preferenza Riduci movimento di macOS Mojave e la preferenza Rimuovi animazioni di Android Pie. Se selezionate, queste preferenze fanno sì che il sistema operativo non utilizzi 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.
Rimuovere il movimento sul web
Media Queries Level 5 porta anche sul web la preferenza utente
per il movimento ridotto. Le media query consentono agli autori di testare ed eseguire query su valori o funzionalità
dell'user agent o del dispositivo di visualizzazione indipendentemente dal documento di cui viene eseguito il rendering. La media query
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 utilizzato. Può assumere due valori possibili:
no-preference: indica che l'utente non ha espresso alcuna preferenza nel sistema operativo sottostante. Questo valore della parola chiave viene valutato comefalsenel contesto booleano.reduce: indica che l'utente ha impostato una preferenza del sistema operativo che indica che le interfacce devono ridurre al minimo il movimento o l'animazione, preferibilmente al punto in cui tutti i movimenti non essenziali vengono rimossi.
Utilizzo della media query dai contesti CSS e JavaScript
Come per tutte le query supporti, prefers-reduced-motion può essere controllato 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 "vibrazione" che attira l'attenzione, ma in quanto buon cittadino del web la riprodurrò solo per gli utenti che hanno esplicitamente acconsentito alle animazioni, ma non per tutti gli altri, ovvero gli utenti che hanno disattivato le animazioni o gli utenti che utilizzano browser che non comprendono la media query.
/*
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 Web Animations. Mentre le regole CSS
vengono attivate dinamicamente dal browser quando le preferenze dell'utente cambiano, per le animazioni JavaScript
devo rilevare personalmente le modifiche e poi 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 alla query supporti effettiva sono obbligatorie:
window.matchMedia('prefers-reduced-motion: reduce');
window.matchMedia('(prefers-reduced-motion: reduce)');
Utilizzo della media query da <picture> contesti
Un caso d'uso interessante è quello di rendere la riproduzione di un AVIF, WebP o GIF animato dipendente dall'attributo
media. Se (prefers-reduced-motion: no-preference) restituisce true, è sicuro
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 che segue. Prova ad attivare/disattivare le preferenze di movimento del dispositivo per notare la differenza.
Scoprire le preferenze dell'utente al momento della richiesta
L'intestazione dell'hint 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 di rendimento.
Demo
Ho creato una piccola demo basata sulle fantastiche 🐈 HTTP Status Cats di Rogério Vicente. Innanzitutto, prenditi un momento per apprezzare la battuta, è
esilarante e aspetterò. Ora che sei tornato, ti presento la
demo. Quando scorri, ogni categoria di stato HTTP
viene visualizzata alternativamente dal lato destro o sinistro. Si tratta di un'animazione a 60 FPS
fluida, ma come accennato in precedenza, alcuni utenti potrebbero non apprezzarla o addirittura soffrire di cinetosi, quindi la
demo è programmata per rispettare prefers-reduced-motion. Funziona anche in modo dinamico, quindi gli utenti possono
modificare le proprie preferenze al volo, senza ricaricare la pagina. Se un utente preferisce un movimento ridotto, le
animazioni di visualizzazione non necessarie vengono rimosse e rimane solo il movimento di scorrimento normale. Il
seguente screencast mostra la demo in azione:
prefers-reduced-motion demo
app
Conclusioni
Il rispetto delle preferenze degli utenti è fondamentale per i siti web moderni e i browser espongono 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 standardizzando altre
query dei media delle 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 colori adiacenti)
e inverted-colors (rileva se l'utente
preferisce i colori invertiti).
(Bonus) Forzare il movimento ridotto su tutti i siti web
Non tutti i siti utilizzano prefers-reduced-motion o forse non in modo significativo 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 tuo rischio e pericolo) che lo consentono.
@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 esegue l'override delle durate di tutte le animazioni e transizioni
in modo che siano così brevi da non essere più visibili. Poiché alcuni siti web dipendono dall'esecuzione di un'animazione
per funzionare correttamente (forse perché un determinato passaggio dipende dall'attivazione dell'evento
animationend),
l'approccio più radicale animation: none !important; non funzionerebbe. Anche l'hack precedente non
garantisce la riuscita 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.
Risorse
- Ultima bozza dell'editor delle Media Queries di livello 5.
prefers-reduced-motionsu Stato della piattaforma Chrome.prefers-reduced-motionBug di Chromium.- Blink Intent to Implement posting.
Ringraziamenti
Un ringraziamento speciale a Stephen McGruer, che ha implementato
prefers-reduced-motion in Chrome e, insieme a
Rob Dodson, ha anche esaminato questo documento.