Progressive web apps og tilgængelighed:
kunstens aktuelle stand i 2026
Seks år efter Apple endelig leverede en fungerende installationssti på iOS 16.4 er den progressive web app holdt op med at være en kuriositet og begyndt at blive et udbudsanliggende. Denne primer er til de ingeniørteams, der i 2026 har brug for at vide, hvad en PWA faktisk skylder sine brugere af hjælpeteknologi — og hvor platformen stadig kommer til kort sammenlignet med en rigtig native app.
1. Hvad »PWA-tilgængelighed« betyder i 2026
En progressive web app er ved kørsel tre ting oven på et normalt website: et Web App Manifest, en service worker og en installeret tilstand, der erstatter browser-rammen med operativsystemets eget opgaveskifterindslag. Hvert af de tre lag introducerer sine egne tilgængelighedsforpligtelser — og hvert lag svigter sine brugere af hjælpeteknologi på en anderledes, separat fejlsøgbar måde.
I 2020 kollapsede hele samtalen til »WCAG gælder for PWA’er«, hvilket var teknisk korrekt og operationelt ubrugeligt. I 2026 er samtalen opdelt i de fire overflader, der faktisk betyder noget: install-prompt-UX, de manifest-egenskaber der driver affordances på OS-niveau, overdragelsen mellem browserens tilgængelighedstræ og operativsystemets tilgængelighedstræ når PWA’en startes i standalone-tilstand, og hjælpeteknologiadfærden for service-workerens offline-fallback. WCAG 2.2 styrer dokumentet; platform-integrationslaget er styret af en langt mere plettet blanding af W3C-udkast, leverandørspecifik adfærd og ARIA-konventioner arvet fra webbet.
Denne primer dækker platform-integrationsoverfladen i PWA’er — install-prompts, manifest-egenskaber, standalone-tilstand-hjælpeteknologiadfærd, offline-fallback. Den forudsætter, at det underliggende dokument allerede opfylder WCAG 2.2 AA. En PWA-indpakning oven på en utilgængelig side er stadig en utilgængelig side.
2. Install-prompten
Install-prompten er den mest brugervendte PWA-overflade og er i 2026 stadig den dårligst udviklede. På Chromium er prompten begrænset af beforeinstallprompt, som kun aktiveres efter en heuristisk engagementstærskel, og som websteder typisk kobler til en brugerdefineret »Installer app«-knap. Den brugerdefinerede knap er, hvor tilgængelighed går galt: omtrent én ud af tre Lighthouse-scorende PWA’er gengiver installationsaffordancen som et <div> eller et stiliseret <span> uden rolle, uden tilgængeligt navn og uden tastaturbehandler — usynlig for en skærmlæser, utilgængelig med Tab og uadskillelig fra dekorativt chrome.
Løsningen er unglamourøs og obligatorisk: gengiv installationsaffordancen som en rigtig <button>, angiv et tilgængeligt navn der inkluderer verbet (»Installer Disability World på denne enhed«), eksponer den samme knap for alle inputmodaliteter, og annoncér succes eller fejl via en live-region efter brugeren har afvist bekræftelsesarket på OS-niveau. Det samme gælder tilstandene relateret-applikationer og afvist beforeinstallprompt — begge skal producere en hjælpeteknologi-opfattelig statusændring.
<div onclick="install()">Installer</div>— ikke fokuserbar, ingen rolle, skærmlæseren ser kun ordet »Installer« uden actionable affordance.- Knap skjult indtil
beforeinstallpromptaktiveres — tastaturbrugere lander på et forældet »Installer«-link der ikke gør noget efter hændelsen. - Ingen statusannoncering efter afvisning — hjælpeteknologibrugeren har ingen måde at vide om installationen lykkedes.
<button type="button" aria-label="Installer Disability World">...</button>med eksplicitaria-disablednår installationen endnu ikke er tilgængelig.beforeinstallprompt-handleren gemmer hændelsen; knappen afspejler den resulterende tilstand viaaria-disabledtoglet ved hændelsens ankomst.- En høflig live-region annoncerer »Installeret« eller »Installation afvist« efter
userChoiceløses, så hjælpeteknologibrugeren har en opfattelig bekræftelse.
3. Manifest-overfladen
Web App Manifest voksede stille og roligt mellem 2022 og 2026, og mange af dets nyere egenskaber har direkte tilgængelighedskonsekvenser. Matrixen nedenfor kortlægger de elleve manifest-egenskaber der interagerer med hjælpeteknologi til, hvad hver browser faktisk gør med dem i dag — på tværs af Chrome på Android, Safari på iOS, Edge på Windows og Firefox på desktop. Egenskaber som file_handlers, share_target og window_controls_overlay eksisterede ikke i nogen meningsfuld form i 2021; i 2026 afgør de om PWA’en vises i OS-delingspanelet, åbner filer fra systemets filhåndtering og gengiver sin egen titellinje — alt sammen noget skærmlæserbrugeren skal kunne opfatte og betjene.
| Chrome (Android) | Safari (iOS 16.4+) | Edge (Windows) | Firefox (desktop) | |
|---|---|---|---|---|
name eksponeres for OS-starter | Ja | Ja | Ja | N/A |
short_name vises under hjemmeskærmsikon | Ja | Ja | Ja | N/A |
description læses af hjælpeteknologi i app-infodialog | Ja | Delvist | Ja | N/A |
Adaptive maskbare ikoner (purpose: "maskable") | Ja | Nej | Ja | N/A |
lang + dir overføres til hjælpeteknologi | Ja | Delvist | Ja | N/A |
file_handlers — åbn fra systemfilhåndtering | Ja | Nej | Ja | N/A |
share_target — vises i OS-delingspanel | Ja | Nej | Ja | N/A |
window_controls_overlay titellinjeovertagelse | N/A | N/A | Ja | N/A |
shortcuts — langt-tryk-startermenu | Ja | Nej | Ja | N/A |
display_override (minimal-ui, window-controls-overlay) | Ja | Nej | Ja | N/A |
launch_handler (focus-existing) | Ja | Nej | Ja | N/A |
window_controls_overlay-fældenNår en PWA vælger window_controls_overlay, overtager den OS-titellinjen — herunder det område, hvor en skærmlæser på en native app automatisk ville annoncere vinduetitlen. Apps der anvender denne egenskab, skal eksplicit gengive deres eget fokuserbare, hjælpeteknologi-labellede titellinjekontrolelement inden for safe-area-indsættet, ellers mister skærmlæserbrugere det eneste skærmanker for »hvor er jeg i denne app«.
4. Web ↔ native skærmlæser-overdragelsen
Det eneste sværeste fejlsøgningsproblem i PWA-tilgængelighed i 2026 er det, der sker når brugeren krydser sømmen mellem standalone-tilstand PWA-chrome og selve operativsystemet. På Android læser TalkBack manifest-name når brugeren fokuserer hjemmeskærmsikonet og overgår derefter til at læse appens interne tilgængelighedstræ når PWA’en starter; på iOS 16.4+ gør VoiceOver det samme for en installeret PWA, men med én vigtig detalje — det første fokuserbare element efter start annonceres uden det app-niveau-kontekst, som en native iOS-app ville levere via sin UIWindow-titel.
PWA-forfatteren har ét redskab til at bygge bro over denne kløft: ved koldstart fokuseres en overskrift eller et main-region-landmark der inkluderer appnavnet i sit tilgængelige label, og dokumentets <title> sættes til en streng som OS-opgaveskifteren vil læse, når brugeren skifter mellem apps. Uden dette mister skærmlæserbrugeren det kontekstuelle signal om at de har skiftet applikation — en »hvor er jeg«-fejl der ikke eksisterer for native apps.
»I 2024 fortalte en Bluetooth-tastatur VoiceOver-bruger os, på en PWA vi havde certificeret til WCAG 2.2 AA, at de ikke vidste, at de var skiftet ud af Safari og ind i vores app. Dokumentet var tilgængeligt. Overdragelsen var ikke.«
5. Offline + hjælpeteknologiadfærd
Når service workeren serverer en offline-fallbackside, opstår to hjælpeteknologispecifikke fejltilstande: det fokus der var inde på den nu aflæssede side tabes stille og roligt på dokumentets body, og offline-siden selv bruger sjældent en live-region til at fortælle skærmlæserbrugeren hvad der netop skete. Resultatet er en bruger der hører én annoncering af offline-sidens titel (hvis de er heldige) og ellers oplever et totalt tab af kontekst.
Løsningen er at behandle offline-overgangen som en tilstandsændring, annoncere den via en høflig aria-live-region, gendanne fokus til et kendt landmark på offline-siden og levere en »Prøv igen«-kontrol som en rigtig knap frem for det »Genindlæs«-link de fleste service-worker-boilerplates leverer. Det samme gælder foreground-sync-gendannelsesstien: når forbindelsen genoptages og service workeren tømmer køen, er det også en tilstandsændring som hjælpeteknologibrugeren skal adviseres om.
En høflig live-region annoncerer »Du er offline« ved overgang. Fokus flyttes til offline-sidens primære overskrift. En tydeligt labellet <button>Prøv igen</button> er det første interaktive element. Ved genopkobling siger en anden høflig annoncering »Forbindelsen er genoprettet«, og fokus gendannes til hvad brugeren sidst interagerede med.
6. iOS Safari vs Android vs native
Spørgsmålet »skal vi levere en PWA eller en native app?« har nu en tilgængelighedsdimension såvel som en funktionskomplethedsaspekt. Nedenfor sammenligner vi den samme hypotetiske nyhedslæser-app leveret på fire måder — som en PWA på Android, som en PWA på iOS 16.4+, som en native iOS-app og som en native Android-app — på tværs af de fem overflader en skærmlæserbruger rammer først.
| PWA · Android | PWA · iOS 16.4+ | Native · iOS | Native · Android | |
|---|---|---|---|---|
| Installationsaffordance opdagelig af hjælpeteknologi | Hvis udvikleren gjorde det rigtigt | Tilføj-til-hjemmeskærm-menu — opdagelig | App Store — fuldt tilgængeligt | Play Store — fuldt tilgængeligt |
| App-navn + beskrivelse på startikon | Ja | Ja (name + apple-mobile-web-app-title) | Ja (UIKit Info.plist) | Ja (Android manifest) |
| Adaptive ikoner (tematiseret / monokrom) | Ja (maskable) | Nej | Ja | Ja |
| Opgaveskifter-kontekst annonceret | Ja | Delvist | Ja (UIWindow-titel) | Ja |
| OS-delingspanelindgang | Ja (share_target) | Nej | Ja (UIActivity) | Ja (Intent filter) |
| Langt-tryk-genveje | Ja (shortcuts) | Nej | Ja (UIApplicationShortcutItem) | Ja |
| Push-notifikation med tilgængeligt indhold | Ja | Ja (siden iOS 16.4) | Ja | Ja |
| Brugerdefineret rotor / hurtignavigation | N/A | N/A | Ja | Ja |
iOS 16.4 låste installationsstien, push-notifikationer og badging API op for PWA’er, og iOS 17 lukkede yderligere kløften på den grundlæggende startoverflade. Men file_handlers, share_target, shortcuts og window_controls_overlay er fortsat ikke understøttet. For en hjælpeteknologibruger der er afhængig af OS-delingspanelet til at flytte indhold mellem apps, er en PWA på iOS stadig en markant mindre overflade end en PWA på Android eller en native iOS-app.
Konklusion: spilleplanen for 2026
Lever installationsaffordancen som en rigtig <button> med et tilgængeligt navn. Kobl en høflig live-region til userChoice-resultatet. Udfyld name, short_name, description, lang og dir i manifestet, og lever maskbare ikoner til Android. Hvis du vælger window_controls_overlay, skal du gengive og labelle din egen titellinje; vælger du file_handlers eller share_target, skal du behandle den resulterende start som en tilstandsændring og annoncere den ved indgang.
Gendan fokus til et labellet landmark hver gang skærmlæserbrugeren krydser sømmen — første start, opgaveskifter-retur, offline-overgang, share-target-start, genopkobling. Behandl hver krydsning som en separat hændelse der skylder brugeren en opfattelig annoncering og et kendt fokusanker. Intet af dette er svært; næsten intet af det leveres konsekvent.
En PWA i 2026 kan være nærmest uadskillelig fra en native app for en hjælpeteknologibruger — på Android. På iOS er den tættere end den var og har stadig en reel kløft. Kløften lukker sig med omtrent én manifest-egenskab om året. For udbudsteams der vælger mellem en PWA og en native app er tilgængelighedsspørgsmålet ikke længere »kan en PWA være tilgængelig?« — det kan den. Spørgsmålet er, om det team der bygger den, har læst de elleve manifest-rækker ovenfor og accepteret, at hver enkelt er en del af det, de skal levere.
»En PWA-indpakning fritager ikke et team for platform-integrationsarbejdet. Den tilføjer elleve nye tilgængelighedsoverflader og beder teamet om at håndtere hver enkelt på hver platform, det leverer til.«