Das HTML dialog-Element: Modale Dialoge nativ und barrierefrei
Modale Dialoge gehören zu den komplexesten UI-Patterns in Bezug auf Barrierefreiheit. Sie erfordern Fokus-Trapping, Escape-Handling, Hintergrund-Deaktivierung und korrekte ARIA-Semantik. Jahrelang mussten Entwickler diese Funktionen manuell implementieren – mit zahlreichen Fehlerquellen. Das native HTML <code><dialog></code>-Element löst viele dieser Probleme automatisch. Es ist seit 2022 in allen modernen Browsern verfügbar und wird von EN 301 549 und dem BFSG als robuste Lösung für barrierefreie Dialoge empfohlen.
Grundlagen: dialog, showModal() und show()
Das <dialog>-Element wird als Container für Dialog-Inhalte verwendet: <dialog id="mein-dialog"><h2>Dialogtitel</h2><p>Inhalt...</p><button>Schließen</button></dialog>. Zwei Öffnungsmethoden: .showModal() öffnet den Dialog als modalen Dialog: Hintergrund wird mit einem Backdrop abgedunkelt, Fokus ist auf den Dialog beschränkt (Focus Trapping), Escape-Taste schließt den Dialog, der Dialog erscheint im Top Layer (über allem anderen). .show() öffnet den Dialog als nicht-modalen Dialog: Kein Backdrop, kein Focus Trapping, Hintergrund bleibt interaktiv. Schließen: .close() schließt den Dialog. Optional kann ein Rückgabewert übergeben werden: dialog.close("confirm") – abrufbar über dialog.returnValue. Events: close-Event wird beim Schließen ausgelöst, cancel-Event bei Escape-Taste. WCAG 2.4.3 fordert eine sinnvolle Fokusreihenfolge – .showModal() implementiert dies automatisch.
Fokus-Management: Automatisch und korrekt
Das native <dialog>-Element mit .showModal() bietet automatisches Fokus-Management: Fokus beim Öffnen: Der Browser setzt den Fokus auf das erste fokussierbare Element im Dialog. Wenn kein fokussierbares Element existiert, erhält der Dialog selbst den Fokus (erfordert kein tabindex). Sie können den initialen Fokus mit dem autofocus-Attribut steuern: <input autofocus>. Focus Trapping: Tab und Shift+Tab navigieren nur innerhalb des Dialogs. Der Fokus verlässt den Dialog nicht – kein manuelles Focus Trapping nötig. Fokus beim Schließen: Der Browser setzt den Fokus automatisch auf das Element zurück, das den Dialog geöffnet hat. Dies erfüllt WCAG 2.4.3 perfekt. Inert-Effekt: Der Hintergrundinhalt wird bei .showModal() automatisch inert – nicht fokussierbar, nicht klickbar, nicht für Screenreader sichtbar. Dies entspricht dem inert-Attribut, wird aber vom Browser intern verwaltet. EN 301 549 Abschnitt 11.2.4.3 fordert genau dieses Verhalten.
Escape-Taste und Schließ-Mechanismen
WCAG 2.1.2 verlangt, dass Nutzer jeden Dialog per Tastatur verlassen können. Das <dialog>-Element implementiert dies nativ: Escape-Taste: Bei .showModal() schließt Escape den Dialog automatisch. Das cancel-Event wird ausgelöst, gefolgt vom close-Event. Sie können das Schließen per Escape verhindern (z. B. bei ungespeicherten Änderungen): dialog.addEventListener("cancel", (e) => { if (hasUnsavedChanges) e.preventDefault(); }); Wichtig: Verhindern Sie Escape nur mit triftigem Grund und bieten Sie immer eine alternative Schließmöglichkeit. Backdrop-Klick: Das native <dialog> schließt sich nicht automatisch bei Klick auf den Backdrop. Dies muss manuell implementiert werden: dialog.addEventListener("click", (e) => { if (e.target === dialog) dialog.close(); }); Schließen-Button: Jeder Dialog sollte einen expliziten Schließen-Button haben (WCAG 3.2.5 – Änderung auf Anforderung). Platzieren Sie ihn oben rechts oder am Ende des Dialoginhalts. Verwenden Sie aria-label="Dialog schließen" für Icon-Buttons.
Styling: Backdrop und CSS-Anpassungen
Das <dialog>-Element und sein Backdrop können vollständig per CSS gestaltet werden: Backdrop: ::backdrop ist ein Pseudo-Element, das bei .showModal() automatisch erscheint: dialog::backdrop { background: rgba(0, 0, 0, 0.5); backdrop-filter: blur(4px); }. Dialog-Styling: dialog { border: none; border-radius: 8px; box-shadow: 0 4px 24px rgba(0,0,0,0.2); max-width: 600px; width: 90%; padding: 2rem; } Animation: Öffnen und Schließen können animiert werden: dialog[open] { animation: fadeIn 0.3s ease; } @keyframes fadeIn { from { opacity: 0; transform: translateY(-20px); } to { opacity: 1; transform: translateY(0); } } Fokusindikator: Stellen Sie sicher, dass der Fokusindikator innerhalb des Dialogs deutlich sichtbar ist (WCAG 2.4.7 – Sichtbarer Fokus, WCAG 2.4.11 – Fokus-Erscheinungsbild). Verwenden Sie :focus-visible für moderne Fokus-Stile. Farbkontrast: Dialog-Text muss gegen den Dialog-Hintergrund mindestens 4.5:1 Kontrastverhältnis haben (WCAG 1.4.3). Der Backdrop sollte den Hintergrund ausreichend abdunkeln.
Barrierefreiheits-Checkliste für Dialoge
ARIA-Attribute: <dialog> hat implizit role="dialog". Ergänzen Sie aria-labelledby mit Verweis auf den Dialog-Titel und optional aria-describedby für eine Beschreibung: <dialog aria-labelledby="dialog-title" aria-describedby="dialog-desc"><h2 id="dialog-title">Bestätigung</h2><p id="dialog-desc">Möchten Sie fortfahren?</p></dialog>. Vollständige Checkliste: Dialog hat aria-labelledby mit Verweis auf die Überschrift? Fokus wird beim Öffnen auf den Dialog oder das erste Element gesetzt? Fokus bleibt innerhalb des Dialogs (Focus Trapping)? Escape-Taste schließt den Dialog? Fokus kehrt nach dem Schließen zum Auslöser zurück? Schließen-Button ist vorhanden und zugänglich benannt? Hintergrundinhalt ist für Screenreader und Tastatur unerreichbar? Dialog-Inhalt hat ausreichenden Farbkontrast? Dialog ist auch auf Mobilgeräten bedienbar? Alle Punkte sind BFSG-relevant gemäß EN 301 549 Abschnitt 11.2.1.1, 11.2.1.2, 11.2.4.3 und 11.4.1.2.
Wie steht deine Webseite in diesem Punkt da?
Kostenloser Scan gegen 15 WCAG-2.1-AA-Kriterien – inkl. HTML dialog-Element-Check.
Jetzt Webseite prüfen →