Zum Inhalt springen

Tutorial

So machst du ein Modal barrierefrei

Kurz gesagt

Nutze das native <dialog>-Element mit showModal(): Es fängt den Fokus im Dialog, macht den Hintergrund inert, schliesst per Escape und liefert die Dialog-Rolle. Gib dem Dialog mit aria-labelledby einen Namen und setze den Fokus beim Schliessen auf den auslösenden Button zurück.

In Kürze

  1. Native <dialog> verwenden

    Ersetze das mit CSS ein- und ausgeblendete <div> durch ein <dialog>-Element und öffne es mit showModal().

  2. Dialog benennen

    Verbinde die Überschrift per aria-labelledby mit dem Dialog, damit Screenreader den Zweck ansagen.

  3. Escape und Fokus-Falle prüfen

    showModal() hält den Fokus im Dialog und schliesst bei Escape. Teste es nur mit der Tastatur.

  4. Fokus zurückgeben

    Setze den Fokus beim close-Event zurück auf den Button, der den Dialog geöffnet hat.

Ein Modal ist eine der häufigsten Barrieren im Web. Typische Fehler: Die Tastatur kann in den Hintergrund tabben, Escape schliesst nichts, der Screenreader sagt nicht an, dass ein Dialog offen ist, und nach dem Schliessen landet der Fokus irgendwo im Nichts. Alle vier Probleme löst du mit einem Element, das der Browser schon mitbringt.

Das Problem

Dieses Muster sieht optisch aus wie ein Dialog, ist für assistive Technik aber keiner: keine Rolle, kein Name, keine Fokus-Falle, kein Escape.

Vorher: nicht barrierefreiHTML
<button onclick="openModal()">Newsletter abonnieren</button>

<div class="modal" id="modal" style="display: none">
  <div class="modal-box">
    <h2>Newsletter</h2>
    <p>Melde dich fuer unseren Newsletter an.</p>
    <input type="email" placeholder="E-Mail" />
    <button onclick="closeModal()">Schliessen</button>
  </div>
</div>
  • Der Hintergrund bleibt mit Tab erreichbar (Fokus verlässt den Dialog).
  • Escape schliesst den Dialog nicht.
  • Ein Screenreader kündigt keinen Dialog an, weil Rolle und Name fehlen.
  • Nach dem Schliessen ist der Fokus verloren.

Die Lösung: das native <dialog>-Element

showModal() macht die meiste Arbeit: Es fängt den Fokus im Dialog (2.1.2 Keine Tastaturfalle bekommt so einen definierten Ausgang), macht den restlichen Seiteninhalt inert, blendet einen Backdrop ein und schliesst bei Escape. Du musst nur noch den Dialog benennen und den Fokus beim Schliessen zurückgeben.

Nachher: barrierefreiHTML
<button type="button" id="open">Newsletter abonnieren</button>

<dialog id="modal" aria-labelledby="modal-title">
  <h2 id="modal-title">Newsletter</h2>
  <p>Melde dich fuer unseren Newsletter an.</p>
  <label for="email">E-Mail</label>
  <input id="email" type="email" />
  <button type="button" id="close">Schliessen</button>
</dialog>
Öffnen, schliessen, Fokus zurückgebenJavaScript
const dialog = document.getElementById("modal");
const openBtn = document.getElementById("open");

openBtn.addEventListener("click", () => {
  // showModal() traps focus inside the dialog, makes the rest of the page inert,
  // and lets the Escape key close it. All three are WCAG requirements you no longer
  // have to hand-roll.
  dialog.showModal();
});

document.getElementById("close").addEventListener("click", () => dialog.close());

// Return focus to the trigger when the dialog closes (native or via Escape).
dialog.addEventListener("close", () => openBtn.focus());

Testen (nur mit der Tastatur)

  1. Öffne den Dialog mit Enter/Leertaste auf dem Button.
  2. Tabbe durch den Dialog: Der Fokus muss im Dialog zirkulieren, nie in den Hintergrund.
  3. Escape muss den Dialog schliessen.
  4. Nach dem Schliessen muss der Fokus wieder auf dem auslösenden Button liegen.

Wenn du das ARIA-Muster ohne <dialog> brauchst (z. B. wegen alter Browser), musst du Fokus-Falle, Escape und Hintergrund-Inertheit selbst per JavaScript nachbauen, plus role="dialog" und aria-modal="true". Das native Element erspart dir genau diesen fehleranfälligen Teil.

Häufige Fragen

Brauche ich role="dialog", wenn ich <dialog> nutze?
Nein. Das native <dialog>-Element hat die Dialog-Rolle bereits. Ein zusätzliches role="dialog" ist überflüssig. Nur bei einem selbstgebauten Dialog aus <div> setzt du role="dialog" und aria-modal="true".
Warum showModal() und nicht show()?
show() öffnet einen nicht-modalen Dialog ohne Fokus-Falle, ohne inerten Hintergrund und ohne Escape-zum-Schliessen. Für ein echtes Modal brauchst du showModal().
Wie gebe ich den Fokus korrekt zurück?
Merke dir das auslösende Element (oder nutze document.activeElement beim Öffnen) und rufe im close-Event .focus() darauf auf. Sonst springt der Screenreader nach dem Schliessen an den Seitenanfang.

Kostenlosen Scan anfragen

Sagen Sie uns Ihre Domain — wir führen einen kostenlosen Erst-Scan durch und zeigen Ihnen die wichtigsten Barrieren.