ARIA wurde entwickelt, um Barrierefreiheit dort zu ermöglichen, wo HTML nicht ausreicht. In der Praxis wird es meistens eingesetzt, um fehlende Semantik zu kompensieren, die das HTML mitbringen sollte. Der Unterschied zwischen beiden Anwendungsfällen ist der Unterschied zwischen einem Werkzeug und einem Pflaster.
Das W3C formuliert sie unmissverständlich: Wenn ein natives HTML-Element mit der benötigten Semantik und dem benötigten Verhalten existiert, ist dieses zu verwenden. ARIA kommt erst dann ins Spiel, wenn HTML an seine Grenzen stößt.
<!-- First Rule verletzt: div mit ARIA-Rolle -->
<div role="button" tabindex="0" onclick="submit()">Absenden</div>
<!-- First Rule erfüllt: natives Element -->
<button type="submit">Absenden</button>
Das native <button> bringt Rolle, Fokussierbarkeit und Tastatursteuerung von Haus aus mit. Das <div> braucht role=„button“, tabindex=„0“ und einen onkeydown-Handler, nur um dasselbe zu leisten. Mehr Code, mehr Fehlerquellen, keine Vorteile.
<!-- Redundant: button hat die Rolle "button" bereits -->
<button role="button">Senden</button>
<!-- Ebenso: input type="checkbox" hat bereits role="checkbox" -->
<input type="checkbox" role="checkbox">
Redundantes ARIA ist meist wirkungslos, erhöht aber die Komplexität und ist oft ein Warnsignal. Eine ARIA-Rolle ist ein Versprechen an assistive Technologien: Was kommuniziert wird, muss technisch auch erfüllt sein.
<!-- Fehler: aria-label macht aus einem div keine Navigation -->
<div aria-label="Hauptnavigation">
<a href="/">Start</a>
<a href="/blog">Blog</a>
</div>
<!-- Besser: semantisches Element mit impliziter Landmark-Rolle -->
<nav aria-label="Hauptnavigation">
<a href="/">Start</a>
<a href="/blog">Blog</a>
</nav>
aria-label benennt ein Element. Es verleiht ihm keine Bedeutung, keine Rolle und keine Struktur. Ein neutrales <div> wird dadurch nicht zur Navigation. Sinnvoll ist aria-label, wenn mehrere gleichartige Landmarks unterschieden werden müssen, etwa eine Hauptnavigation und eine Footer-Navigation. Als Ersatz für semantisches HTML ist es kein Hilfsmittel, sondern ein Symptom.
<!-- Fehler: aria-hidden versteckt den Bereich vor Screenreadern,
aber fokussierbare Elemente können erreichbar bleiben -->
<div aria-hidden="true">
<button>Schließen</button>
</div>
<!-- Korrekt: inaktiven Bereich vollständig aus Interaktion
und Accessibility Tree nehmen -->
<div inert>
<button>Schließen</button>
</div>
aria-hidden=„true“ entfernt Inhalte aus dem Accessibility Tree, nicht zuverlässig aus der Interaktion. Fokussierbare Elemente in einem solchen Bereich sind besonders problematisch: Sie können per Tastatur erreichbar bleiben, während Screenreader keinen sinnvollen Kontext mehr ausgeben. Für ganze inaktive Bereiche ist inert die robustere Lösung, weil es Fokus, Eingaben und die Ausgabe an assistive Technologien gemeinsam unterbindet.
<!-- aria-labelledby zeigt auf eine ID, die nicht existiert -->
<input type="text" aria-labelledby="field-label">
<!-- <label id="field-label"> fehlt oder hat andere ID -->
Assistive Technologien ignorieren defekte ARIA-Referenzen stillschweigend. Das Eingabefeld hat dann keinen zugänglichen Namen, ohne dass es einen sichtbaren Fehler gibt. Regelmäßige Tests mit einem Screenreader oder Accessibility-Checker decken das auf.
Wenn sich Inhalte auf der Seite ändern, ohne dass der Fokus wechselt, bekommen Screenreader-Nutzende das ohne Live Region nicht mit. Statusmeldungen, Ladeindikatoren, Suchergebnisse, Fehleranzeigen nach Formularvalidierung.
<div
aria-live="polite"
aria-atomic="true"
class="status-message"
>
<!-- Dynamisch eingefügte Meldungen werden hier automatisch vorgelesen -->
</div>
aria-live=„polite“ liest die Meldung beim nächsten natürlichen Pause-Punkt vor. aria-live=„assertive“ unterbricht sofort. Nur für echte Fehlerzustände verwenden, nicht für Statusinfos.
Nicht alle komplexen Komponentenzustände lassen sich mit HTML allein ausdrücken. Einfache Zustände wie checked, disabled, required oder hidden existieren nativ. ARIA wird stark, wo Custom Components eigene Zustände kommunizieren müssen.
<!-- Akkordeon-Trigger -->
<button aria-expanded="false" aria-controls="panel-1">
Abschnitt öffnen
</button>
<div id="panel-1" hidden>...</div>
<!-- Reiter (Tab) -->
<button role="tab" aria-selected="true" aria-controls="panel-a">
Reiter 1
</button>
aria-expanded, aria-selected, aria-checked und aria-pressed kommunizieren Zustände, die HTML allein nicht ausdrücken kann.
<label for> reicht nicht immer aus. Für Fehlermeldungen, Hinweistexte und mehrteilige Beschriftungen kommt aria-describedby ins Spiel.
<label for="email">E-Mail-Adresse</label>
<input
type="email"
id="email"
aria-describedby="email-hint"
>
<span id="email-hint">Bitte geschäftliche E-Mail-Adresse verwenden.</span>
<span id="email-error" role="alert"></span>
Bei der Validierung ergänzt JavaScript den Fehler:
<input
type="email"
id="email"
aria-invalid="true"
aria-describedby="email-hint email-error"
>
<span id="email-hint">Bitte geschäftliche E-Mail-Adresse verwenden.</span>
<span id="email-error" role="alert">Dieses Feld ist erforderlich.</span>
aria-describedby kann auf mehrere IDs verweisen. Wichtig: Fehlermeldungen nicht vorsorglich als Beschreibung ankündigen, bevor ein Fehler vorliegt. Erst wenn das Feld ungültig ist, wird aria-invalid=„true“ gesetzt und die Fehlermeldung in die Beschreibung aufgenommen. role=„alert“ sorgt dafür, dass der dynamisch eingefügte Text automatisch vorgelesen wird.
| Situation | Empfehlung |
|---|---|
| Natives HTML-Element verfügbar | Natives Element verwenden, kein ARIA |
| Interaktive Custom-Komponente | Rolle, Zustand und Keyboard-Handler vollständig implementieren |
| Dynamische Inhaltsaktualisierung | aria-live mit passendem Wert |
| Formularfeld mit Hinweis oder Fehler | aria-describedby und aria-invalid |
| Versteckter Bereich ausblenden | inert statt aria-hidden auf fokussierbaren Elementen |
| Landmark mit doppelter Funktion | aria-label zur Unterscheidung, nicht als Strukturersatz |
Technische Spezifikation des W3C, die HTML um Zugänglichkeitsattribute erweitert. Besteht aus Rollen (role), Zuständen (aria-expanded, aria-checked) und Eigenschaften (aria-label, aria-describedby). Grundregel: Wo natives HTML ausreicht, ist ARIA nicht nötig. Falsch eingesetztes ARIA ist schlechter als kein ARIA.
Erste und wichtigste Regel der ARIA-Spezifikation des W3C: Wenn ein natives HTML-Element mit der benötigten Semantik und dem benötigten Verhalten existiert, ist dieses zu verwenden, statt ein neutrales Element mit ARIA-Attributen nachzurüsten. Verhindert unnötige Komplexität und typische Implementierungsfehler.
ARIA-Eigenschaft, die einen Bereich als Live Region markiert. Screenreader lesen Änderungen in diesem Bereich automatisch vor, ohne dass der Fokus wechseln muss. Werte: polite (beim nächsten Pause-Punkt), assertive (sofort, unterbricht laufende Ausgabe), off (Standard, keine automatische Ausgabe). Nur assertive für kritische Fehlerzustände verwenden.
Parallele Baumstruktur, die der Browser aus dem DOM ableitet und an assistive Technologien übergibt. Enthält Rollen, Namen, Zustände und Eigenschaften fokussierbarer Elemente. aria-hidden=„true" entfernt Elemente aus dem Accessibility Tree, nicht aus dem Tab-Fluss. inert entfernt sie aus beidem.