Accessibilita Web — Cheat Sheet

Tag: a11y, accessibility, wcag, aria, html, frontend

Livello: intermedio

TL;DR: Principi WCAG (POUR), semantica HTML nativa, navigazione da tastiera e pattern ARIA per garantire accessibilita e superare audit tecnici.

Concetti chiave

I quattro principi WCAG (POUR): Percepibile, Operabile, Comprensibile, Robusto.

Livelli di conformita WCAG: A (minimo), AA (standard di settore), AAA (massimo).

La semantica HTML nativa batte sempre ARIA: prima usa tag nativi, poi aggiungi attributi ARIA solo se necessario.

Contrasto colore minimo standard WCAG AA: 4.5:1 per testo normale, 3:1 per testo grande o elementi UI essenziali.

Focus management obbligatorio: tutti gli elementi interattivi devono essere raggiungibili e azionabili solo da tastiera.

Focus outline visibile: mai rimuovere outline: none senza fornire un indicatore di focus alternativo evidente.

Struttura dei landmark semantici: header, nav, main, aside, footer facilitano il salto rapido da screen reader.

Gerarchia degli heading ordinata: usare un solo h1 e non saltare livelli logici (es. da h2 a h4).

Immagini informative richiedono alt descrittivo; immagini puramente decorative richiedono alt="" esplicito per essere ignorate.

Messaggi di errore e aggiornamenti dinamici richiedono aria-live (polite o assertive) per la lettura vocale.

Domande tipiche e risposte pronte

Q: Come affronti l'accessibilita nello sviluppo di un'applicazione web complessa?

R: Integro l'accessibilita fin dal design, rispettando lo standard WCAG AA. Parto da HTML semantico, verifico la navigabilita completa da tastiera, gestisco il trap del focus nei modali e automatizzo controlli con axe-core in CI.

Q: Quando e come utilizzi gli attributi ARIA?

R: Seguo la prima regola di ARIA: non usare ARIA se esiste un elemento HTML nativo con lo stesso ruolo e comportamento. Uso ARIA solo per componenti custom (es. combobox, dialog) per esporre ruoli, stati e proprieta agli screen reader.

Q: Come gestisci il focus all'apertura e chiusura di un modal?

R: All'apertura sposto il focus sul primo elemento interattivo o sul contenitore del modal e intrappolo il focus all'interno con un focus trap. Alla chiusura, ripristino il focus esattamente sull'elemento scatenante che ha aperto il modal.

Q: Qual e la differenza tra aria-hidden="true" e la classe CSS visually-hidden (o sr-only)?

R: aria-hidden="true" nasconde un elemento agli screen reader lasciandolo visibile a schermo, utile per icone decorative. visually-hidden nasconde un elemento a schermo mantenendolo leggibile dagli screen reader, utile per label testuali aggiuntive.

Insidie e errori comuni

Creare bottoni con <div onClick={...}> invece di <button>: si perde il focus da tastiera e la gestione di Enter/Space.

Rimuovere il focus ring globale con outline: none o outline: 0 senza un sostituto visibile accessibile.

Saltare gerarchie di heading (h1 seguito da h3), compromettendo l'indice di lettura dello screen reader.

Omettere l'attributo alt su <img>: lo screen reader legge l'URL del file anziche saltarlo o descriverlo.

Associare label e input solo visivamente senza usare for/id o aria-labelledby.

Usare solo il colore per indicare stato o errore (es. bordo rosso senza icona o testo di spiegazione).

Abusare di aria-live="assertive", interrompendo inutilmente l'output vocale continuo dell'utente.

Dimenticare di chiudere il focus trap nei menu a tendina o modali alla pressione del tasto Escape.

Snippet e comandi

<!-- Skip link per saltare la navigazione -->
<a href="#main-content" class="skip-link">Salta al contenuto principale</a>

<!-- Classe visivamente nascosta ma leggibile da screen reader -->
<style>
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}
</style>
// Pattern pulsante toggle accessibile con ARIA
interface ToggleButtonProps {
  isExpanded: boolean;
  controlsId: string;
  onToggle: () => void;
  label: string;
}

export function ToggleButton({ isExpanded, controlsId, onToggle, label }: ToggleButtonProps) {
  return (
    <button
      type="button"
      aria-expanded={isExpanded}
      aria-controls={controlsId}
      onClick={onToggle}
    >
      {label}
    </button>
  );
}
# Audit da riga di comando con Axe CLI o Lighthouse
npx axe-cli https://localhost:3000
npx lighthouse https://localhost:3000 --only-categories=accessibility --view

Da ripassare

[ ] Implementazione e test di un focus trap completo per modali (Tab, Shift+Tab, Escape)

[ ] Regole di contrasto WCAG 2.1 e 2.2 (text vs non-text contrast)

[ ] Pattern ARIA Authoring Practices Guide (APG) per menu, tabs e combobox

[ ] Differenza d'uso tra role="status" e role="alert"

[x] Ruoli dei tag semantici HTML5 nativi vs role generici

[x] Gestione di alt descrittivo vs alt="" decorativo

Riferimenti

W3C Web Content Accessibility Guidelines (WCAG) 2.1 / 2.2

WAI-ARIA Authoring Practices Guide (APG)

Deque axe-core Documentation

MDN Web Docs: Accessibility (a11y)

Modifica direttamente o con Gemini Fai clic in un punto qualsiasi per digitare e modificare direttamente oppure seleziona il testo per chiedere a Gemini di apportare modifiche.

Il file markdown accessibilita-web-cheat-sheet.md è stato generato rispettando rigorosamente la struttura del master prompt. Vuoi approfondire o aggiungere altri snippet tecnici specifici (es. implementazione React di un focus trap)?

Jarvis Interviews
Jarvis