ARIA (Accessible Rich Internet Applications) ist ein mächtiges Werkzeug — aber auch ein häufig falsch eingesetztes. Die erste Regel der ARIA-Spezifikation lautet: "Benutze kein ARIA, wenn du es nicht brauchst." Dieser Artikel erklärt, wann ARIA nötig ist, welche Attribute es gibt und wie Sie die häufigsten Fehler vermeiden.
Die 5 Regeln von ARIA (W3C): 1. Natürliches HTML bevorzugen. 2. Die Semantik nicht ändern. 3. Alle ARIA-Kontrollelemente müssen per Tastatur bedienbar sein. 4. Fokussierbare Elemente nie verstecken (aria-hidden). 5. Alle interaktiven Elemente müssen einen zugänglichen Namen haben.
Wann brauchen Sie ARIA?
ARIA ist nötig, wenn HTML allein die Zugänglichkeit nicht sicherstellen kann:
- Custom-UI-Komponenten (Tabs, Accordeons, Datepicker, Modals) ohne natives HTML-Äquivalent
- Dynamische Inhalte, die sich ohne Seitenaktualisierung ändern
- Elemente ohne sichtbaren Text (Icon-Buttons, Symbole)
- Komplexe Layouts, bei denen die DOM-Reihenfolge von der visuellen Reihenfolge abweicht
Die wichtigsten ARIA-Attribute
Zugängliche Namen: aria-label und aria-labelledby
Jedes interaktive Element braucht einen zugänglichen Namen — den Text, den Screen Reader vorlesen, wenn der Nutzer auf das Element fokussiert.
<!-- aria-label: direkter Text-String --> <button aria-label="Suche öffnen"> <svg aria-hidden="true">...</svg> </button> <!-- aria-labelledby: verweist auf Element-ID --> <section aria-labelledby="section-heading"> <h2 id="section-heading">Unsere Produkte</h2> ... </section> <!-- aria-describedby: zusätzliche Beschreibung --> <input type="password" aria-describedby="pw-hint" /> <p id="pw-hint">Mindestens 8 Zeichen, 1 Sonderzeichen</p>
Zustände kommunizieren: aria-expanded, aria-selected, aria-checked
Dynamische Zustände müssen programmatisch kommuniziert werden:
<!-- Dropdown/Accordion -->
<button
aria-expanded="false"
aria-controls="menu-content"
onclick="toggleMenu(this)"
>
Menü öffnen
</button>
<div id="menu-content" hidden>...</div>
<!-- Tabs -->
<button
role="tab"
aria-selected="true"
aria-controls="panel-1"
>
Tab 1
</button>
<!-- Toggle-Button -->
<button
aria-pressed="false"
onclick="this.setAttribute('aria-pressed',
this.getAttribute('aria-pressed') === 'true' ? 'false' : 'true')"
>
Dunkelmodus
</button>Live-Regionen: aria-live
Wenn Inhalte dynamisch aktualisiert werden (Suchergebnisse, Fehlermeldungen, Chat), muss der Screen Reader informiert werden:
<!-- polite: liest beim nächsten Pause-Moment vor -->
<div aria-live="polite" aria-atomic="true">
{/* Suchergebnisse: "12 Produkte gefunden" */}
</div>
<!-- assertive: liest sofort vor (nur für kritische Fehler) -->
<div role="alert">
Fehler: Ungültige Kreditkartennummer
</div>
<!-- status: für nicht-kritische Statusmeldungen -->
<div role="status" aria-live="polite">
Datei erfolgreich hochgeladen
</div>aria-hidden: Verstecken vor Screen Readern
<!-- Dekoratives Icon: für SR verstecken --> <button> <svg aria-hidden="true" focusable="false">...</svg> Speichern </button> <!-- Redundante Information verstecken --> <span aria-hidden="true">★★★★☆</span> <span class="sr-only">4 von 5 Sternen</span>
ARIA-Rollen
Rollen definieren die Art eines Elements für Hilfstechnologien:
| Rolle | Wann verwenden | HTML-Alternative |
|---|---|---|
| role="button" | Div/Span als Button (nur wenn <button> nicht möglich) | <button> |
| role="dialog" | Modal-Fenster | Kein natives Element |
| role="alert" | Wichtige Fehlermeldungen | Kein natives Element |
| role="tablist" | Tab-Navigation | Kein natives Element |
| role="navigation" | Navigationsbereich | <nav> |
| role="main" | Hauptinhalt | <main> |
| role="banner" | Seitenkopf | <header> |
Die häufigsten ARIA-Fehler
Doppelte Attribute — aria-label und sichtbarer Text
Ein Button mit Text "Suchen" und aria-label="Suchen" ist redundant. Das aria-label überschreibt den sichtbaren Text für Screen Reader — was sinnlos ist, wenn beide gleich sind. Nur dann aria-label nutzen, wenn kein sichtbarer Text vorhanden ist.
aria-label auf nicht-interaktiven Elementen
Ein Div mit aria-label hat keinen Effekt — Divs haben keine Rolle, also keinen zugänglichen Namen. Entweder eine Rolle hinzufügen (role="region") oder semantisches HTML nutzen.
aria-required statt required
Das native required-Attribut kommuniziert Pflichtfelder automatisch — an Browser und Screen Reader. Zusätzlich aria-required="true" zu setzen ist redundant.
aria-expanded ohne Funktionalität
aria-expanded="false" zu setzen und den Wert nie zu ändern ist schlechter als kein ARIA. Der Screen Reader kündigt "zugeklappt" an — und öffnet nichts. Immer per JavaScript den Wert beim Öffnen/Schließen aktualisieren.
Praktisches Beispiel: Ein zugängliches Modal
<!-- Trigger-Button -->
<button
aria-haspopup="dialog"
aria-controls="confirm-dialog"
onclick="openModal()"
>
Bestellung bestätigen
</button>
<!-- Modal-Dialog -->
<div
id="confirm-dialog"
role="dialog"
aria-modal="true"
aria-labelledby="dialog-title"
aria-describedby="dialog-desc"
>
<h2 id="dialog-title">Bestellung bestätigen</h2>
<p id="dialog-desc">
Möchten Sie Ihre Bestellung für 49,99 € abschicken?
</p>
<button onclick="confirmOrder()">Ja, jetzt kaufen</button>
<button onclick="closeModal()">Abbrechen</button>
</div>
<script>
function openModal() {
const modal = document.getElementById('confirm-dialog');
modal.removeAttribute('hidden');
// Fokus auf ersten Button im Modal
modal.querySelector('button').focus();
// Hintergrund für SR verstecken
document.getElementById('main').setAttribute('aria-hidden', 'true');
}
function closeModal() {
const modal = document.getElementById('confirm-dialog');
modal.setAttribute('hidden', '');
document.getElementById('main').removeAttribute('aria-hidden');
// Fokus zurück auf Trigger
document.querySelector('[aria-controls="confirm-dialog"]').focus();
}
</script>ARIA-Fehler auf Ihrer Website finden
Unser Scanner erkennt häufige ARIA-Probleme — fehlende zugängliche Namen, falsch gesetzte Attribute und verwaiste aria-labelledby-Referenzen. Kostenlos scannen.
Website auf ARIA-Fehler prüfen →