Zum Inhalt springen

Native Interaktion: das dialog-Element

Erinnert ihr euch an den Modal-Backdrop aus dem Positionierungs-Abschnitt? position: fixed, z-index, ein abgedunkelter Hintergrund mit rgb(0 0 0 / 0.6), alles von Hand gebaut. Das <dialog>-Element bringt genau das fertig mit:

<dialog id="hinweis">
<p>Das ist ein Modal-Fenster.</p>
</dialog>
<button commandfor="hinweis" command="show-modal">Hinweis anzeigen</button>
  • Ein <dialog> ist standardmäßig unsichtbar - egal was drinsteht
  • commandfor="hinweis" verbindet den Button mit dem <dialog id="hinweis"> - genau wie popovertarget beim popover-Attribut, das weiter unten in diesem Kapitel vorkommt
  • command="show-modal" öffnet das Dialog modal: der Rest der Seite wird automatisch abgedunkelt und ist nicht mehr klickbar, bis das Dialog geschlossen wird
  • Kein JavaScript nötig - genau wie bei <details> und popover übernimmt der Browser das Öffnen komplett
  • Die Esc-Taste schließt ein modales Dialog automatisch - ebenfalls ganz ohne eigenen Code

Schließen ganz ohne JavaScript: <form method="dialog">

Abschnitt betitelt „Schließen ganz ohne JavaScript: <form method="dialog">“

Auch das Schließen braucht kein JavaScript - dafür reicht ein Formular mit method="dialog" innerhalb des Dialogs:

<dialog id="bestaetigung">
<p>Wirklich löschen?</p>
<form method="dialog">
<button value="abbrechen">Abbrechen</button>
<button value="loeschen">Löschen</button>
</form>
</dialog>
  • method="dialog" sorgt dafür, dass ein Klick auf irgendeinen Submit-Button im Formular das Dialog schließt, statt die Seite neu zu laden
  • Das funktioniert für jeden Button im Formular - “Abbrechen” und “Löschen” schließen beide das Dialog
<button commandfor="confirm-dialog" command="show-modal">Verwerfen...</button>
<dialog id="confirm-dialog">
<h2>Änderungen verwerfen?</h2>
<p>Ungespeicherte Änderungen gehen verloren.</p>
<form method="dialog">
<button value="cancel">Abbrechen</button>
<button value="discard" autofocus>Verwerfen</button>
</form>
</dialog>
#confirm-dialog {
border: none;
border-radius: 12px;
padding: 24px;
box-shadow: 0 8px 24px rgb(0 0 0 / 0.2);
}
#confirm-dialog::backdrop {
background-color: rgb(0 0 0 / 0.5);
}

Der abgedunkelte Hintergrund hinter einem modalen Dialog ist selbst ein Pseudo-Element, das ihr anpassen könnt:

dialog::backdrop {
background-color: rgb(0 0 0 / 0.7);
backdrop-filter: blur(4px);
}
dialog {
border: none;
border-radius: 12px;
padding: 24px;
max-width: 400px;
}
MethodeVerhalten
show()öffnet das Dialog, Rest der Seite bleibt bedienbar
showModal() / command="show-modal"öffnet modal: Rest der Seite abgedunkelt, nicht bedienbar, Fokus bleibt im Dialog gefangen
Fortgeschritten: Öffnen und Schließen per JavaScript - für später, wenn ihr JS könnt

Die deklarative Lösung von oben (command/commandfor + <form method="dialog">) reicht für die allermeisten Fälle. Kennt ihr schon JavaScript, geht dasselbe auch programmatisch - und ist die einzige Möglichkeit für Fälle, die sich nicht rein deklarativ lösen lassen (z.B. ein Dialog, das automatisch nach einem erfolgreichen API-Aufruf öffnet):

const dialog = document.querySelector("#hinweis");
document.querySelector("#oeffnen").addEventListener("click", () => {
dialog.showModal(); // entspricht command="show-modal"
});
dialog.close(); // entspricht command="close"

Nutzt ihr <form method="dialog">, landet der value des geklickten Buttons zusätzlich in dialog.returnValue - damit lässt sich per JavaScript auslesen, welcher Button gedrückt wurde:

dialog.addEventListener("close", () => {
console.log(dialog.returnValue); // "abbrechen" oder "loeschen"
});