ARIA (Accessible Rich Internet Applications) ger utvecklare en kraftfull verktygslåda för att göra dynamiska, komplexa webbgränssnitt tillgängliga för skärmläsaranvändare — men felanvändning är utbredd och kostsam. Den här guiden går igenom varje större kategori av ARIA-roller, förklarar de gyllene reglerna för ARIA-användning och visar konkreta kodexempel så att du kan använda det på rätt sätt.
Här är en nykter siffra: enligt WebAIMs analys av de en miljon mest besökta webbplatsers startsidor har sidor som inkluderar ARIA-attribut i genomsnitt betydligt fler upptäckbara tillgänglighetsfel än sidor utan ARIA överhuvudtaget. Det är inte ett argument mot att använda ARIA — det är ett argument för att använda det korrekt. ARIA är ett av de mest kraftfulla verktygen i den moderna tillgänglighetsverktygslådan, men det är också ett av de mest missförstådda. Gör du rätt öppnar du på ett meningsfullt sätt din webbplats för miljoner användare med funktionsnedsättningar. Gör du fel försämrar du aktivt deras upplevelse.
Vad är ARIA och varför finns det?
ARIA står för Accessible Rich Internet Applications. Det är en uppsättning HTML-attribut, definierade av W3C:s Web Accessibility Initiative, som gör det möjligt för utvecklare att kommunicera semantisk information till hjälpmedel som skärmläsare, brailledisplayer och röststyrningsprogram. När en webbläsare renderar en sida bygger den två parallella strukturer: DOM:en (det du ser) och Accessibility Tree (det hjälpmedel läser). ARIA-attribut låter dig modifiera detta Accessibility Tree för att korrekt beskriva vad anpassade komponenter är och hur de beter sig.
Behovet av ARIA växte fram ur ett verkligt problem. HTML designades för dokument, inte applikationer. När webben utvecklades till en plattform för rika, interaktiva upplevelser — flikgränssnitt, modala dialoger, drag-and-drop, live-datastreamar — kunde inbyggda HTML-element inte förmedla vad dessa komponenter var eller hur de fungerade till en skärmläsare. ARIA fyller den luckan. Som MDN uttrycker det, "kompletterar ARIA HTML så att interaktioner och widgets som vanligtvis används i applikationer kan föras vidare till hjälpmedel när det annars inte finns någon mekanism."
ARIA ändrar inte den visuella presentationen. Det lägger inte till beteende. Det ger inte tangentbordsstöd automatiskt. Det modifierar enbart vad Accessibility Tree exponerar för hjälpmedel. Detta är en viktig skillnad — en som orsakar många av de fel utvecklare gör när de sträcker sig efter ARIA som en genväg.
Specifikationen underhålls av W3C som WAI-ARIA, för närvarande i version 1.2, med 1.3 aktivt under utveckling. Den tillhandahåller en ontologi av roller, tillstånd och egenskaper som tillsammans beskriver tillgängliga användargränssnittselement över hela spannet av moderna webb-mönster.
De tre pelarna: roller, tillstånd och egenskaper
Innan du skriver en enda rad ARIA behöver du förstå de tre distinkta byggstenar som specifikationen tillhandahåller. De är inte utbytbara, och att blanda ihop dem är en av de vanligaste källorna till fel.
Roller definierar vad ett element är. En roll besvarar frågan: vilken typ av sak tittar jag på? Exempel inkluderar button, dialog, navigation, tablist och progressbar. Du applicerar en roll med attributet role: <div role='button'>. Rollen kommunicerar elementets syfte till hjälpmedel så att användaren vet hur hen ska interagera med det.
Tillstånd beskriver det dynamiska tillståndet hos ett element — något som ändras när användaren interagerar med sidan. Attributet aria-expanded talar om för en skärmläsare om en hopfällbar sektion är öppen eller stängd. aria-checked återspeglar om en anpassad kryssruta är ikryssad. Tillstånd måste hållas synkroniserade med JavaScript; ett statiskt aria-expanded='false' som aldrig ändras är inte bara värdelöst utan direkt vilseledande.
Egenskaper ger beskrivande, vanligtvis mer stabil information om ett element. aria-label ger ett element ett tillgängligt namn som ersätter dess synliga text. aria-labelledby pekar på ett annat element vars text fungerar som etikett. aria-describedby länkar till kompletterande beskrivande text. aria-required signalerar att ett formulärfält måste fyllas i. Medan tillstånd förväntas ändras ofta tenderar egenskaper att sättas en gång och lämnas ifred — även om det finns undantag.
Roller definierar vad ett element är. Tillstånd definierar hur det beter sig just nu. Egenskaper ger ytterligare beskrivande kontext. Du behöver alla tre som samverkar för att skapa en fullt tillgänglig anpassad komponent.
Den gyllene regeln — och varför den är viktigare än du tror
W3C:s första regel för ARIA-användning är entydig: om du kan använda ett inbyggt HTML-element eller attribut med den semantik och det beteende du behöver redan inbyggt, använd det. Sträck dig inte efter ARIA först. Detta kallas ibland principen "ingen ARIA är bättre än dålig ARIA" — ett uttryck som speglar den mycket verkliga faran med välmenande men felaktig ARIA-användning.
Inbyggda HTML-element har implicita ARIA-semantiker gratis. Ett <button>-element exponeras redan i Accessibility Tree som en knapp. Det är redan tangentbordsfokuserbart. Det triggas redan av både Enter- och mellanslagstangenten. Det annonserar redan sin etikett. I samma ögonblick som du skriver <div role='button'> har du tagit på dig ansvaret att manuellt återskapa allt det beteendet — tangentbordshantering, fokusstyrning, uppdatering av tillstånd — i JavaScript. Detta är inte en teoretisk fråga. Att glömma tangentbordsstöd på en anpassad knapp är ett av de vanligaste och mest skadliga ARIA-felen i produktion.
De fall där ARIA verkligen är nödvändigt tenderar att klustra kring några få scenarier: när du bygger en komplex widget som saknar HTML-motsvarighet (en karusell, en combobox med autokomplettering, en trädvy); när du åtgärdar äldre markup där omstrukturering av DOM:en är alltför kostsam; när du bygger en web component som behöver exponera anpassad semantik; eller när stöd i webbläsare och hjälpmedel för ett inbyggt element är så inkonsekvent att ARIA-motsvarigheten fungerar mer tillförlitligt i praktiken.
Utanför dessa scenarier bör din första instinkt alltid vara semantisk HTML. Använd <nav> istället för <div role='navigation'>. Använd <main> istället för <div role='main'>. Använd <button> istället för <div role='button'>. De inbyggda elementen är mer robusta, bättre stödda och kräver betydligt mindre underhåll.
En rundtur bland de viktigaste ARIA-rollkategorierna
WAI-ARIA-specifikationen organiserar roller i flera kategorier. Att förstå dessa kategorier hjälper dig att veta vilken roll du ska välja och när.
Landmärkesroller
Landmärkesroller markerar de viktigaste regionerna på en sida och gör det möjligt för skärmläsaranvändare att hoppa direkt till nyckelsektioner med tangentbordsgenvägar. De mest använda landmärkesrollerna är banner, navigation, main, complementary, contentinfo, search och form. Var och en av dessa har en direkt inbyggd HTML-motsvarighet: <header>, <nav>, <main>, <aside>, <footer> och så vidare. I praktiken innebär detta att landmärkesroller nästan alltid är överflödiga om du använder modern semantisk HTML. Lägg bara till dem när du sitter fast med icke-semantisk markup av strukturella skäl.
<!-- Prefer this -->
<header>
<nav>...</nav>
</header>
<main>...</main>
<footer>...</footer>
<!-- Use ARIA only when you must use divs -->
<div role='banner'>
<div role='navigation'>...</div>
</div>
<div role='main'>...</div>
<div role='contentinfo'>...</div>
Widgetroller
Widgetroller beskriver interaktiva komponenter som användaren manipulerar direkt. Det är här ARIA gör sitt viktigaste arbete, eftersom många widgetmönster saknar inbyggd HTML-motsvarighet. Vanliga widgetroller inkluderar button, checkbox, dialog, menu, menuitem, slider, tablist, tab, tabpanel, tooltip, tree och combobox.
När du använder en widgetroll tar du på dig fullt ansvar för tangentbordsinteraktion. WAI-ARIA Authoring Practices Guide (APG) definierar förväntade tangentbordsmönster för varje widgettyp — till exempel piltangenter för att flytta mellan flikar, Escape för att stänga en dialog, Home och End för att hoppa till första och sista objektet i en listbox. Att misslyckas med att implementera dessa mönster innebär att din komponent är tekniskt etiketterad men funktionellt oanvändbar för användare som bara använder tangentbord.
<!-- A custom tab interface -->
<div role='tablist' aria-label='Account settings'>
<button role='tab' aria-selected='true' aria-controls='panel-profile' id='tab-profile'>
Profile
</button>
<button role='tab' aria-selected='false' aria-controls='panel-security' id='tab-security' tabindex='-1'>
Security
</button>
</div>
<div role='tabpanel' id='panel-profile' aria-labelledby='tab-profile'>
<p>Profile settings content</p>
</div>
<div role='tabpanel' id='panel-security' aria-labelledby='tab-security' hidden>
<p>Security settings content</p>
</div>
Live region-roller
Live regions är en av ARIA:s mest genuint användbara funktioner. De gör det möjligt för hjälpmedel att annonsera dynamiska innehållsuppdateringar — saker som statusmeddelanden, felmeddelanden, chattmeddelanden och laddningsindikatorer — för användare som inte kan se att skärmen ändras. Utan live regions kanske en skärmläsaranvändare som skickar in ett formulär aldrig får veta om det lyckades eller misslyckades, om inte fokus uttryckligen flyttas till resultatet.
Kärnrollerna för live regions är alert, status, log, marquee och timer. Rollen alert har implicit inställningen aria-live='assertive', vilket innebär att den avbryter användaren omedelbart — lämpligt för fel eller brådskande varningar. Rollen status använder aria-live='polite', och väntar tills användaren är klar med sin aktuella uppgift innan den annonserar — idealiskt för framgångsmeddelanden och förloppsindikatorer.
<!-- Polite status message for non-urgent feedback -->
<div role='status' aria-live='polite' aria-atomic='true'>
<!-- Dynamically inject text here with JavaScript -->
</div>
<!-- Assertive alert for errors that demand immediate attention -->
<div role='alert'>
Please correct the errors below before submitting.
</div>
Nyckeln till live regions är att containern måste finnas i DOM:en innan det dynamiska innehållet injiceras. En live region som skapas och fylls samtidigt missas ofta av skärmläsare. Bygg containern vid sidladdning och fyll den med JavaScript när händelser inträffar.
Roller för dokumentstruktur
Roller för dokumentstruktur — såsom article, list, listitem, table, row, cell, figure och heading — beskriver den strukturella organiseringen av innehåll. De flesta av dessa har nu ersatts av inbyggda HTML-element, och MDN noterar att majoriteten av rollerna för dokumentstruktur "inte längre bör användas eftersom webbläsare nu stöder semantiska HTML-element med samma betydelse." Det främsta undantaget är när du arbetar med anpassade renderingsmiljöer, web components eller SVG-baserat innehåll där inbyggda HTML-element inte är tillgängliga.
Viktiga ARIA-egenskaper som varje utvecklare bör känna till
Utöver roller förekommer flera ARIA-egenskaper ständigt i verkligt tillgänglighetsarbete. Det är dessa du kommer att använda oftast:
- aria-label: Ger ett tillgängligt namn för ett element när ingen synlig textetikett finns eller när den synliga texten är otillräcklig. Vanliga användningsfall: knappar som bara består av en ikon, sökfält utan synlig etikett och stängknappar på modaler. Observera att
aria-labelåsidosätter all synlig text eller inbyggd etikett, så använd det med försiktighet på element som har synlig text. - aria-labelledby: Pekar på ett eller flera element vars textinnehåll fungerar som det tillgängliga namnet. Mer robust än
aria-labeli komplexa fall eftersom etiketttexten hålls synkroniserad med det synliga innehållet. Accepterar en blankstegsseparerad lista med element-ID:n, och hjälpmedel konkatenerar den refererade texten i ordning. - aria-describedby: Länkar till kompletterande beskrivningstext — inte ett namn, utan ytterligare kontext. Använd det för att koppla formulärfält till deras felmeddelanden, eller för att associera en tooltip med elementet den beskriver. Skärmläsare annonserar vanligtvis detta efter elementets namn och roll.
- aria-hidden: Tar bort ett element helt från Accessibility Tree. Ovärderligt för dekorativa ikoner, duplicerat innehåll och visuella element som bara skulle skapa brus för skärmläsaranvändare. Applicera aldrig
aria-hidden='true'på ett fokuserbart element — en användare kan fortfarande tabba till det, men får ingen information om det. - aria-expanded: Kommunicerar om ett hopfällbart element — en dropdown, en accordion eller en disclosure-widget — för närvarande är öppet eller stängt. Måste togglas dynamiskt med JavaScript; ett statiskt värde är sämre än att utelämna attributet helt.
- aria-current: Indikerar det aktuella objektet inom en uppsättning, oftast använt i navigation för att markera den aktiva sidlänken (
aria-current='page') eller det aktuella steget i en flerstegsprocess.
Vanliga ARIA-misstag som faktiskt skadar tillgängligheten
Med tanke på att sidor med ARIA tenderar att visa fler tillgänglighetsfel än de utan, är det värt att vara tydlig med vad som oftast går fel. Detta är inte specialfall — det är mönster som förekommer i produktionskod varje dag.
Att använda ARIA-roller på element med stark inbyggd semantik. Vissa HTML-element har det specifikationen kallar "strong native semantics" — betydelser som är djupt inbakade i webbläsaren och inte säkert kan åsidosättas. Att placera en olämplig roll på ett <button> eller ett <input> kan göra att webbläsaren ignorerar ARIA-rollen helt, eller skapa motsägelsefullt beteende som förvirrar hjälpmedel. Rollen du deklarerar måste vara lämplig för elementet du sätter den på.
Att glömma tangentbordsstöd med widgetroller. ARIA:s role='button' talar om för en skärmläsare att elementet är en knapp. Det gör inte elementet tangentbordsopererbart. Om du använder ett <div> med role='button' måste du lägga till tabindex='0' för att göra det fokuserbart, och du måste lägga till händelselyssnare för både Enter- och mellanslagstangenten. Att missa någon del av detta bryter upplevelsen för användare som bara använder tangentbord.
<!-- Incomplete and inaccessible -->
<div role='button' onclick='doSomething()'>Submit</div>
<!-- Correct custom button implementation -->
<div
role='button'
tabindex='0'
onclick='doSomething()'
onkeydown='if(event.key==="Enter"||event.key===" ")doSomething()'
>Submit</div>
<!-- Or, the right answer: just use a button -->
<button onclick='doSomething()'>Submit</button>
Att använda aria-hidden på fokuserbara element. Att applicera aria-hidden='true' på ett fokuserbart element döljer det från Accessibility Tree men inte från tangentbordsnavigering. En tangentbordsanvändare kan fortfarande tabba till det, får ingen information om det och har inget sätt att veta vad det gör. Detta är ett WCAG 2.1-fel under framgångskriterium 4.1.2 (Name, Role, Value).
Inaktuella ARIA-tillstånd. Att misslyckas med att uppdatera aria-expanded, aria-checked, aria-selected och liknande tillstånd när UI:t ändras lämnar skärmläsaranvändare med en fundamentalt felaktig bild av gränssnittet. En meny som visuellt öppnas men vars trigger fortfarande läses som aria-expanded='false' är aktivt vilseledande.
Redundanta roller. Att lägga till role='navigation' på ett <nav>-element, eller role='button' på ett <button>, gör inget nyttigt. Det skräpar ner koden och kan ibland förvirra vissa kombinationer av hjälpmedel. Lita på den inbyggda semantiken.
ARIA och WCAG: att förstå kopplingen
ARIA är inte WCAG. De är separata specifikationer som samverkar. WCAG (Web Content Accessibility Guidelines) definierar vad — de resultat som krävs för tillgängligt innehåll. ARIA är en del av hur — en teknisk mekanism för att uppnå vissa av dessa resultat. Det mest relevanta WCAG-framgångskriteriet för ARIA är 4.1.2: Name, Role, Value, som kräver att alla användargränssnittskomponenter har ett namn, exponerar sin roll för hjälpmedel och kommunicerar sitt tillstånd och sina egenskaper programmatiskt. ARIA är ett av de primära verktygen för att uppfylla detta kriterium för anpassade komponenter.
ARIA stödjer också flera andra framgångskriterier. Landmärkesroller bidrar till 2.4.1 (Bypass Blocks) genom att möjliggöra att block kan hoppas över. Live regions är ofta rätt verktyg för att uppfylla 4.1.3 (Status Messages) i WCAG 2.1, som kräver att statusmeddelanden ska vara programmatiskt avgörbara utan att få fokus. Korrekt användning av aria-label och aria-labelledby hjälper till att uppfylla 2.4.6 (Headings and Labels) och 1.3.1 (Info and Relationships).
Det är värt att notera att WCAG-efterlevnad i allt högre grad är ett juridiskt krav. European Accessibility Act trädde i full kraft i juni 2025 och utökade obligatoriska tillgänglighetskrav till ett brett spektrum av digitala tjänster i privat sektor i EU:s medlemsstater. I USA fortsätter ADA att tolkas som att den inkluderar webbtillgänglighet, och federala krav enligt Section 508 gäller för statliga och federalt finansierade organisationer. Att förstå ARIA korrekt är inte bara bästa praxis — det är i allt högre grad en del av dina efterlevnadsskyldigheter.
Testa din ARIA-implementering
Det enda sättet att veta om din ARIA-implementering faktiskt fungerar är att testa den med verkliga hjälpmedel. Automatiserade verktyg som axe, WAVE och Lighthouse kan fånga strukturella överträdelser — en saknad obligatorisk egenskap, en ogiltig roll, ett aria-hidden applicerat på ett fokuserbart element — men de kan inte tala om för dig om en skärmläsare annonserar din modal på ett sätt som är begripligt, eller om tangentbordsnavigering genom din anpassade trädwidget följer förväntade mönster.
För manuell testning är de viktigaste skärmläsarna att täcka JAWS och NVDA på Windows (tillsammans representerar de den stora majoriteten av skärmläsaranvändning på desktop) och VoiceOver på macOS och iOS. TalkBack täcker Android. Varje kombination av skärmläsare och webbläsare kan bete sig olika, så testning över minst två kombinationer rekommenderas starkt. Testa varje interaktivt tillstånd: öppna dialogen, expandera accordionen, välj alternativet, trigga alerten. Bekräfta att annonseringen matchar vad en seende användare skulle förstå av att titta på samma gränssnitt.
När du testar anpassade widgets, gå igenom tangentbordsinteraktionsmodellen som definieras i WAI-ARIA Authoring Practices Guide för den widgettypen. Om din tablist inte svarar på piltangenter, eller din dialog inte fångar fokus, är det fel oavsett hur korrekt ARIA-markupen ser ut i en automatiserad granskning.
Viktiga lärdomar
- Föredra alltid semantisk HTML framför ARIA. Inbyggda element som
<button>,<nav>,<main>och<dialog>har inbyggda tillgänglighetssemantiker som är mer robusta och kräver betydligt mindre kod än deras ARIA-på-en-div-motsvarigheter. Sträck dig efter ARIA bara när inbyggd HTML verkligen inte räcker till. - ARIA-roller är ett löfte, inte en genväg. Att applicera
role='button'ellerrole='dialog'på ett anpassat element innebär att du förbinder dig att implementera den fullständiga tangentbordsinteraktionsmodellen för den widgettypen. Roller utan motsvarande beteende skapar förvirring och WCAG-fel. - Håll ARIA-tillstånd synkroniserade med ditt UI. Dynamiska attribut som
aria-expanded,aria-checked,aria-selectedocharia-live-innehåll måste uppdateras i JavaScript när UI:t ändras. Ett inaktuellt tillstånd är aktivt skadligt — det kommunicerar fel information till användaren. - Använd live regions för dynamiska innehållsuppdateringar. Allt innehåll som uppdateras utan sidomladdning — notiser, felmeddelanden, laddningstillstånd, chattflöden — behöver en
aria-live-region eller en lämplig roll somalertellerstatusså att skärmläsaranvändare får samma information som seende användare ser automatiskt. - Testa med verkliga hjälpmedel, inte bara automatiserade verktyg. Automatiska skannrar fångar strukturella ARIA-fel men kan inte validera om din implementering ger en sammanhängande, användbar upplevelse. Manuell testning med JAWS, NVDA och VoiceOver är det enda sättet att täppa till den luckan.
