Diagrammi STEM accessibili:
SVG, contenuti descritti con ARIA, audio description
Una molecola di chimica, la sezione trasversale di un mitocondrio, un diagramma di forze in un corpo libero, il grafico di una funzione cubica — ogni libro di testo STEM pubblicato nell’ultimo decennio è costruito su immagini che uno screen reader non riesce a consumare in modo significativo. La soluzione non è «aggiungi il testo alternativo». È uno stack a quattro livelli composto da SVG accessibile, descrizioni strutturate, audio description per i diagrammi animati e conoscenza della compatibilità con le AT che non si trasferisce tra sistemi operativi. Questo articolo è il manuale di produzione.
1. Perché i diagrammi STEM sono diversi da qualsiasi altro problema di accessibilità
Un’immagine hero di un blog con un attributo alt è un problema risolto. Un diagramma STEM non lo è. Tre proprietà delle immagini scientifiche rompono le assunzioni incorporate in alt, aria-label e nel modello vocale degli screen reader.
Primo, la densità di informazioni è così alta che una singola frase non riesce a contenerla. Un anello benzenico è sei carboni, sei idrogeni, legami doppi alternati, un sistema pi delocalizzato, una geometria planare, una lunghezza di legame di 1,39 angstrom. La convenzione del testo alternativo chiede «una breve sostituzione testuale»; il benzene ha bisogno di un paragrafo. Comprimerlo in una frase perde le informazioni strutturali («una molecola di benzene») oppure produce un testo ininterrotto che lo screen reader deve sillabare a 180 parole al minuto.
Secondo, le relazioni tra gli elementi portano tanto significato quanto gli elementi stessi. In un diagramma del corpo libero, la freccia dalla scatola alla parete non è decorazione — è la forza normale, e il suo angolo rispetto al vettore della gravità è la risposta al problema. Una descrizione piatta non riesce a codificare «l’angolo tra queste due frecce è 90 gradi ed è per questo che il problema si risolve», perché la descrizione piatta non ha struttura. SVG, usato con cura, ce l’ha.
Terzo, gli studenti STEM hanno bisogno di navigare nel diagramma, non solo di ascoltarlo. Uno studente che lavora su un grafico di una funzione cubica non vuole sentire il testo alternativo dall’inizio alla fine — vuole atterrare sul massimo locale, chiedere «qual è la pendenza qui», poi spostarsi al punto di flesso. Questo è un modello di interazione diverso da quello con cui gli screen reader vengono forniti per impostazione predefinita. Costruirlo richiede gestori di tastiera sui singoli nodi SVG, un albero di contenuti descritti da ARIA e un fallback per gli stack di tecnologie assistive che non riescono a stare al passo.
Molecole di chimica (atomi e legami), strutture cellulari di biologia (regioni etichettate), diagrammi di forze fisiche (vettori con magnitudini e angoli) e grafici di funzioni matematiche (curve con caratteristiche nominate). Ognuno mette sotto pressione un diverso livello dello stack SVG accessibile, e il manuale alla fine è modellato su ciò che si rompe per quale tipo.
2. SVG come substrato accessibile — e perché il raster è un vicolo cieco
Quasi ogni libro di testo STEM pubblicato distribuisce ancora i suoi diagrammi come PNG o JPG. Un’immagine raster è una griglia di pixel opaca: ha un unico punto di accesso per le tecnologie assistive, l’attributo alt, e un unico fallback, l’attributo longdesc che i browser hanno passato dieci anni a deprecare. Non c’è struttura all’interno dell’immagine a cui uno screen reader possa rivolgersi. Il diagramma è una scatola nera con un’etichetta davanti.
SVG inverte il modello. Ogni forma in un documento SVG è un nodo DOM — indirizzabile, focalizzabile, etichettabile. Un anello benzenico reso come SVG ha sei elementi circle per i carboni, sei elementi line per i legami e un elemento g che racchiude il tutto e lo nomina. Ognuno di questi nodi può portare attributi role, aria-label, aria-labelledby, aria-describedby e tabindex. Lo screen reader vede un albero di accessibilità di regioni nominate invece di un singolo blob opaco.
L’SVG accessibile minimo portabile ha tre cose sul suo elemento radice svg: role=“img”, aria-labelledby che punta a un figlio title e aria-describedby che punta a un figlio desc o a un paragrafo esterno tramite ID. Ognuno è piccolo. Ognuno fa un lavoro che gli altri due non riescono a fare.
<img src="benzene.png"
alt="Molecola di benzene" />L’immagine è opaca. «Molecola di benzene» fornisce un nome e nient’altro. Uno studente che ha bisogno del pattern di legami, della geometria dell’anello o del numero di carboni e idrogeni non riesce a ottenerli da questo markup. Non esiste un percorso verso le informazioni strutturali se non consultare una fonte diversa.
<svg role="img"
aria-labelledby="benz-title"
aria-describedby="benz-desc"
viewBox="0 0 200 200">
<title id="benz-title">Anello benzenico</title>
<desc id="benz-desc">
Un esagono regolare di sei atomi di carbonio,
ciascuno legato a un idrogeno. Legami singoli
e doppi alternati formano un anello aromatico
planare con elettroni delocalizzati.
</desc>
<g role="group" aria-label="Atomi di carbonio">
<circle cx="100" cy="40" r="6"
tabindex="0"
aria-label="C1, in alto"/>
</g>
<g role="group" aria-label="Legami">
</g>
</svg>La radice si nomina e si descrive. Ogni atomo è una regione tabbabile e nominata. Un utente di screen reader può sentire il riepilogo, poi entrare nella struttura con il tab per ispezionare un singolo legame. Lo stesso markup serve sia il lettore vedente che quello non vedente senza compromessi.
Un avvertimento importante: role=“img” sull’elemento radice svg cambia quello che le tecnologie assistive fanno con i figli. Con role=“img”, NVDA e JAWS trattano l’intero SVG come una singola immagine etichettata e non espongono i nodi interni — anche se quei nodi interni hanno tabindex. Per ottenere entrambi i comportamenti — un’etichetta di riepilogo in cima e figli indirizzabili all’interno — lasciare il role della radice non impostato (o impostare role=“graphics-document” dal modulo W3C Graphics ARIA) e mettere l’etichetta su un g figlio piuttosto che sulla radice. Browser e screen reader gestiscono questa combinazione in modo non uniforme. La matrice nella sezione 6 documenta cosa funziona dove.
3. Lo stack equivalente a longdesc: dove vive effettivamente la descrizione lunga
L’attributo longdesc era la risposta originale a «un attributo alt non è sufficiente». I browser ne stanno rimuovendo silenziosamente il supporto da anni; Firefox lo ha eliminato nella versione 90, Safari non l’ha mai implementato, Chrome lo tratta come un no-op. Chiunque scriva ancora longdesc=“benzene-desc.html” nel 2026 sta spedendo markup che nessuno legge. La sostituzione non è un singolo attributo ma un pattern a tre livelli che combina una descrizione inline, un pannello espandibile visibile e metadati leggibili dalle macchine.
Il livello uno è l’elemento desc inline all’interno dell’SVG. Due o quattro frasi. Letto dagli screen reader quando la radice SVG viene annunciata. Questo è il nuovo longdesc — una descrizione che fa parte del documento SVG e lo segue ovunque vada.
Il livello due è un pannello di descrizione espandibile visibile accanto al diagramma, disponibile per ogni lettore, non solo per gli utenti di screen reader. Una riga di riepilogo più un pulsante di divulgazione che apre una descrizione testuale più lunga — di solito da tre a dieci frasi per una molecola di chimica, più lunga per un diagramma di struttura cellulare con venti organelli etichettati. Il pannello visibile risolve un problema che il desc inline non riesce a risolvere: gli studenti che possono vedere il diagramma ma non riescono a decodificarlo (studenti ipovedenti, studenti dislessici, chiunque stia imparando il materiale per la prima volta) hanno bisogno anch’essi della descrizione lunga. Metterla dietro un pulsante non la nasconde agli screen reader — questi enumerano la divulgazione, l’utente la attiva e la descrizione viene letta nel buffer.
Il livello tre è costituito da metadati strutturati tramite JSON-LD. Un oggetto CreativeWork il cui array accessibilityFeature enumera ciò che il diagramma offre: longDescription, alternativeText, structuralNavigation, describedMath, tactileGraphic (se è disponibile un grafico tattile stampabile). I motori di ricerca, i recommender di contenuti e gli scanner di conformità all’accessibilità consumano tutti questi metadati. Non fa nulla per l’esperienza di lettura immediata dello screen reader, ma rende il diagramma scopribile come contenuto accessibile — il che conta quando uno studente sceglie tra tre libri di testo e uno di essi pubblicizza le sue funzionalità di accessibilità in forma leggibile dalle macchine.
L’oggetto CreativeWork vive in un blocco script type=“application/ld+json” in qualsiasi punto della pagina. Chiavi: accessibilityFeature (array di stringhe — longDescription, alternativeText, structuralNavigation, MathML, describedMath), accessibilityHazard (noFlashingHazard, noMotionSimulationHazard), accessibilityAPI (ARIA) e accessMode (textual, visual) più accessModeSufficient (le modalità di accesso che da sole sono sufficienti per percepire il lavoro). Un diagramma che spedisce tutti e tre i livelli di descrizione dovrebbe pubblicare tutti questi.
4. Audio description per i diagrammi animati: le mutazioni DOM come flusso di segnali
I diagrammi statici sono il caso facile. Il caso difficile è il diagramma animato — un mitocondrio che ruota in 3D, un’onda sinusoidale che viene tracciata lungo l’asse x, una reazione chimica con legami che si rompono e si riformano in quattro secondi. La risposta convenzionale è un file video con una traccia di audio description, ma questo abbandona l’indirizzabilità dell’SVG: nel momento in cui si racchiude l’animazione in un video, ogni nodo etichettato con cura smette di essere un nodo DOM e torna a essere un pixel.
L’alternativa accessibile è mantenere l’animazione come SVG (o Canvas con un albero di accessibilità offscreen) ed emettere audio description man mano che l’animazione progredisce, guidate dalle stesse mutazioni DOM che guidano il cambiamento visivo. Il pattern: un MutationObserver osserva l’SVG per i cambiamenti — un nuovo attributo transform, un legame che appare, un vettore che ruota — e ad ogni cambiamento significativo scrive un breve aggiornamento testuale in una regione globale aria-live=“polite”. L’animazione visiva guida una narrazione audio, generata al volo dalla stessa fonte di verità.
L’implementazione ha tre parti in movimento. La prima è l’animazione stessa, espressa come una sequenza di keyframe temporali — gli stessi dati che il renderer SVG consuma. La seconda è un livello di annotazione: ogni keyframe porta un breve testo che descrive cosa cambia in quel momento («si forma un legame tra C1 e C2», «l’onda attraversa lo zero dal basso»). La terza è il driver dell’audio description, che si iscrive alla timeline, raccoglie ogni keyframe annotato e scrive il suo testo nella regione live alcune centinaia di millisecondi prima che il cambiamento visivo avvenga. Il tempo di anticipo corrisponde a ciò che fa l’audio description di produzione per il cinema: la descrizione viene sentita appena prima dell’evento visivo, non dopo.
Tre modalità di fallimento sono abbastanza comuni da meritare di essere segnalate. Primo, aggiornamenti a raffica. Un’animazione che lancia 60 mutazioni al secondo sommerge il sintetizzatore dello screen reader — gli annunci si accodano, ritardano l’animazione e diventano incomprensibili. Annotare solo i keyframe semanticamente significativi, non ogni frame, e limitare la frequenza a circa un annuncio ogni 1500ms. Secondo, mancanza dell’inizio. Una regione live che non esisteva prima dell’inizio dell’animazione non annuncerà il suo primo aggiornamento in modo affidabile (vedere il pezzo sul framework aria-live per il problema sottostante dello scheduler). Montare la regione live vuota al caricamento della pagina. Terzo, assenza di un controllo di pausa. Gli utenti devono poter mettere in pausa l’audio description, rallentarla o scorrere un evento alla volta. Costruire una piccola barra di controllo — play, pausa, evento-precedente, evento-successivo — e collegare i suoi pulsanti allo stesso driver della timeline.
Ogni diagramma STEM animato deve rispettare la media query prefers-reduced-motion: reduce. La sostituzione non è «nessuna animazione, nessuna descrizione» — è un SVG statico con la descrizione lunga del livello due dello stack di descrizione espansa per impostazione predefinita. L’animazione è una modalità di accesso; le immagini statiche descritte ne sono un’altra. Uno studente con disturbi vestibolari che ha attivato la riduzione del movimento ha comunque bisogno del diagramma, solo non della rotazione.
5. Navigazione da tastiera tra i punti dati nei grafici interattivi
Un grafico di una funzione matematica che uno studente vedente può scorrere con il cursore non è accessibile finché uno studente non vedente non riesce a scorrere con la tastiera. Il meccanismo è ben noto e mal implementato nella pratica: ogni punto dati significativo sulla curva riceve tabindex=“0”, un aria-label che descrive le sue coordinate e qualsiasi caratteristica nominata («massimo locale a x = -1, y = 4») e un gestore di tastiera che risponde ai tasti freccia per il movimento granulare tra i punti adiacenti.
La granularità giusta conta più di quanto la gente realizzi. Il tab attraverso ogni pixel tracciato di una curva cubica è ostile — l’utente sente migliaia di annunci «x uguale 0,1, y uguale 0,001» prima di raggiungere qualcosa di interessante. Il tab solo attraverso le caratteristiche nominate (massimi locali, minimi, punti di flesso, intersezioni con l’asse x, intersezioni con l’asse y) è troppo scarso. Il compromesso pragmatico: due livelli di navigazione. Il tasto Tab scorre solo tra le caratteristiche nominate — di solito da tre a sette su una curva — e i tasti freccia, una volta che una caratteristica è focalizzata, si spostano a sinistra e a destra lungo la curva a un’ampiezza di passo definita dallo studente, annunciando le coordinate ad ogni passo. Home e Fine saltano ai bordi sinistro e destro della curva. Pagina Su e Pagina Giù saltano alla caratteristica nominata successiva.
Per un grafico a più serie — un grafico di cinetica chimica, un grafico di oscillazione fisica con due forme d’onda — aggiungere un asse di cambio serie. I tasti freccia Su e Giù si spostano tra le serie alla coordinata x corrente; Sinistra e Destra si spostano lungo la serie corrente. La convenzione è parallela a come i lettori di fogli di calcolo navigano righe e colonne e riutilizza un modello mentale che molti utenti già hanno.
Un dettaglio che spesso viene trascurato: il punto dati focalizzato ha bisogno di un indicatore di focus visibile. Un utente non vedente non ne ha bisogno, ma un utente vedente che usa lo screen reader sì, così come gli insegnanti che osservano lo schermo dello studente. Render un anello di focus intorno all’elemento SVG focalizzato con lo stile :focus-visible — la stessa convenzione degli anelli di focus dei pulsanti, applicata ai nodi SVG che il browser non stila per impostazione predefinita.
| Tipo di diagramma | Markup SVG | Descrizione lunga | Audio description | Navigazione da tastiera |
|---|---|---|---|---|
| Molecola di chimica | Obbligatoria — role group per atomo, per legame | Obbligatoria — 3-6 frasi | Solo se la reazione è animata | Tab tra gli atomi, freccia verso i legami |
| Struttura cellulare di biologia | Obbligatoria — role group per regione etichettata | Obbligatoria — 5-12 frasi | Solo se il processo è animato | Tab tra gli organelli in ordine z |
| Diagramma di forze fisiche | Obbligatoria — role group per vettore | Obbligatoria — 3-5 frasi con magnitudini e angoli | Obbligatoria se interattiva (trascinamento dei vettori) | Tab tra i vettori, freccia per ruotare |
| Grafico di funzione matematica | Obbligatoria — caratteristiche nominate come nodi | Obbligatoria — dominio, codominio, asintoti, caratteristiche | Facoltativa — solo se c’è animazione di tracciamento | Tab per le caratteristiche, freccia per scorrimento granulare |
6. Compatibilità AT: cosa funziona e dove l’albero SVG è interrotto
La verità più difficile di questo articolo: lo stack SVG accessibile non funziona allo stesso modo su browser e screen reader diversi, e le lacune non sono bug nel proprio markup. NVDA su Firefox è la combinazione più affidabile — l’unica in cui ogni pattern di questo articolo si comporta come dice la mappatura di accessibilità SVG W3C. Ogni altra combinazione ha almeno una lacuna nota.
Safari su macOS con VoiceOver è il più problematico dei principali stack. L’albero di accessibilità SVG di WebKit ha lacune documentate nel modo in cui espone gli elementi g interni con etichette ARIA: le etichette sono presenti nel DOM e ispezionabili con l’inspector di accessibilità, ma VoiceOver non le rileva sempre quando l’utente naviga con VO-Freccia-Destra. Il comportamento è incoerente — a volte le etichette interne vengono annunciate, a volte viene letta solo l’etichetta SVG della radice, senza un pattern visibile dal client. Il bugzilla di WebKit ha problemi aperti dal 2020 su questo. L’implicazione pragmatica: se il proprio diagramma STEM funziona su Mac, questa è una condizione necessaria, non sufficiente. Testare su Windows con NVDA prima di pubblicare.
Chrome su Windows con JAWS è il secondo stack più affidabile — vicino a NVDA + Firefox, con una sfumatura: JAWS tratta role=“img” su SVG in modo più aggressivo di NVDA, comprimendo più spesso i nodi interni. La soluzione è usare role=“graphics-document” dal modulo W3C Graphics ARIA sulla svg radice, che JAWS gestisce correttamente. NVDA lo gestisce correttamente. Firefox e Chrome forniscono entrambi i mapping API di piattaforma necessari.
Il mobile è un problema separato. VoiceOver su iOS eredita le lacune SVG di WebKit; TalkBack su Android su Chrome gestisce i nodi interni in modo affidabile ma non supporta ancora i role W3C Graphics ARIA, quindi ricade al comportamento di role=“img”. Per un editore di libri di testo che si rivolge sia al desktop che al mobile, la scelta sicura è distribuire due modalità SVG: una modalità con navigazione strutturale per il desktop e una modalità «riepilogo più descrizione lunga» che disabilita la navigazione interna sul mobile. Il cambio di modalità è guidato dall’user agent e dalla preferenza dell’utente, memorizzata tra le sessioni.
| NVDA + Firefox | JAWS + Chrome | VoiceOver + Safari | TalkBack + Chrome | |
|---|---|---|---|---|
| SVG title e desc (radice) | OK | OK | OK | OK |
| g interno con aria-label | OK | OK | Parziale | OK |
| tabindex su nodi SVG | OK | OK | Parziale | Fallisce |
| role=“graphics-document” | OK | OK | Fallisce | Fallisce |
| aria-live guidato da mutazioni | OK | OK | Parziale | Parziale |
| focus-visible su nodi SVG | OK | OK | OK | OK |
Una lettura della matrice: distribuire NVDA + Firefox come obiettivo di conformità di riferimento, documentare i fallback per Safari e TalkBack e non usare mai l’assenza di un annuncio di nodo interno su Mac come prova che l’SVG non è accessibile. Il diagramma può essere perfettamente accessibile — la piattaforma semplicemente non sta esponendo le etichette scritte. L’inspector di accessibilità nel menu Sviluppo di Safari mostra cosa è nell’albero anche quando VoiceOver non riesce a leggerlo, ed è lo strumento giusto per distinguere «markup interrotto» da «piattaforma interrotta».
7. Il manuale di produzione
Creare ogni diagramma STEM come SVG, mai come raster
PNG e JPG sono vicoli ciechi. SVG fornisce un DOM, e il DOM è dove vivono tutte le funzionalità di accessibilità di questo articolo. Se la pipeline di authoring produce raster (la maggior parte degli strumenti di disegno chimico lo fa ancora), aggiungere un passaggio che esporti anche SVG e distribuire entrambi — l’SVG è l’artefatto accessibile, il PNG è un fallback per le stampanti legacy.
Mettere title e desc su ogni radice SVG
Due figli. Il title è il nome breve. Il desc sono da due a quattro frasi che descrivono cosa mostra il diagramma. Collegarli con aria-labelledby e aria-describedby sulla radice. Nessuna eccezione, nemmeno per i diagrammi «piccoli» — una piccola molecola è ancora una molecola, e un utente di screen reader ha lo stesso diritto di sentire la struttura che un utente vedente ha di vederla.
Aggiungere un pannello di descrizione lunga espandibile e visibile accanto a ogni diagramma
Da tre a dieci frasi, in un pannello con pattern di divulgazione che qualsiasi lettore può aprire. Risolve il bisogno di descrizione per gli studenti ipovedenti e dislessici che il solo desc SVG non serve. Rispecchiare il testo della descrizione nel desc SVG per gli utenti di screen reader che non incontrano la divulgazione.
Pubblicare un CreativeWork JSON-LD con accessibilityFeature
Un blocco per pagina o per diagramma. Enumerare ogni funzionalità di accessibilità che il diagramma effettivamente porta. I motori di ricerca e gli scanner di conformità leggono questo; gli studenti che usano un CMS che filtra per contenuti accessibili leggono questo. È economico da scrivere e ripaga nel momento in cui qualcuno sta scegliendo tra risorse.
Guidare l’audio description per i diagrammi animati dalle mutazioni DOM
Un MutationObserver per ogni SVG animato. Keyframe annotati nella timeline dell’animazione. Una regione aria-live=“polite” globale e vuota all’avvio dell’app, montata prima che qualsiasi diagramma venga renderizzato. Limitare la frequenza a circa un annuncio ogni 1500ms. Rispettare prefers-reduced-motion: reduce collassando al fallback statico più descrizione lunga.
Rendere i grafici interattivi navigabili da tastiera a due granularità
Tab solo attraverso le caratteristiche nominate. Tasti freccia per il movimento granulare lungo la curva. Home, Fine, Pagina Su, Pagina Giù per i salti di confine e caratteristica. I tasti freccia Su e Giù cambiano serie nei grafici a più serie. Rendere visibile un anello di focus sul nodo SVG focalizzato — gli utenti non vedenti non ne hanno bisogno, ma gli utenti vedenti che usano lo screen reader sì.
Testare su NVDA + Firefox prima di qualsiasi altra combinazione
La piattaforma di riferimento. Se un pattern fallisce lì, il markup è sbagliato. Se funziona lì ma fallisce su Safari, la piattaforma è sbagliata e il passo successivo è documentare il fallback piuttosto che riscrivere l’SVG. JAWS + Chrome è il test di accettazione secondario. VoiceOver + Safari è necessario per la parità ma mai sufficiente.
Conclusione: l’accessibilità STEM è un problema di markup con una coda di interaction design
La maggior parte delle linee guida pubblicate sull’accessibilità dei diagrammi STEM si ferma al livello title-e-desc. Quello è il 30 percento facile. Il restante 70 percento — il pannello delle descrizioni lunghe, la timeline dell’audio description guidata dalle mutazioni DOM, la navigazione da tastiera a due granularità, i fallback specifici della piattaforma — è interaction design tanto quanto markup. Lo screen reader è un utente; uno studente non vedente che usa uno screen reader per navigare in un grafico di funzione al ritmo di un compagno di classe vedente è un utente diverso, con esigenze diverse.
Il dividendo è grande e disomogeneo. Un editore di libri di testo che distribuisce lo stack completo su circa 600 diagrammi in un libro di testo di calcolo serve ogni studente non vedente che usa quel libro di testo, ogni studente ipovedente che apprezza il pannello di divulgazione, ogni studente dislessico che riesce a leggere la descrizione lunga ma non riesce a decodificare le convenzioni visive del campo, ogni studente di italiano come seconda lingua che trova la descrizione strutturata più facile delle convenzioni visive della materia, e ogni insegnante vedente che produce riepiloghi audio per podcast. Lo stesso markup serve cinque pubblici distinti. Il costo è alcune ore per diagramma, ammortizzate su decenni di utilizzo da parte degli studenti.
Lo stato attuale dell’arte è disomogeneo perché le implementazioni dell’albero di accessibilità differiscono tra i sistemi operativi che gli studenti effettivamente usano. NVDA e JAWS su Windows hanno colmato la maggior parte delle lacune SVG. Safari su macOS non lo ha fatto. Fino a quando le piattaforme non convergeranno, il pattern di produzione è creare per il target più rigoroso — NVDA + Firefox — e documentare i fallback per le piattaforme con lacune note. Questo è più lavoro di quanto richiedesse il modello dell’attributo alt. È anche l’unico modo per distribuire un libro di testo STEM che non escluda i lettori che dovrebbe insegnare.
«Un anello benzenico è sei carboni, sei idrogeni, legami doppi alternati, un sistema pi delocalizzato, una geometria planare, una lunghezza di legame di 1,39 angstrom. La convenzione del testo alternativo chiede una frase. SVG pone invece la domanda giusta: su quale atomo vorresti atterrare per primo?»