Test accessibilità

Pagina di test per verificare il comportamento dell’accessibility tree e dei tool di verifica automatica sui web component Dev Kit Italia.

Contesto e scopo

Questa pagina fa parte di un’analisi esplorativa sulla verificabilità dell’accessibilità dei siti che usano Dev Kit Italia. I componenti <it-*> usano shadow DOM per incapsulare markup e stili, e slot per ricevere contenuto dal light DOM. Questo approccio funziona bene con screen reader e browser moderni, ma mette in difficoltà diversi tool di verifica automatica.

La pagina raccoglie casi di test pensati per forzare errori controllati e confrontare come diversi tool (axe-core, Siteimprove, ARC Toolkit, WAVE, pa11y, MAUVE++) li rilevano o non li rilevano.

Gli errori in questa pagina sono intenzionali — servono a misurare la copertura dei tool, non a suggerire pattern d’uso dei componenti.

Cosa questa pagina non è

Questa pagina non valuta l’accessibilità di Dev Kit Italia. I componenti sono stati sviluppati seguendo le migliori pratiche WAI-ARIA e verificati durante lo sviluppo con controlli estesi:

L’obiettivo di questa pagina è diverso: verificare come gli strumenti di verifica automatica rilevano eventuali errori d’uso quando i componenti vengono applicati in un sito reale (slot non popolati, contrasti forzati, ARIA cross-scope, gerarchie heading miste). Questi errori dipendono da come il dev usa i componenti, non dai componenti stessi.

Come leggere la pagina

Ogni sezione include un 🔴 errore intenzionale su un web component Dev Kit e lo stesso errore su HTML classico come controllo. Se il tool segnala entrambi, e riconosce anche i casi 🟢 controllo, è possibile dedurre che stia verificando dentro il shadow DOM, salvo verificare in ogni caso i risultati.

Legenda:

Test con pa11y da CLI

La pagina è direttamente testabile ad esempio con pa11y:

bashEngine HTML_CodeSniffer (default) npx pa11y https://italia.github.io/design-jekyll-devkit-theme/test-a11y/ --standard WCAG2AA --runner axe


A. Slot vuoti — elementi semantici fantasma

Quando uno slot obbligatorio non viene popolato, il componente Dev Kit genera comunque l’elemento semantico nel shadow DOM (heading, label, button), producendo un nodo accessibile con nome vuoto. Dev Kit segnala il problema in console ma il DOM non reagisce.

Card

Card completa (🟢 controllo ok)

Titolo card presente Testo card di esempio.

Card senza slot title (🔴 errore intenzionale)

Testo presente ma nessun titolo.

Card completamente vuota (🔴 errore intenzionale)

Card senza slot title con immagine (🔴 errore intenzionale)

Placeholder
Card con immagine ma senza titolo.

Card con slot title vuoto (🔴 errore intenzionale)

Testo presente ma title vuoto.

Card full-height senza title (🔴 errore intenzionale)

Full height senza titolo.

Accordion

Accordion completo (🟢 controllo ok)

Heading presente
Contenuto presente.

Accordion senza slot heading (🔴 errore intenzionale)

Contenuto senza heading.

Accordion item vuoto (🔴 errore intenzionale)

Input

Input con label (🟢 controllo ok)

Campo di testo

Input senza label (🔴 errore intenzionale)

Button

Button con testo (🟢 controllo ok)

Testo del pulsante

Button senza testo (🔴 errore intenzionale)

Callout

Callout completo (🟢 controllo ok)

Titolo callout

Testo del callout di esempio.

Callout senza slot title (🔴 errore intenzionale)

Testo del callout senza titolo.

Apri modale completa Titolo modale Descrizione della modale

Contenuto della modale.

Conferma
Apri modale senza header

Contenuto senza titolo.

Azione 1 Azione 2 Azione 1

Select

Select con label (🟢 controllo ok)

Etichetta

Select senza label (🔴 errore intenzionale)

Checkbox

Checkbox con label (🟢 controllo ok)

Checkbox di esempio

Checkbox senza label (🔴 errore intenzionale)

Radio button

Radio group completo (🟢 controllo ok)

Gruppo radio Radio 1 Radio 2

Radio group senza label (🔴 errore intenzionale)

Home Voce corrente

Chip

Chip con label (🟢 controllo ok)

Chip senza label (🔴 errore intenzionale)

Hero

Hero con contenuto (🟢 controllo ok)

Immagine hero

Hero vuoto (🔴 errore intenzionale)


B. Contrasto colori nel shadow DOM

Verifica se i tool calcolano il contrasto sui testi renderizzati nel shadow DOM dei componenti, confrontando lo stesso errore applicato in due modi diversi:

La seconda forma è il vero banco di prova — un tool che non entra nel shadow DOM non può calcolare il contrasto corretto.

Card Dev Kit con contrasto 🔴 errato (via style sugli slot)

Titolo con contrasto insufficiente Testo con contrasto insufficiente — grigio chiaro su bianco (#aaa su #fff = ratio 2.32:1).

HTML classico con stesso contrasto 🔴 errato (controllo)

Titolo con contrasto insufficiente

Testo con contrasto insufficiente — grigio chiaro su bianco (#aaa su #fff = ratio 2.32:1).

Card Dev Kit con contrasto corretto (🟢 controllo ok)

Titolo con contrasto corretto Testo con contrasto corretto — colori default.

Callout con testo su sfondo colorato

Callout warning

Testo su sfondo colorato — il contrasto è verificato dai tool?

Chip varianti colore

B. Contrasto colori test con parts

Verifica se i tool calcolano il contrasto sui testi renderizzati nel shadow DOM. Il test usa il selettore ::part() per forzare un colore a basso contrasto sugli elementi dentro il shadow DOM dei web component.

Card Dev Kit con contrasto 🔴 errato (via ::part nel shadow DOM)

Titolo con contrasto insufficiente Testo con contrasto insufficiente nel shadow DOM (#aaa su #fff = ratio 2.32:1).

HTML classico con stesso contrasto 🔴 errato (controllo)

Titolo con contrasto insufficiente

Testo con contrasto insufficiente — grigio chiaro su bianco (#aaa su #fff = ratio 2.32:1).

Card Dev Kit con contrasto corretto (🟢 controllo ok)

Titolo con contrasto corretto Testo con contrasto corretto — colori default.

Button Dev Kit con contrasto 🔴 errato (via ::part nel shadow DOM)

Testo button con contrasto insufficiente

Button HTML classico con stesso contrasto 🔴 errato (controllo)


C. Form association cross-shadow-root

Verifica se un <form> nel light DOM riceve i valori degli input Dev Kit (che hanno l’<input> reale dentro il shadow DOM). Per gli utenti, è la differenza tra “il form funziona” e “il form invia dati vuoti”.

Compilare i campi e cliccare “Invia form” — se il riquadro mostra i dati, la form association funziona.

Form Dev Kit dentro form nativo

Nome Email Ruolo Accetto la privacy policy
Invia form
Clicca "Invia form" per verificare i dati ricevuti dal form nativo.

Form HTML classico (🟢 controllo)

Clicca "Invia form classico" per verificare i dati.

D. ARIA relationships cross-shadow-root

Per spec W3C, aria-describedby e aria-labelledby non funzionano attraverso i confini del shadow DOM: un ID nel light DOM non è risolvibile da un elemento nel shadow DOM.

Dev Kit espone it-aria-describedby e it-aria-labelledby che vengono applicati all’input generato nel shadow DOM. Il test verifica se il riferimento cross-shadow-root funziona in pratica.

Risultato atteso: non funziona (verificato con VoiceOver). Dev Kit fornisce alternative interne (support-text, validity-message) per i casi d’uso standard.

Input Dev Kit con aria-describedby che punta a ID esterno (🔴 errore atteso)

Questa descrizione è nel light DOM, fuori dal web component.

Campo con aria-describedby esterno

Input HTML classico con aria-describedby (🟢 controllo — deve funzionare)

Questa descrizione è nel light DOM.

Input Dev Kit con aria-labelledby che punta a ID esterno (🔴 errore atteso)

Etichetta esterna nel light DOM

Campo con aria-labelledby esterno (dovrebbe usare l'etichetta esterna)

Input HTML classico con aria-labelledby (🟢 controllo — deve funzionare)

Etichetta esterna nel light DOM


E. Focus management

Verifica l’ordine di tabulazione attraverso shadow DOM boundaries.

Posizionarsi sul link “1. Link nativo” e premere Tab ripetutamente. L’ordine atteso è 1→2→3→4→5→6. Shift+Tab per l’ordine inverso.

1. Link nativo (inizio sequenza) 2. Input Dev Kit 4. Accordion Dev Kit 6. Button Dev Kit (fine sequenza)

F. Modal: focus trap e ARIA

Verifica che la modal intrappoli il focus e che gli attributi ARIA siano impostati correttamente.

Aprire la modal, premere Tab ripetutamente — il focus deve ciclare solo tra gli elementi interni. Premere Escape — la modal si chiude e il focus torna sul trigger.

Aprire la modal, premere Tab ripetutamente. Il focus deve ciclare solo tra gli elementi interni della modale. Premere Escape — la modal deve chiudersi e il focus tornare sul trigger.

Apri modal focus test Test focus trap Verifica che Tab cicli solo tra gli elementi della modale
Campo nella modale Link nella modale
Annulla Conferma
Apri modal con form Form nella modale
Seleziona un'opzione Opzione 1 Opzione 2
Conferma

G. Gerarchia heading mista light DOM + shadow DOM

Verifica se i tool vedono la gerarchia heading completa quando heading nativi e heading nel shadow DOM sono mischiati.

Nota sulla struttura di questa sezione: contrariamente alle altre, qui usiamo deliberatamente heading di livello non convenzionale (h1 nel corpo della pagina) per costruire i casi di test sulla gerarchia. Gli h1 ripetuti e i salti h1→h3 sono parte del test stesso, non errori di impaginazione della pagina. I tool che calcolano la struttura heading dovrebbero segnalarli.

Gerarchia corretta (🟢 controllo)

Sezione con heading nativo h2

Card con h3 nel shadow DOM — gerarchia corretta Questa card genera un h3, che segue l'h2 nativo.

Gerarchia con salto h1 > h3 (🔴 errore intenzionale)

(test)

Card con h3 subito dopo h1 — salta h2 Questa card genera un h3 direttamente dopo l'h1 della pagina, saltando h2.

Heading nativo dopo heading shadow DOM

(test)

Callout con h2 nel shadow DOM

Il callout genera un h2. Il prossimo heading nativo è un h3 — la gerarchia è corretta?

Heading h3 nativo dopo callout h2 shadow DOM

I tool vedono la sequenza h2 (shadow DOM) → h3 (nativo) come gerarchia valida?