Tillgänglighet och inkludering i AI-produkter
Kunna designa AI-funktioner som fungerar för personer med funktionsnedsättning och olika språkbakgrund.
Förkunskaper
- EUX för AI-funktionerkrävs
Intuition
WCAG 2.2 bygger på fyra principer — innehåll ska vara möjligt att uppfatta, hantera, förstå och robust nog att fungera med hjälpmedel.
För offentlig sektor i Sverige är nivå AA ett lagkrav (lagen om tillgänglighet till digital offentlig service), och tillgänglighetsdirektivet utvidgar kraven till privata aktörer från 2025.
Grunderna gäller förstås även AI-gränssnitt:
| Krav | I praktiken |
|---|---|
| Kontrast ≥ 4,5:1 | brödtext mot bakgrund |
| Tangentbordsnavigering | allt ska gå att nå med Tab |
| Synlig fokusmarkering | man ska se var man är |
| Alt-text på bilder | eller alt="" om dekorativ |
| Etiketter på formulärfält | kopplade med for/id |
| Klickytor ≥ 24×24 px | särskilt på mobil |
Men AI-gränssnitt har egna problem som WCAG inte skrevs för.
Formellt
Fem AI-specifika tillgänglighetsproblem:
| Problem | Varför det uppstår | Lösning |
|---|---|---|
| Strömmande svar | skärmläsare läser om texten när den ändras | aria-live="polite" på en stabil behållare, uppdatera i block |
| Genererade bilder utan alt-text | det finns ingen upphovsperson som skrev den | generera beskrivning med en VLM, låt användaren rätta |
| Ingen tidsgräns i väntan | oklart om systemet hänger | statusmeddelande i live-region, inte bara en snurra |
| Långa svar | tungt att navigera utan struktur | rubriker, listor, hopplänkar |
| Endast röstgränssnitt | utesluter dövhet och talsvårigheter | alltid ett textalternativ |
Strömmande svar är det svåraste och det vanligaste felet. En naiv implementation uppdaterar samma element token för token; en skärmläsare tolkar det som att innehållet ändras hundratals gånger och läser om från början. Lösningen är att buffra till meningsnivå och använda aria-live="polite" så att uppläsningen inte avbryter sig själv.
Språklig inkludering är den andra halvan:
| Grupp | Behov |
|---|---|
| Svenska som andraspråk | enklare språk på begäran, inte bara ett komplicerat svar |
| Dialekt och talspråk | modellen ska förstå indata som inte är skriftspråk |
| Teckenspråk | textalternativ, och video där det går |
| Lässvårigheter och dyslexi | uppläsning, kortare stycken, tydlig struktur |
| Kognitiv funktionsnedsättning | ett steg i taget, inga oväntade ändringar |
Modellens egen partiskhet är också en tillgänglighetsfråga. En taligenkänning som fungerar sämre för dialekt, brytning eller talsvårigheter utesluter användare i praktiken, även om gränssnittet är perfekt. Mät prestandan per grupp, inte bara totalt.
Testning, i tre nivåer:
| Nivå | Vad | Fångar |
|---|---|---|
| Automatiskt (axe, Lighthouse) | kontrast, etiketter, roller | ~30 % av problemen |
| Manuellt | tangentbord, skärmläsare, 200 % zoom | mycket mer |
| Med verkliga användare | faktisk användning med hjälpmedel | det som ingen annan metod hittar |
Den första nivån är billig och bör ligga i CI — AI-grafen kör npm run a11y med axe-core över alla sidor vid varje bygge. Men den fångar bara en tredjedel, och den sista nivån är den enda som hittar de verkliga problemen.
Kod
<!-- Strömmande AI-svar som fungerar med skärmläsare -->
<div role="region" aria-label="Svar från handledaren">
<div id="status" aria-live="polite" class="sr-only">Handledaren skriver …</div>
<div id="svar" aria-live="polite" aria-atomic="false"></div>
<button id="avbryt">Avbryt</button>
</div>
// Buffra till meningsnivå — annars läser skärmläsaren om texten vid varje token
let buffert = "";
const svar = document.getElementById("svar");
const status = document.getElementById("status");
function taEmot(token) {
buffert += token;
if (/[.!?]\s$/.test(buffert)) { // hel mening klar
const p = document.createElement("p");
p.textContent = buffert.trim();
svar.appendChild(p); // lägg TILL, skriv inte över
buffert = "";
}
}
function klar() {
if (buffert.trim()) {
const p = document.createElement("p");
p.textContent = buffert.trim();
svar.appendChild(p);
}
status.textContent = "Svaret är klart.";
}
# Alt-text för genererade bilder — med möjlighet att rätta
def alt_text(bild, kontext: str) -> dict:
beskrivning = vlm(
"Beskriv bilden i högst 125 tecken för någon som inte ser den. "
"Nämn bara det som syns. Skriv 'framgår inte' om något är oklart.\n"
f"Sammanhang: {kontext}", bild)
return {"alt": beskrivning[:125], "genererad": True, "kan_rattas": True}
# Mät modellprestanda PER GRUPP — inte bara totalt
def wer_per_grupp(asr, testset):
import jiwer
from collections import defaultdict
per = defaultdict(list)
for fall in testset:
w = jiwer.wer(fall["facit"], asr(fall["ljud"]))
per[fall["grupp"]].append(w) # dialekt, brytning, ålder, talsvårighet
return {g: round(sum(v) / len(v), 3) for g, v in sorted(per.items())}
# {'brytning': 0.31, 'dialekt_norrland': 0.19, 'rikssvenska': 0.08, 'talsvarighet': 0.44}
# ↑ totalsiffran hade dolt att systemet är oanvändbart för en av grupperna
Sista utskriften är poängen: en genomsnittlig WER på 0,12 ser bra ut och döljer att systemet i praktiken utesluter användare med talsvårigheter.
Behärskning innebär
- Tillämpar WCAG på AI-gränssnitt
- Hanterar AI-specifika tillgänglighetsproblem
- Testar med hjälpmedel
Logga in för att göra övningarna och bygga upp din behärskning.
Källor
- W3C — WCAG 2.2 — W3C Document License
- DIGG — Vägledning för webbutveckling och tillgänglighet — myndighetsmaterial
- MDN — ARIA live regions — CC BY-SA 2.5