Komponenten · ARIA-Techniken
ARIA: Rollen, States & Properties
Was sind ARIA-Rollen, -States und -Properties? Kurz gesagt: Die Rolle legt fest, was ein Element ist (role="tab"), Eigenschaften beschreiben stabile Merkmale wie den zugänglichen Namen (aria-labelledby), und Zustände wie aria-expanded melden, was sich während der Bedienung ändert. All das landet im Accessibility Tree – einer vereinfachten Parallelstruktur zum DOM, aus der Screenreader für jedes Bedienelement Name, Rolle und Wert vorlesen; genau diese Dreiheit fordert das WCAG-Kriterium 4.1.2.
Wer diese Dreiteilung einmal verstanden hat, liest ARIA-Markup deutlich entspannter – und setzt es sparsamer und treffsicherer ein. Vorausgesetzt natürlich, man beachtet zuerst die erste Regel von ARIA und greift überhaupt nur dort zu ARIA, wo natives HTML nicht ausreicht.
Das Wichtigste in Kürze
- Rolle (
role="tab") sagt, was ein Element ist. Eigenschaft (aria-labelledby) beschreibt ein stabiles Merkmal. Zustand (aria-expanded) meldet, was sich beim Bedienen ändert. - Technisch sind States und Properties beides
aria-*-Attribute. Die Trennung steht in der Spezifikation und hilft beim Denken, nicht beim Schreiben. - Alles landet im Accessibility Tree – der vereinfachten Parallelstruktur zum DOM, aus der Screenreader Name, Rolle und Wert vorlesen.
- Genau diese Dreiheit verlangt WCAG 4.1.2 Name, Rolle, Wert (Stufe A) für jedes Bedienelement.
- ARIA ändert nur die Ansage, nie das Verhalten. Ein
role="button"am<div>liefert weder Fokus noch Tastaturbedienung – beides musst du selbst nachbauen. - Jede Rolle erwartet bestimmte Zustände:
role="checkbox"ohnearia-checkedist unvollständig,aria-expandedan einemrole="img"bedeutungslos. - Zustände müssen synchron gepflegt werden. Ein
aria-expanded="false"an einem offenen Menü ist schlimmer als gar kein ARIA, weil es aktiv falsch informiert. - Faustregel bleibt die erste Regel von ARIA: kein ARIA ist besser als schlechtes ARIA – natives HTML bringt Rolle, Zustand und Bedienung schon mit.
Am einfachsten merke ich mir die drei so: Die Rolle sagt, was etwas ist. Die Eigenschaft beschreibt eine Beschaffenheit. Der Zustand hält fest, in welcher Verfassung es gerade ist. An einem echten Bauteil sieht das so aus:
Der Accessibility Tree: wo ARIA wirklich landet
Um ARIA zu verstehen, hilft ein Blick dahin, wo es wirkt. Parallel zum DOM baut der Browser den Accessibility Tree auf – eine vereinfachte Struktur, die er der assistiven Technik (Screenreadern, Sprachsteuerung, Braillezeilen) über die Betriebssystem-Schnittstellen anbietet. Dabei fliegt alles raus, was keine Bedeutung trägt: reine Styling-<div>s, generische Container ohne Namen, display: none-Inhalte. Was bleibt, ist ein Baum aus Knoten, von denen jeder im Wesentlichen vier Dinge trägt: Name, Rolle, Wert und Zustände.
DOM Accessibility Tree
──────────────────────────── ─────────────────────────────────────
<div class="wrapper"> (der wrapper-div taucht nicht auf)
<nav aria-label="Hauptmenü"> navigation "Hauptmenü"
<ul> list
<li><a href="../">Start</a> listitem
link "Start"
<div class="deko"></div> (weg – trägt nichts bei)
<button aria-expanded="false"> button "Menü" – Zustand: reduziert
Menü
</button>
Daraus folgt der wichtigste Satz dieser Seite: ARIA verändert ausschließlich den Accessibility Tree – niemals das Verhalten. Ein role="button" macht aus einem <div> keinen fokussierbaren, per Leertaste auslösbaren Button; es ändert nur die Ansage. Fokus, Tastaturbedienung und das Aktualisieren der Zustände bleiben deine Aufgabe (per HTML oder JavaScript). Genau deshalb ist natives HTML fast immer die bessere Wahl: <button> bringt Rolle, Fokus und Verhalten mit.
Praktisch prüfen lässt sich das direkt im Browser: In den Chrome DevTools zeigt der Tab „Barrierefreiheit“ (im „Elemente“-Panel rechts neben „Stile“) für jedes Element den berechneten Namen, die Rolle und alle ARIA-Zustände – eine schnelle Selbstkontrolle, bevor du überhaupt einen Screenreader startest.
Name, Rolle, Wert: was der Screenreader ansagt
Ein Screenreader liest für jedes Bedienelement dieselbe Formel vor: erst der Name, dann die Rolle, dann Wert oder Zustand. So klingt das konkret:
| Markup | Ansage (sinngemäß) |
|---|---|
<button>Speichern</button> |
„Speichern, Schalter“ |
<button aria-expanded="false">Menü</button> |
„Menü, Schalter, reduziert“ |
<input type="checkbox" checked> + Label „AGB“ |
„AGB, Kontrollfeld, aktiviert“ |
<a href="…">Impressum</a> |
„Impressum, Link“ |
<input type="range" …> + Label „Lautstärke“ |
„Lautstärke, Schieberegler, 50 %“ |
Der Name entsteht dabei nach einer festen Rangfolge, der sogenannten Accessible-Name- Berechnung: aria-labelledby schlägt aria-label, beide schlagen die native Beschriftung (<label>, Button-Text, alt), und ganz am Ende steht als Notnagel title. Das ist nützlich – aber auch eine Falle, denn ein unbedachtes aria-label kann einen guten sichtbaren Text stillschweigend überschreiben (und verletzt dann schnell WCAG 2.5.3, „Sichtbare Beschriftung im Namen“). Ich setze Namen deshalb am liebsten über echtes, sichtbares Markup und greife zu aria-label nur, wenn es sein muss (siehe Labels).
Rollen: was ein Element ist
Eine Rolle legt die Bedeutung eines Elements fest – role="tab", role="dialog", role="alert". Sie wird in der Regel einmal gesetzt und ändert sich nicht. Wichtig: Viele Rollen sind in HTML schon eingebaut. Ein <nav> ist eine Navigation, ein <button> ist ein Button – hier ein explizites role zu setzen, ist überflüssig.
<!-- Überflüssig: das Element trägt die Rolle bereits -->
<nav role="navigation">…</nav>
<!-- Sinnvoll: HTML hat dafür kein natives Element -->
<div role="tablist">…</div>
Die WAI-ARIA-Spezifikation (Version 1.2, seit Juni 2023 offizieller W3C-Standard) definiert über 60 Rollen; MDN gruppiert sie in sechs Kategorien – als Landkarte reicht dieser Überblick:
| Kategorie | Beispiele | Wofür |
|---|---|---|
| Widget-Rollen | tab, slider, switch, searchbox |
einzelne Bedienelemente |
| Komposit-Rollen | tablist, menu, listbox, grid |
Widgets, die andere Widgets enthalten |
| Dokumentstruktur | list, table, img, heading |
Inhalte gliedern (meist nativ vorhanden) |
| Landmark-Rollen | navigation, main, banner, search |
Seitenbereiche – siehe Landmarks |
| Live-Region-Rollen | alert, status, log |
Bereiche, deren Änderungen angesagt werden |
| Fenster-Rollen | dialog, alertdialog |
eigenständige Fenster im Fenster |
Daneben kennt die Spezifikation abstrakte Rollen (widget, composite, input …). Sie sind nur das interne Ordnungssystem der Spec – im Markup haben sie nichts verloren, und Prüfwerkzeuge wie axe melden sie als Fehler.
Eine Rolle ist immer ein Versprechen: role="tab" kündigt das Tabs-Verhalten an – inklusive Pfeiltasten-Navigation. Dieses Verhalten musst du dann auch tatsächlich liefern, sonst führt die Rolle in die Irre.
Eigenschaften: stabile Merkmale
Eigenschaften (Properties) beschreiben Merkmale, die sich meist nicht über die Zeit ändern. Die mit Abstand wichtigsten betreffen den zugänglichen Namen und die Beschreibung eines Elements:
| Attribut | Wirkung |
|---|---|
aria-label |
setzt den Namen direkt als Text |
aria-labelledby |
setzt den Namen über die id eines anderen Elements |
aria-describedby |
verknüpft eine ergänzende Beschreibung (z. B. Hilfetext, Fehler) |
aria-controls |
verweist auf das Element, das gesteuert wird |
aria-haspopup |
kündigt ein aufklappbares Element an |
aria-describedby ist die Eigenschaft, die mir im Formularalltag am häufigsten begegnet – sie trägt Hilfetexte und Fehlermeldungen ans Feld.
Zwei Regeln sparen Debugging-Zeit: Erstens gibt es globale Attribute, die überall erlaubt sind (aria-hidden, aria-describedby, aria-live …) – und rollengebundene, die nur an bestimmten Rollen wirken: aria-selected gehört zu tab, option oder row; aria-checked zu Checkbox-artigen Rollen. Ein aria-selected am normalen Button ist schlicht wirkungslos. Zweitens verlieren aria-label und aria-labelledby ihre Wirkung auf Elementen mit role="presentation" bzw. role="none" – wer einem Element die Semantik nimmt, kann es nicht gleichzeitig benennen.
Die aria-value-Familie: Werte für eigene Regler
Für alles, was einen einstellbaren oder gemessenen Wert hat – Slider, Fortschritts- und Bewertungsanzeigen –, gibt es ein eigenes Eigenschafts-Quartett:
<div
role="slider"
tabindex="0"
aria-valuemin="0"
aria-valuemax="5"
aria-valuenow="3"
aria-valuetext="3 von 5 Sternen"
aria-label="Bewertung"
></div>
aria-valuemin und aria-valuemax stecken den Bereich ab, aria-valuenow hält den aktuellen Wert (und wird bei Bedienung wie ein Zustand aktualisiert), und aria-valuetext übersetzt die nackte Zahl in eine verständliche Ansage – „3 von 5 Sternen“ statt „3“. Die ehrliche Empfehlung dazu: Native Elemente wie <input type="range">, <progress> und <meter> bringen all das fertig mit – der nachgebaute Slider ist die Ausnahme, nicht die Regel (siehe Toggles & Custom Controls).
Zustände: was sich ändert
Zustände (States) beschreiben die aktuelle Verfassung und werden dynamisch aktualisiert, meist per JavaScript. Sie sind das, was während der Bedienung lebt:
| Attribut | Bedeutung |
|---|---|
aria-expanded |
auf-/zugeklappt (Menüs, Akkordeons) |
aria-selected |
ausgewählt (Tabs, Optionen) |
aria-checked |
angehakt (nachgebaute Checkboxen, Switches) |
aria-pressed |
gedrückt (Umschalt-Buttons) |
aria-current |
aktuelles Element (aktive Seite, aktueller Schritt) |
aria-invalid |
fehlerhafte Eingabe |
aria-disabled |
bedienbar dargestellt, aber deaktiviert gemeldet |
aria-hidden |
vor assistiver Technik verborgen |
Der entscheidende Punkt: Ein Zustand muss mit der Realität synchron bleiben. Klappt ein Akkordeon auf, muss aria-expanded im selben Moment von false auf true springen. Ein Zustand, der hinterherhinkt, ist eine falsche Auskunft – und die ist schlimmer als gar keine.
aria-expanded="false" oder "true" – und muss im exakt selben Moment umspringen wie das Panel.<button type="button" aria-expanded="false" aria-controls="panel">
Details
</button>
<div id="panel" hidden>…</div>
button.addEventListener('click', () => {
const offen = button.getAttribute('aria-expanded') === 'true';
button.setAttribute('aria-expanded', String(!offen));
panel.hidden = offen;
});
Drei Verwandte, drei Bedeutungen: aria-pressed, aria-checked, aria-expanded
Weil sich diese drei Zustände ähneln, lohnt die saubere Trennung – Rolle und Zustand gehören immer als Paket zusammen:
| Muster | Rolle + Zustand | Ansage (sinngemäß) |
|---|---|---|
| Umschalt-Button („Fett“) | <button aria-pressed="true"> |
„Fett, Umschalter, gedrückt“ |
| Schalter („Benachrichtigungen“) | role="switch" + aria-checked="true" |
„Benachrichtigungen, Schalter, ein“ |
| Checkbox (nachgebaut) | role="checkbox" + aria-checked="true" |
„AGB, Kontrollfeld, aktiviert“ |
| Aufklapper („Details“) | <button aria-expanded="true"> |
„Details, Schalter, erweitert“ |
Ein aria-checked an einem normalen <button> ist dagegen ein klassischer Fehler: Die Rolle button kennt diesen Zustand nicht, die Ansage bleibt aus. Entweder die Rolle wechseln (switch, checkbox) – oder beim Button bleiben und aria-pressed nehmen.
Die Grenze ist fließend – und das ist okay
Streng genommen sind Zustand und Eigenschaft technisch beide nur Attribute, und selbst die Spezifikation zieht die Grenze nicht immer scharf. Für die Praxis genügt die Merkhilfe: Ändert sich der Wert während der Bedienung, behandle ihn wie einen Zustand und halte ihn aktuell. Bleibt er konstant, ist es eine Eigenschaft, die du einmal richtig setzt.
Randnotiz – mehr ARIA heißt nicht mehr Barrierefreiheit. Das WebAIM-Million-Projekt untersucht jedes Jahr eine Million Startseiten. Ergebnis der Ausgabe vom Februar 2026: 82,7 % der Seiten setzen ARIA ein – aber Seiten mit ARIA hatten im Schnitt 59,1 automatisch erkennbare Fehler, Seiten ohne nur 42. ARIA wird also überwiegend falsch oder überflüssig eingesetzt. Die Konsequenz ist nicht „kein ARIA“, sondern: erst natives HTML, dann gezieltes, korrektes ARIA – genau die Dreiheit aus Rolle, Verhalten und gepflegten Zuständen.
Häufige Fehler
- Rolle ohne Verhalten.
role="tab"ohne Tastaturmodell verspricht etwas, das fehlt. - Zustand nicht aktualisiert.
aria-expandedbleibt auffalse, obwohl offen. - Zustand an der falschen Rolle.
aria-checkedam normalen<button>(richtig:aria-pressed– oder gleichrole="switch"). -
aria-labelüberschreibt sichtbaren Text. Sichtbarer Name und zugänglicher Name sollten übereinstimmen (WCAG 2.5.3). - Redundante Rollen.
role="button"am<button>,role="list"am<ul>– überflüssig. - Abstrakte Rollen im Markup.
role="widget"steht zwar in der Spec, gehört aber nie in HTML. -
aria-describedbyzeigt auf eine fehlendeid. Die Verknüpfung läuft ins Leere. - ARIA als Verhaltens-Ersatz.
role="button"am<div>macht es weder fokussierbar noch per Tastatur bedienbar – ARIA ändert nur die Ansage.
Häufige Fragen
Woher weiß ich, welche Rolle welche Zustände erwartet?
Aus dem ARIA Authoring Practices Guide. Dort steht für jedes Muster, welche Rollen, Zustände und welches Verhalten zusammengehören – diese Dreiheit ist immer als Paket zu denken. Die normative Quelle dahinter ist die WAI-ARIA-1.2-Spezifikation, die für jede Rolle auflistet, welche Attribute erlaubt und welche erforderlich sind.
Was ist der Accessibility Tree – und wie sehe ich ihn?
Die vereinfachte Parallelstruktur zum DOM, die der Browser assistiver Technik anbietet: je Knoten Name, Rolle, Wert und Zustände. In den Chrome DevTools zeigt der Tab „Barrierefreiheit“ im Elemente-Panel die berechneten Werte jedes Elements – die schnellste Kontrolle, ob dein ARIA wirklich ankommt.
aria-label oder aria-labelledby?
aria-labelledby, wenn der Name schon als sichtbarer Text auf der Seite steht (dann verweist du darauf). aria-label, wenn es keinen passenden sichtbaren Text gibt. Sichtbarer Text bleibt aber die erste Wahl.
Warum ändert ARIA nichts am Verhalten?
Weil ARIA nur eine Beschreibungsschicht für den Accessibility Tree ist. Es beeinflusst, was angesagt wird – nicht, was passiert. Fokusführung, Tastaturbedienung und Zustandspflege musst du mit HTML und JavaScript selbst liefern; natives HTML nimmt dir davon am meisten ab.
Kann ich neue ARIA-1.3-Attribute wie aria-braillelabel schon nutzen?
Besser noch nicht. ARIA 1.3 (u. a. aria-braillelabel, neue Rollen wie suggestion und comment) ist noch im Entwurfsstadium, die Unterstützung in Browsern und Screenreadern lückenhaft. Produktiv verlässlich ist der Stand von ARIA 1.2.
Brauche ich aria-live hier auch?
aria-live ist eine Eigenschaft für sich – sie macht einen Bereich zur Live-Region, deren Änderungen angekündigt werden. Weil das ein eigenes Thema ist, hat es eine eigene Seite.
Fazit
ARIA gliedert sich in Rollen (was etwas ist), Eigenschaften (stabile Merkmale, allen voran der Name) und Zustände (was sich während der Bedienung ändert). Alles davon wirkt an genau einer Stelle: im Accessibility Tree, aus dem Screenreader Name, Rolle und Wert vorlesen – Verhalten liefert ARIA nie. Eine Rolle ist deshalb ein Versprechen, das Tastaturbedienung und aktuell gehaltene Zustände einlösen müssen. Wer diese Aufteilung im Kopf hat und Zustände nur an ihre passenden Rollen hängt, setzt ARIA gezielt ein – und merkt schnell, wie oft gutes natives HTML die halbe Arbeit schon erledigt.
- W3C – WAI-ARIA 1.2 (Recommendation, Juni 2023)
- W3C – ARIA Authoring Practices Guide (APG)
- W3C – Accessible Name and Description Computation 1.2
- MDN – ARIA-Zustände und -Eigenschaften (Referenz)
- Chrome for Developers – Full Accessibility Tree in DevTools
- WebAIM – The WebAIM Million (Jahresstudie, Ausgabe Februar 2026)