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.