Accessibilità
Autoplay e prefers-reduced-motion
Un autoplay oltre cinque secondi viola il criterio 2.2.2 senza un controllo di pausa; prefers-reduced-motion aggiunge la preferenza dell'utente, in CSS e in JavaScript.
In sintesi
- Il criterio 2.2.2 (livello A) chiede un controllo di pausa per ogni contenuto che si muove da solo per più di cinque secondi.
- La media query prefers-reduced-motion spegne solo le animazioni CSS: i timer JavaScript continuano a girare.
- Le pagine con caroselli JavaScript hanno più errori della media, ma il dato è una correlazione, non una causa.
Un video o un carosello che parte da solo e si muove per più di cinque secondi viola il criterio 2.2.2 (livello A), a meno che l'utente possa fermarlo. La difesa è doppia: un controllo di pausa visibile e una media query prefers-reduced-motion che rispetta chi ha chiesto meno movimento.
Cosa chiede il criterio 2.2.2
Il criterio copre ogni informazione che si muove, lampeggia o scorre da sola, dura più di cinque secondi e sta accanto ad altro contenuto: serve un meccanismo per metterla in pausa, fermarla o nasconderla. L'audio che parte da solo e dura più di tre secondi ricade invece nel criterio 1.4.2: serve un controllo di volume o di stop, separato da quello di sistema. WCAG 2.2 è una W3C Recommendation del 5 ottobre 2023, pubblicata con W3C Document License.
La media query spegne solo il CSS
Questa regola è il punto di partenza, non la soluzione: azzera durate e iterazioni, così un'animazione non parte nemmeno una volta. Attenzione a animation-delay: senza azzerarlo, un elemento può restare invisibile perché l'animazione è in attesa.
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
animation-duration: 0.01ms !important;
animation-delay: 0s !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
scroll-behavior: auto !important;
}
}
Un carosello guidato da setInterval continua a girare: il CSS non lo vede. La stessa preferenza si legge in JavaScript con matchMedia e si ascolta con l'evento change, così l'utente che cambia impostazione a pagina aperta non deve ricaricare.
const motion = window.matchMedia('(prefers-reduced-motion: reduce)');
let timer = null;
function sync() {
if (timer) clearInterval(timer);
timer = null;
if (motion.matches) return; // no rotation, the list stays still
timer = setInterval(nextSlide, 6000);
}
motion.addEventListener('change', sync);
sync();
Video: la parte che nessun CSS copre
Un video con autoplay e audio parte comunque, qualunque sia la preferenza. Togli l'autoplay, oppure parti muto con muted e playsinline, aggiungi un bottone di pausa sempre visibile e non far ripartire la riproduzione quando il puntatore esce. Il controllo deve stare nel DOM, non solo nell'interfaccia nativa del browser.
Il carosello che regge
- Pausa sempre visibile: non solo al passaggio del puntatore, perché chi naviga da tastiera non ci passa sopra.
- Stop al focus: quando il focus entra nel carosello, la rotazione si ferma e non riparte da sola finché il focus resta dentro.
- Lista statica se il contenuto è informativo: tre schede in una griglia si leggono in un colpo, un carosello le nasconde.
- Nessun annuncio continuo: una regione live su un carosello automatico interrompe il lettore di schermo ogni pochi secondi.
Il catalogo EneUI
EneUI indicizza i componenti della categoria animazione e i blocchi hero, dove gli autoplay compaiono più spesso. Un record verificato è 3d carousel di Cult UI, licenza MIT dichiarata a monte: il movimento è nel componente, quindi va gated con la preferenza invece di essere tolto a mano. Controllo eseguito il 1 novembre 2026 sul catalogo da 111.985 componenti.
La limitazione
La media query riflette un'impostazione di sistema che molte persone non sanno di avere, e non copre video, canvas o animazioni dentro un iframe di terze parti. Non è un interruttore di accessibilità: è un segnale che va ascoltato insieme al controllo di pausa. E l'emulazione in DevTools verifica il CSS, non il comportamento dei timer.
Dove continuare
Il pattern del carosello con scroll snap è in caroselli con CSS scroll snap; le classi di movimento in Tailwind, con le varianti per la preferenza, sono in animazioni in Tailwind. Il confronto fra le librerie di animazione, con licenze e peso, è in migliori librerie di animazione.
Domande frequenti
Quanto deve durare un'animazione per violare 2.2.2?
Più di cinque secondi, se parte da sola e convive con altro contenuto. Sotto quella soglia il criterio non si applica, ma la preferenza dell'utente resta valida.
prefers-reduced-motion ferma anche i video?
No. La media query riguarda il CSS. Un video con autoplay continua: serve togliere l'attributo autoplay o aggiungere un controllo di pausa visibile.
Devo togliere tutte le animazioni?
No. Riduci il movimento, non l'interfaccia: transizioni brevi, nessun movimento ampio, nessun parallasse. Il contenuto e lo stato devono restare leggibili.
I caroselli automatici sono sempre sbagliati?
No, ma un carosello informativo è meglio come lista statica. Se resta automatico, aggiungi pausa sempre visibile, stop al focus e nessun cambio sotto il puntatore.
Come testo la preferenza senza cambiare le impostazioni di sistema?
Con l'emulazione in DevTools: Rendering, Emulate CSS media feature prefers-reduced-motion. Copre il CSS, non i timer JavaScript.