HTML <dialog> – Modal

dialog ist ein natives HTML-Element für Popups / Modals / Bestätigungsfenster. Es kann:

  • als Modal geöffnet werden (blockiert Interaktion mit der Seite)
  • oder als normales Fenster (nicht-modal) angezeigt werden

Wichtig: Ein Dialog wird erst sichtbar, wenn er aktiv geöffnet wird.

  • per JavaScript: showModal() oder show()
  • oder per HTML-Formular-Mechanik (method="dialog"), um ihn zu schliessen

See the Pen Das <dialog>-Tag (HTML Dialog / Modal) by Intensivstation (@intensivstation) on CodePen.


Was bedeuten die wichtigen Teile?

<dialog id="...">

Das <dialog>-Element ist der eigentliche Container für das Modal. Es ist standardmässig unsichtbar und wird erst sichtbar, wenn es geöffnet wird.

Ohne Öffnungsmethode (show() oder showModal()) bleibt der Dialog verborgen.


showModal() vs. show()

Es gibt zwei Arten, einen Dialog zu öffnen:

  • showModal()
    Öffnet den Dialog als modal.
    Der Hintergrund wird blockiert und ein Backdrop wird angezeigt.
  • show()
    Öffnet den Dialog nicht-modal.
    Die Seite bleibt weiterhin bedienbar.

In den meisten UI-Fällen wird showModal() verwendet.


<form method="dialog">

Ein Formular mit method="dialog" hat eine besondere Funktion:

  • Buttons innerhalb dieses Formulars schliessen den Dialog automatisch
  • Kein JavaScript ist zum Schliessen des Dialogs notwendig.

Der value des geklickten Buttons wird dabei in dialog.returnValue gespeichert.

<form method="dialog">
  <button value="cancel">Abbrechen</button>
  <button value="confirm">OK</button>
</form>

aria-labelledby / aria-describedby

Diese Attribute sorgen für bessere Accessibility.

  • aria-labelledby verweist auf den Titel des Dialogs
  • aria-describedby verweist auf die Beschreibung oder den Erklärungstext

Screenreader können dadurch korrekt vorlesen, worum es im Dialog geht.

<dialog
  aria-labelledby="dialogTitle"
  aria-describedby="dialogDesc">
</dialog>

dialog.addEventListener("close", ...)

Das close-Event wird ausgelöst, sobald der Dialog geschlossen wird.

Typische Anwendungsfälle:

  • Auswertung von dialog.returnValue
  • Reaktion auf Abbrechen oder Bestätigen
  • Zurücksetzen von Formularen oder Status

Das Event feuert unabhängig davon, ob der Dialog per Button, ESC-Taste oder programmatisch geschlossen wurde.


Dialog – UX & Robustheit

Dieses Beispiel baut auf dem vorherigen Code-Beispiel auf und zeigt typische UX- und Robustheits-Details, die im Alltag schnell wichtig werden, aber oft vergessen gehen.


See the Pen Dialog – UX & Robustheit by Intensivstation (@intensivstation) on CodePen.


cancel-Event (ESC / Abbrechen durch Benutzer)

Neben dem close-Event gibt es beim <dialog>-Element auch ein cancel-Event.

  • Es wird ausgelöst, wenn der Benutzer den Dialog abbricht
  • z. B. durch die ESC-Taste

Damit kann man explizit zwischen „bewusst geschlossen“ und „abgebrochen“ unterscheiden.

dialog.addEventListener("cancel", () => {
  console.log("Dialog wurde abgebrochen");
});

Optional kann das Abbrechen verhindert werden:

dialog.addEventListener("cancel", (e) => {
  e.preventDefault();
});

dialog.open – Schutz vor Mehrfach-Öffnen

showModal() wirft einen Fehler, wenn der Dialog bereits offen ist.

Darum prüft man im produktiven Code oft vorher:

if (!dialog.open) {
  dialog.showModal();
}

dialog.open ist ein Boolean und zeigt an, ob der Dialog aktuell geöffnet ist.


Backdrop-Klick (bewusste UX-Entscheidung)

Ein Klick auf den dunklen Hintergrund schliesst einen Dialog nicht automatisch.

Wenn man dieses Verhalten möchte, muss man es selbst implementieren:

dialog.addEventListener("click", (e) => {
  const rect = dialog.getBoundingClientRect();
  const inside =
    rect.top <= e.clientY && e.clientY <= rect.bottom &&
    rect.left <= e.clientX && e.clientX <= rect.right;

  if (!inside) dialog.close("backdrop");
});

Wichtig: Das ist keine technische Pflicht, sondern eine Design-Entscheidung.


Fokus sauber zurückgeben

Beim Öffnen eines Dialogs übernimmt der Browser automatisch das Fokus-Handling.

Beim Schliessen sollte der Fokus aber bewusst zurückgegeben werden, z. B. auf den Button, der den Dialog geöffnet hat:

dialog.addEventListener("close", () => {
  openButton.focus();
});

Das verbessert:

  • Tastatur-Navigation
  • Accessibility
  • das generelle UI-Gefühl

autofocus – sinnvolle Standard-Aktion

Mit autofocus kann gesteuert werden, welcher Button beim Öffnen aktiv ist:

<button value="cancel" autofocus>Abbrechen</button>

Gerade bei kritischen Aktionen (Löschen, Überschreiben) ist es oft sinnvoll, Abbrechen als Default zu wählen.


Fazit:
Dieses zweite Beispiel zeigt keinen „anderen Dialog“, sondern die Details, die einen simplen Dialog produktionstauglich machen.