Standards · ARIA

Rolle Fenster

dialog

Kennzeichnet einen Container als modalen oder nicht-modalen Dialog. Das native <dialog>-Element mit showModal() übernimmt Fokusfalle, Top-Layer, Hintergrundblende und Escape-Schließen automatisch. role="dialog" sollte nur verwendet werden, wenn das native Element nicht möglich ist.

Verwendung

Das <dialog>-Element sollte per .showModal() geöffnet werden. Das native Element wird in allen aktuellen Browsern unterstützt und übernimmt automatisch die Inertisierung des Hintergrunds, die Fokusfalle, das Schließen per Escape, den ::backdrop-Styling-Hook und das Top-Layer-Rendering. Dadurch entfallen etwa 200 Zeilen fehleranfälliges JavaScript.

role="dialog" auf einem <div> sollte nur verwendet werden, wenn:

  • Browser älter als Chrome 37 / Firefox 98 / Safari 15.4 unterstützt werden müssen (in 2026 unwahrscheinlich).
  • Das Design einen Dialog verlangt, der nicht im Top-Layer leben kann (selten).
  • Ein unzugängliches Custom-Modal während eines Refactorings gepatcht wird.

Jeder Dialog MUSS einen zugänglichen Namen haben (aria-labelledby auf eine sichtbare Überschrift ist das stärkste Muster). Modale Dialoge benötigen zusätzlich aria-modal="true".

Tastatur- und Fokusvertrag

Gemäß dem APG-Muster für modale Dialoge:

  • Beim Öffnen wandert der Fokus zum ersten fokussierbaren Element im Dialog (häufig dem Schließen-Button oder dem primären Eingabefeld).
  • Tab und Shift+Tab bewegen den Fokus NUR innerhalb des Dialogs – eine „Fokusfalle“. Tab vom letzten Element kehrt zum ersten zurück; Shift+Tab vom ersten zum letzten.
  • Escape schließt den Dialog.
  • Beim Schließen kehrt der Fokus zu dem Element zurück, das den Dialog geöffnet hat. Das Speichern und Wiederherstellen des Fokus ist nicht verhandelbar; Nutzende, die ihren Ausgangspunkt verlieren, haben keinen Anker mehr.
  • Der Rest der Seite ist inert (oder als Fallback aria-hidden="true" plus nicht fokussierbar), solange der Dialog geöffnet ist.

Häufige Fehler

  • Custom-Dialog ohne Fokusfalle: Tab verlässt den Dialog und landet dahinter; Nutzende verlieren den Kontext.
  • Fokus wird beim Schließen nicht zum auslösenden Element zurückgekehrt: Das nächste Tab landet auf dem Dokumentkörper.
  • Hintergrundinhalt bleibt per Tab erreichbar, obwohl er optisch hinter dem Dialog verborgen ist.
  • Kein zugänglicher Name: Der Dialog öffnet sich, und der Screenreader kündigt lediglich „Dialog“ an.
  • Custom-Dialog ohne aria-modal="true" — assistive Technologie behandelt ihn als Inline-Inhalt.
  • Escape schließt den Dialog, aber der Dialog ist über ein Portal gerendert, das beim Schließen die Tastatursteuerung verliert.

Beispiel

<!-- Bevorzugt -->
<dialog id="confirm">
  <h2>Delete this draft?</h2>
  <p>This cannot be undone.</p>
  <form method="dialog">
    <button value="cancel">Cancel</button>
    <button value="delete" autofocus>Delete</button>
  </form>
</dialog>
<script>
  document.getElementById('confirm').showModal();
</script>

<!-- Wenn <dialog> nicht möglich ist -->
<div role="dialog" aria-modal="true" aria-labelledby="dlgTitle">
  <h2 id="dlgTitle">Edit profile</h2>

</div>