Tilgængelige STEM-diagrammer:
SVG, ARIA-beskrevet indhold, synstolkning
Et kemisk molekyle, et mitokondrie-tværsnit, et kraftdiagram, grafen for en tredjegradspolynomium — ethvert STEM-lærebog udgivet i de seneste ti år er bygget af billeder, som en skærmlæser ikke kan formidle meningsfuldt. Løsningen er ikke „tilføj alternativ tekst.“ Det er en firlags-stak af tilgængelig SVG, strukturerede beskrivelser, synstolkning til animerede diagrammer og viden om hjælpeteknologikompatibilitet, der ikke overfører mellem operativsystemer. Denne artikel er produktionsguiden.
1. Hvorfor STEM-diagrammer adskiller sig fra ethvert andet tilgængelighedsproblem
Et bloghero-billede med et alt-attribut er et løst problem. Et STEM-diagram er det ikke. Tre egenskaber ved videnskabelige billeder bryder de antagelser, der er indlejret i alt, aria-label og skærmlæserens talemodel.
For det første er informationstætheden høj nok til, at en enkelt sætning ikke kan bære den. En benzenring er seks kulstofatomer, seks hydrogenatomer, skiftende dobbeltbindinger, et delokaliseret pi-system, en planær geometri, en bindingslængde på 1,39 ångström. Alt-tekst-konventionen beder om „en kort tekstmæssig erstatning“; benzen har brug for et afsnit. At komprimere det til én sætning mister enten den strukturelle information („et benzenmolekyle“) eller producerer et ulæseligt run-on, som skærmlæseren må stave op ved 180 ord i minuttet.
For det andet bærer relationerne mellem elementer lige så meget mening som elementerne selv. I et kraftdiagram er pilen fra kassen til væggen ikke dekoration — det er normalkraften, og dens vinkel i forhold til tyngdekraftsvektoren er svaret på opgaven. En flad beskrivelse kan ikke kode „vinklen mellem disse to pile er 90 grader, og det er derfor opgaven løses,“ fordi flad beskrivelse ikke har struktur. SVG, brugt omhyggeligt, har det.
For det tredje har STEM-studerende brug for at navigere i diagrammet, ikke blot høre det. En studerende, der arbejder sig igennem grafen for en tredjegradspolynomium, ønsker ikke at høre alt-teksten fra start til slut — vedkommende vil lande på det lokale maksimum, spørge „hvad er hældningen her,“ og derefter flytte sig til infleksionspunktet. Det er en anden interaktionsmodel end den, skærmlæsere leveres med som standard. At bygge den kræver tastaturhandlere på individuelle SVG-noder, et ARIA-beskrevet indholdstræ og en fallback til de hjælpeteknologi-stakke, der ikke kan følge med.
Kemiske molekyler (atomer og bindinger), biologiske cellestrukturer (mærkede regioner), fysikkens kraftdiagrammer (vektorer med størrelser og vinkler) og matematikkens funktionsgrafik (kurver med navngivne features). Hver stresser et andet lag af den tilgængelige SVG-stak, og guiden til sidst er formet af, hvad der bryder for hvad.
2. SVG som tilgængeligt fundament — og hvorfor rasterbilleder er en blindgyde
Næsten alle udgivne STEM-lærebøger leverer stadig diagrammer som PNG eller JPG. Et rasterbillede er et uigennemsigtigt pixelgitter: det har ét indgangspunkt for hjælpeteknologi, alt-attributten, og én fallback, longdesc-attributten, som browsere har brugt ti år på at afvikle. Der er ingen struktur inde i billedet, som en skærmlæser kan adressere. Diagrammet er en sort boks med en etiket på forsiden.
SVG vender modellen om. Hvert element i et SVG-dokument er en DOM-node — adresserbar, fokuserbar, mærkerbar. En benzenring renderet som SVG har seks circle-elementer til kulstofferne, seks line-elementer til bindingerne og et omsluttende g-element, der navngiver det hele. Hver af disse noder kan bære role-, aria-label-, aria-labelledby-, aria-describedby- og tabindex-attributter. Skærmlæseren ser et tilgængelighedstræ af navngivne regioner i stedet for en enkelt uigennemsigtig klump.
Den minimalt tilgængelige SVG bærer tre ting på sit rod-svg-element: role=“img”, aria-labelledby der peger på et title-barn og aria-describedby der peger på et desc-barn eller på et eksternt afsnit via ID. Hver er lille. Hver udfører arbejde, de andre to ikke kan.
<img src="benzene.png"
alt="Benzenmolekyle" />Billedet er uigennemsigtigt. „Benzenmolekyle“ giver et navn og intet andet. En studerende, der har brug for bindingsmønsteret, ringgeometrien eller kulstof-hydrogen-antallet, kan ikke få det fra denne markup. Der er ingen vej til den strukturelle information ud over at konsultere en anden kilde.
<svg role="img"
aria-labelledby="benz-title"
aria-describedby="benz-desc"
viewBox="0 0 200 200">
<title id="benz-title">Benzenring</title>
<desc id="benz-desc">
Et regulært hexagon af seks kulstofatomer,
hvert bundet til ét hydrogen. Skiftende
enkelt- og dobbeltbindinger danner en planær
aromatisk ring med delokaliserede elektroner.
</desc>
<g role="group" aria-label="Kulstofatomer">
<circle cx="100" cy="40" r="6"
tabindex="0"
aria-label="C1, øverst"/>
</g>
<g role="group" aria-label="Bindinger">
</g>
</svg>Roden navngiver sig selv og beskriver sig selv. Hvert atom er en fokuserbar, navngivet region. En skærmlæser-bruger kan høre oversigten og derefter tabbe ind i strukturen for at inspicere en enkelt binding. Den samme markup tjener en seende og en ikke-seende bruger uden kompromis.
En skarp advarsel: role=“img” på rod-svg’en ændrer, hvad hjælpeteknologi gør med børnene. Med role=“img” behandler NVDA og JAWS hele SVG’en som et enkelt mærket billede og eksponerer ikke de indre noder — selv hvis disse indre noder har tabindex. For at få begge adfærde — et resumé-label øverst og adresserbare børn indeni — lad rod-rollen være usat (eller sæt role=“graphics-document” fra W3C Graphics ARIA-modulet) og placer labelen på et barn-g snarere end på roden. Browsere og skærmlæsere håndterer denne kombination ujævnt. Matrixen i afsnit 6 dokumenterer, hvad der virker hvor.
3. Longdesc-ækvivalenten: hvor den lange beskrivelse faktisk bor
longdesc-attributten var det oprindelige svar på „et alt-attribut er ikke nok.“ Browsere har stille og roligt fjernet understøttelse i årevis; Firefox droppede den i version 90, Safari implementerede den aldrig, Chrome behandler den som en no-op. Den, der stadig skriver longdesc=“benzene-desc.html” i 2026, sender markup, som intet læser. Erstatningen er ikke et enkelt attribut men et trelags-mønster, der kombinerer en inline-beskrivelse, et synligt udvidbart panel og maskinlæsbar metadata.
Lag et er det inline desc-element inde i SVG’en. To til fire sætninger. Læses af skærmlæsere, når SVG-roden annonceres. Dette er den nye longdesc — en beskrivelse, der er en del af SVG-dokumentet og rejser med det, uanset hvor SVG’en placeres.
Lag to er et synligt udvidbart beskrivelsespanel ved siden af diagrammet, tilgængeligt for enhver læser, ikke kun skærmlæser-brugere. En resumélinje plus en disclosure-knap, der åbner en længere tekstgennemgang — typisk tre til ti sætninger for et kemisk molekyle, længere for et cellestruktur-diagram med tyve mærkede organeller. Det synlige panel løser et problem, som det inline desc ikke kan: studerende, der kan se diagrammet men ikke afkode det (svagsynede studerende, dyslektiske studerende, alle, der lærer materialet for første gang), har brug for den lange beskrivelse også. At placere den bag en knap skjuler den ikke for skærmlæsere — de opregner disclosure, brugeren aktiverer det, og beskrivelsen læses ind i bufferen.
Lag tre er struktureret metadata via JSON-LD. Et CreativeWork-objekt, hvis accessibilityFeature-array opregner, hvad diagrammet tilbyder: longDescription, alternativeText, structuralNavigation, describedMath, tactileGraphic (hvis et udskrivbart taktilt er tilgængeligt). Søgemaskiner, indholdsanbefalere og tilgængeligheds-overvågningsscannere forbruger alle disse metadata. Det gør intet for den umiddelbare skærmlæseroplevelse, men gør diagrammet opdageligt som tilgængeligt indhold — hvilket er vigtigt, når en studerende vælger mellem tre lærebøger, og én af dem reklamerer for sine tilgængelighedsfunktioner i maskinlæsbar form.
CreativeWork-objektet bor i et script type=“application/ld+json”-blok et sted på siden. Nøgler: accessibilityFeature (array af strenge — longDescription, alternativeText, structuralNavigation, MathML, describedMath), accessibilityHazard (noFlashingHazard, noMotionSimulationHazard), accessibilityAPI (ARIA) og accessMode (textual, visual) plus accessModeSufficient (de adgangsformer, der er tilstrækkelige alene til at opfatte værket). Et diagram, der leverer alle tre beskrivende lag, bør publicere alle disse.
4. Synstolkning til animerede diagrammer: DOM-mutationer som kue-strøm
Statiske diagrammer er det nemme tilfælde. Det svære tilfælde er det animerede diagram — et mitokondrie, der roterer i 3D, en sinusbølge, der tegnes ud langs x-aksen, en kemisk reaktion med bindinger, der brydes og genopbygges over fire sekunder. Det konventionelle svar er en videofil med et synstolkningsspor, men det opgiver SVG’s adresserbarhed: i det øjeblik animationen bages ind i en video, ophører enhver nøje mærket node med at være en DOM-node og bliver til en pixel igen.
Det tilgængelige alternativ er at holde animationen som SVG (eller Canvas med et offscreen-tilgængelighedstræ) og udsende synstolkninger efterhånden som animationen skrider frem, drevet af de samme DOM-mutationer, der driver den visuelle ændring. Mønsteret: en MutationObserver overvåger SVG’en for ændringer — et nyt transform-attribut, en binding der opstår, en vektor der roterer — og ved hver signifikant ændring skriver en kort tekstopdatering ind i en global aria-live=“polite”-region. Den visuelle animation driver en lydbeskrivelse, genereret løbende fra samme kilde.
Implementeringen har tre bevægelige dele. Den første er selve animationen, udtrykt som en sekvens af tidslinje-keyframes — de samme data SVG-rendereren forbruger. Den anden er et annotationslag: hvert keyframe bærer en kort tekst, der beskriver, hvad der ændres på det tidspunkt („binding dannes mellem C1 og C2,“ „bølge krydser nul nedefra“). Den tredje er synstolknings-driveren, der abonnerer på tidslinjen, henter hvert annoteret keyframe og skriver dets tekst ind i live-regionen nogle hundrede millisekunder, inden den visuelle ændring sker. Forspringet matcher, hvad produktions-synstolkning gør til film: beskrivelsen høres lige inden den visuelle begivenhed, ikke efter.
Tre fejltilstande er hyppige nok til at nævne. Første er burst-opdateringer. En animation, der sender 60 mutationer i sekundet, drukner skærmlæserens synthesizer — annonceringserne stiller op i kø, haler bagud og bliver uforståelige. Annotoér kun de semantisk betydningsfulde keyframes, ikke hvert frame, og throttle til ca. én annoncering pr. 1500 ms. Anden er at gå glip af starten. En live-region, der ikke eksisterede, inden animationen begyndte, annoncerer ikke sin første opdatering pålideligt (se aria-live-framework-artiklen for det underliggende scheduler-problem). Montér live-regionen tom ved sideindlæsning. Tredje er ingen pausekontrol. Brugere har brug for at sætte synstolkningen på pause, sænke farten eller gennemgå den én begivenhed ad gangen. Byg en lille kontrolbjælke — afspil, pause, forrige begivenhed, næste begivenhed — og forbind dens knapper til den samme tidslinje-driver.
Ethvert animeret STEM-diagram skal overholde prefers-reduced-motion: reduce media-forespørgslen. Erstatningen er ikke „ingen animation, ingen beskrivelse“ — det er en statisk SVG med den lange beskrivelse fra lag to i beskrivelsessakken udvidet som standard. Animation er én adgangsmåde; beskrevet statisk billede er en anden. En studerende med vestibulær lidelse, der har aktiveret reduceret bevægelse, har stadig brug for diagrammet, bare ikke rotationen.
5. Tastaturnavigation mellem datapunkter i interaktive diagrammer
En matematisk funktionsgraf, som en seende studerende kan skrubbe med markøren, er ikke tilgængelig, før en ikke-seende studerende kan skrubbe den med tastaturet. Mekanismen er velkendt og dårligt implementeret i praksis: hvert signifikant datapunkt på kurven får tabindex=“0”, et aria-label der beskriver dets koordinater og eventuelle navngivne feature (»lokalt maksimum ved x = -1, y = 4«), og en tastaturhandler, der reagerer på piletaster for finkornet bevægelse mellem tilstødende punkter.
Den rette granularitet betyder mere, end folk indser. At tabbe igennem hvert plottet pixel af en kubisk kurve er fjendtligt — brugeren hører tusindvis af »x er lig med 0,1, y er lig med 0,001«-annonceringsser, inden noget interessant nås. At tabbe igennem kun de navngivne features (lokale maxima, minima, infleksionspunkter, x-skæringspunkter, y-skæringspunkter) er for sparsomt. Det pragmatiske kompromis: to navigationsniveauer. Tab-tasten cykler kun igennem navngivne features — typisk tre til syv på en kurve — og piletasterne, når en feature er i fokus, går til venstre og højre langs kurven i en brugerdefineret skridtstørrelse og annoncerer koordinaten ved hvert skridt. Home og End hopper til kurvens venstre og højre grænser. Page Up og Page Down hopper til den næste navngivne feature.
For et flerseriert diagram — et kinetikplot i kemi, en fysisk oscillationsgraf med to bølgeformer — tilføj en serie-skiftende akse. Op- og ned-piletaster skifter mellem serier ved den aktuelle x-koordinat; venstre og højre bevæger sig langs den aktuelle serie. Konventionen paralleliserer, hvordan regnearkslæsere navigerer rækker og kolonner og genbruger et mentalt skema, mange brugere allerede har.
Ét detalje, der glemmes: det fokuserede datapunkt har brug for et synligt fokusindikator. En ikke-seende bruger har ikke brug for det, men en seende skærmlæser-bruger gør, ligesom partner-instruktører, der kigger over den studerendes skulder. Render en fokusring omkring det fokuserede SVG-element med :focus-visible-styling — den samme konvention som knap-fokusringe, anvendt på SVG-noder, som browseren ikke styler som standard.
| Diagramtype | SVG-markup | Lang beskrivelse | Synstolkning | Tastaturnavigation |
|---|---|---|---|---|
| Kemisk molekyle | Påkrævet — role group pr. atom, pr. binding | Påkrævet — 3 til 6 sætninger | Kun ved animeret reaktion | Tab igennem atomer, pil til bindinger |
| Biologisk cellestruktur | Påkrævet — role group pr. mærket region | Påkrævet — 5 til 12 sætninger | Kun ved animeret proces | Tab igennem organeller i z-rækkefølge |
| Fysisk kraftdiagram | Påkrævet — role group pr. vektor | Påkrævet — 3 til 5 sætninger med størrelser og vinkler | Påkrævet ved interaktiv (træk vektorer) | Tab igennem vektorer, pil til rotation |
| Matematisk funktionsgraf | Påkrævet — navngivne features som noder | Påkrævet — domæne, interval, asymptotiske, features | Valgfri — kun ved sporingsanimation | Tab for features, pil for finkornet skrubning |
6. Hjælpeteknologi-kompatibilitet: hvad der virker, og hvor SVG-træet er brudt
Den sværeste sandhed i denne artikel: den tilgængelige SVG-stak fungerer ikke på samme måde på tværs af browsere og skærmlæsere, og manglerne er ikke fejl i din markup. NVDA på Firefox er den mest pålidelige kombination — den eneste, hvor hvert mønster i denne artikel opfører sig, som W3C SVG-tilgængelighedsmappingen siger, det skal. Enhver anden kombination har mindst én kendt mangel.
Safari på macOS med VoiceOver er den mest problematiske af de store stakke. WebKits SVG-tilgængelighedstræ har dokumenterede huller i, hvordan det eksponerer indre g-elementer med ARIA-labels: labels er til stede i DOM’en og kan inspiceres med tilgængeligheds-inspektøren, men VoiceOver henter dem ikke altid op, når brugeren navigerer med VO-højre-pil. Adfærden er inkonsistent — nogle gange annonceres de indre labels, nogle gange læses kun rod-SVG-labelen, uden noget klient-synligt mønster. WebKit bugzilla har åbne problemer fra 2020 om dette. Den pragmatiske konsekvens: hvis dit STEM-diagram virker på Mac, er det en nødvendig betingelse, ikke en tilstrækkelig. Test på Windows med NVDA inden levering.
Chrome på Windows med JAWS er den næst mest pålidelige stak — tæt på NVDA + Firefox, med én krølle: JAWS behandler SVG role=“img” mere aggressivt end NVDA og kollapser indre noder oftere. Løsningen er at bruge role=“graphics-document” fra W3C Graphics ARIA-modulet på rod-svg’en, som JAWS håndterer korrekt. NVDA håndterer det også korrekt. Firefox og Chrome leverer begge de nødvendige platform-API-mappinger.
Mobil er et separat problem. iOS VoiceOver arver WebKits SVG-mangler; Android TalkBack på Chrome håndterer indre noder pålideligt, men understøtter endnu ikke W3C Graphics ARIA-roller, så den falder tilbage på role=“img”-adfærd. For en lærebogsudbyder, der målretter sig mod både desktop og mobil, er det sikre valg at levere to SVG-tilstande: en strukturelt-navigerbar tilstand til desktop og en »oversigt plus lang beskrivelse«-tilstand, der deaktiverer indre navigation på mobil. Tilstandsskiftet drives af user agent og af brugerindstilling, gemt på tværs af sessioner.
| NVDA + Firefox | JAWS + Chrome | VoiceOver + Safari | TalkBack + Chrome | |
|---|---|---|---|---|
| SVG title og desc (rod) | OK | OK | OK | OK |
| Indre g med aria-label | OK | OK | Delvist | OK |
| tabindex på SVG-noder | OK | OK | Delvist | Fejler |
| role=“graphics-document” | OK | OK | Fejler | Fejler |
| aria-live drevet af mutationer | OK | OK | Delvist | Delvist |
| focus-visible på SVG-noder | OK | OK | OK | OK |
Én læsning af matrixen: leverér NVDA + Firefox som baseline-overensstemmelsesmål, dokumentér Safari- og TalkBack-fallbacks og brug aldrig fraværet af en indre-node-annoncering på en Mac som bevis for, at SVG’en er utilgængelig. Diagrammet kan være fuldt tilgængeligt — platformen eksponerer bare ikke de labels, du har skrevet. Tilgængeligheds-inspektøren i Safari Develop-menuen viser, hvad der er i træet, selv når VoiceOver ikke læser det, og er det rette værktøj til at skelne »ødelagt markup« fra »ødelagt platform.«
7. Produktionsguiden
Forfat ethvert STEM-diagram som SVG, aldrig som raster
PNG og JPG er blindgyder. SVG giver dig en DOM, og DOM’en er der, enhver tilgængelighedsfunktion i denne artikel lever. Hvis din forfatningspipeline producerer raster (de fleste kemi-tegneværktøjer gør det stadig), tilføj et trin, der eksporterer SVG også, og lever begge — SVG’en er det tilgængelige artefakt, PNG’en er en fallback til ældre printere.
Placer title og desc på enhver SVG-rod
To børn. Title er det korte navn. Desc er to til fire sætninger, der beskriver, hvad diagrammet viser. Forbind dem med aria-labelledby og aria-describedby på roden. Ingen undtagelser, selv for »små« diagrammer — et lille molekyle er stadig et molekyle, og en skærmlæser-bruger har den samme ret til at høre strukturen, som en seende bruger har til at se den.
Tilføj et synligt udvidbart lang-beskrivelsespanel ved siden af hvert diagram
Tre til ti sætninger i et disclosure-mønster-panel, som enhver læser kan åbne. Løser beskrivelses-behovet for svagsynede og dyslektiske studerende, som SVG desc alene ikke tjener. Spejl beskrivelsesteksten ind i SVG desc til skærmlæser-brugere, der ikke møder disclosure.
Publicér et JSON-LD CreativeWork med accessibilityFeature
Ét blok pr. side eller pr. diagram. Opregn enhver tilgængeligheds-feature, diagrammet faktisk bærer. Søgemaskiner og overvågningsscannere læser dette; studerende, der bruger et CMS, der filtrerer efter tilgængeligt indhold, læser dette. Det er billigt at skrive og betaler sig tilbage i det øjeblik nogen vælger mellem ressourcer.
Driv synstolkning til animerede diagrammer fra DOM-mutationer
Én MutationObserver pr. animeret SVG. Annoterede keyframes i animationstidslinjen. En global tom aria-live=“polite”-region ved app-start, monteret inden et diagram renderes. Throttle til ca. én annoncering pr. 1500 ms. Overhold prefers-reduced-motion: reduce ved at kollapse til statisk-plus-lang-beskrivelse-fallbacken.
Gør interaktive diagrammer tastaturnavigérbare på to granularitetsniveauer
Tab igennem navngivne features kun. Piletaster til finkornet bevægelse langs kurven. Home, End, Page Up, Page Down til grænse- og feature-hop. Op- og ned-piletaster skifter serier i flerseriet plots. Render en synlig fokusring på den fokuserede SVG-node — ikke-seende brugere har ikke brug for den, seende skærmlæser-brugere gør.
Test på NVDA + Firefox inden enhver anden kombination
Referenceplatformen. Hvis et mønster fejler der, er markup’en forkert. Hvis det virker der men fejler på Safari, er platformen forkert, og næste skridt er at dokumentere fallbacken snarere end at omskrive SVG’en. JAWS + Chrome er den sekundære acceptancetest. VoiceOver + Safari er nødvendig for paritet, men aldrig tilstrækkelig.
Konklusion: STEM-tilgængelighed er et markup-problem med en interaktionsdesign-hale
De fleste udgivne vejledninger om STEM-diagram-tilgængelighed stopper ved title-og-desc-laget. Det er de nemme 30 procent. De resterende 70 procent — det lange beskrivelsespanel, synstolknings-tidslinjen drevet af DOM-mutationer, den to-granularitets tastaturnavigation, de platformsspecifikke fallbacks — er interaktionsdesign lige så meget som det er markup. Skærmlæseren er én bruger; en ikke-seende studerende, der bruger en skærmlæser til at navigere en funktionsgraf i samme tempo som en seende medstuderende, er en anden bruger med andre behov.
Udbyttet er stort og ujævnt. En lærebogsudbyder, der leverer den fulde stak på tværs af ca. 600 diagrammer i en calculus-lærebog, betjener enhver ikke-seende studerende, der bruger den lærebog, enhver svagsynet studerende, der sætter pris på disclosure-panelet, enhver dyslektisk studerende, der kan læse den lange beskrivelse men ikke afkode det visuelle, enhver studerende med dansk som andetsprog, der finder den strukturerede beskrivelse lettere end feltets visuelle konventioner, og enhver seende instruktør, der producerer lydopsummeringer til podcasts. Den samme markup betjener fem distinkte målgrupper. Omkostningen er et par timer pr. diagram, amortiseret over årtiers studerendes brug.
Den aktuelle stand of the art er ujævn, fordi tilgængeligheds-træ-implementeringerne adskiller sig på tværs af de operativsystemer, studerende faktisk bruger. NVDA og JAWS på Windows har lukket de fleste SVG-mangler. Safari på macOS har ikke. Indtil platformene konvergerer er produktionsmønsteret at forfatte for det strengeste mål — NVDA + Firefox — og dokumentere fallbacks for platformene med kendte mangler. Det er mere arbejde end alt-attribut-modellen plejede at kræve. Det er også den eneste måde at levere en STEM-lærebog på, der ikke udelukker de læsere, den er beregnet til at undervise.
»En benzenring er seks kulstofatomer, seks hydrogenatomer, skiftende dobbeltbindinger, et delokaliseret pi-system, en planær geometri, en bindingslængde på 1,39 ångström. Alt-tekst-konventionen beder om én sætning. SVG stiller det rigtige spørgsmål i stedet — hvilket atom vil du lande på først?«