# Checklist tecnica WCAG 2.1 AA

> La checklist di accessibilità da verificare su ogni sito soggetto all'EAA, dai landmark al contrasto alla navigazione da tastiera, con i criteri WCAG di riferimento.

<!-- Fonte: https://sitoanorma.it/docs/accessibilita/checklist -->
<!-- Aggiornato: 2026-08-15 -->

Lo standard di riferimento è **WCAG 2.1 livello AA** (EN 301 549). Questa è la checklist tecnica da applicare a un sito soggetto all'[obbligo EAA](/docs/accessibilita/chi-e-obbligato), con il criterio WCAG corrispondente.

## Struttura e semantica

- [ ] HTML semantico: `<header>`, `<nav>`, `<main>`, `<footer>`, un solo `<main>` per pagina *(1.3.1)*
- [ ] Un solo `<h1>` per pagina, gerarchia dei titoli senza salti di livello *(1.3.1, 2.4.6)*
- [ ] `lang` dichiarato su `<html>`, e su porzioni in lingua diversa *(3.1.1, 3.1.2)*
- [ ] `<title>` univoco e descrittivo per ogni pagina *(2.4.2)*
- [ ] `aria-label` sui `<nav>` multipli, per distinguerli *(1.3.1)*
- [ ] Tabelle dati con `<th scope>` e `<caption>` *(1.3.1)*

## Percezione

- [ ] Contrasto testo ≥ **4.5:1**; ≥ **3:1** per testo grande (≥ 24px, o ≥ 19px bold) *(1.4.3)*
- [ ] Contrasto ≥ **3:1** per componenti UI e bordi di campi form *(1.4.11)*
- [ ] L'informazione non è veicolata **dal solo colore** *(1.4.1)*
- [ ] Zoom fino al **200%** senza perdita di contenuto o funzionalità *(1.4.4)*
- [ ] Reflow a **320px** di larghezza senza scroll orizzontale *(1.4.10)*
- [ ] Testo alternativo corretto sulle [immagini](/docs/accessibilita/immagini) *(1.1.1)*
- [ ] Nessun testo importante annegato in un'immagine *(1.4.5)*

## Interazione da tastiera

- [ ] Tutto raggiungibile e azionabile **da tastiera**, ordine di tabulazione logico *(2.1.1, 2.4.3)*
- [ ] Nessuna **trappola di focus**: si entra e si esce da ogni componente *(2.1.2)*
- [ ] **Focus visibile** e con contrasto sufficiente su ogni elemento interattivo *(2.4.7)*
- [ ] **Skip-link** al contenuto principale come primo elemento focusabile *(2.4.1)*
- [ ] Target di click di dimensione ragionevole, non adiacenti a filo *(2.5.5 AAA, buona prassi)*

## Form

- [ ] `<label>` associata a ogni campo via `for`/`id`: il placeholder **non** è un'etichetta *(1.3.1, 3.3.2)*
- [ ] Errori identificati **in testo**, non solo con il colore del bordo *(3.3.1)*
- [ ] Messaggi di errore associati al campo (`aria-describedby`) e annunciati *(3.3.1, 4.1.3)*
- [ ] Suggerimenti per correggere l'errore, dove è possibile fornirli *(3.3.3)*
- [ ] `autocomplete` corretto sui campi che raccolgono dati dell'utente *(1.3.5)*
- [ ] Campi correlati raggruppati in `<fieldset>` con `<legend>` *(1.3.1)*

## Movimento e media

- [ ] Rispetto di `prefers-reduced-motion` *(2.3.3 AAA, buona prassi)*
- [ ] Niente contenuti che lampeggiano più di 3 volte al secondo *(2.3.1)*
- [ ] Carousel e animazioni automatiche: possibilità di metterle in pausa *(2.2.2)*
- [ ] Sottotitoli per i video con audio parlato *(1.2.2)*
- [ ] Audiodescrizione o alternativa testuale per i contenuti video *(1.2.3, 1.2.5)*

## Contenuti dinamici

- [ ] Aggiornamenti importanti annunciati via `aria-live` *(4.1.3)*
- [ ] Modali: focus spostato all'apertura, intrappolato, restituito alla chiusura *(2.4.3)*
- [ ] Nessun cambio di contesto automatico al focus o all'input *(3.2.1, 3.2.2)*
- [ ] Il **banner cookie** rispetta tutti i criteri sopra: è il componente più spesso escluso dai test

## Come verificare

Nessuno strumento automatico copre più di una parte dei criteri. Serve una combinazione:

| Strumento | Cosa copre |
|-----------|-----------|
| **axe DevTools** / **WAVE** | Errori automatizzabili (contrasti, alt, label, ARIA) |
| **Lighthouse** | Sottoinsieme di axe, comodo in CI |
| Navigazione **solo da tastiera** | Ordine, focus, trappole (non automatizzabile) |
| **Screen reader** (NVDA, VoiceOver) | Come viene realmente annunciata la pagina |
| **Zoom 200% e viewport 320px** | Reflow e perdita di contenuto |

> Gli strumenti automatici intercettano indicativamente un terzo dei problemi reali. Il test da tastiera è quello che dà il maggior risultato per il tempo speso: se non riesci a completare un acquisto senza mouse, nessun report automatico verde ha valore.

## In continuo, non una volta sola

L'accessibilità si perde a ogni rilascio. Conviene:

- inserire un controllo automatico (axe) nella pipeline di CI;
- fare il test da tastiera sulle pagine chiave prima di ogni rilascio importante;
- rivedere la [dichiarazione di accessibilità](/docs/pagine-legali/accessibilita) quando il sito cambia in modo sostanziale.
