Modale Dialoge ohne Framework – das native <dialog>-Element
Für ein Modal brauchst du kein Bibliotheks-Ballast und keine z-index-Schlacht. Das HTML-Element <dialog> bringt Overlay, Fokus-Falle und Schließen mit Escape von Haus aus mit. Ich zeige dir showModal(), ::backdrop und das saubere Schließen.
Jahrelang war ein Modal-Dialog im Web erstaunlich nervig: ein <div> mit position: fixed, ein Overlay dahinter, z-index-Gefummel, Tastatur-Fokus einfangen, Escape abfangen. Das kannst du dir heute sparen – das native <dialog>-Element macht das meiste selbst.
Das Markup
<dialog id="hinweis">
<form method="dialog">
<h2>Änderungen speichern?</h2>
<p>Deine Eingaben gehen sonst verloren.</p>
<menu>
<button value="abbrechen">Abbrechen</button>
<button value="speichern">Speichern</button>
</menu>
</form>
</dialog>
<button id="oeffnen">Dialog öffnen</button>Öffnen mit showModal()
const dlg = document.getElementById("hinweis");
document.getElementById("oeffnen").onclick = () => dlg.showModal();
dlg.addEventListener("close", () => {
console.log("Gewählt:", dlg.returnValue); // "speichern" oder "abbrechen"
});showModal() macht die eigentliche Arbeit: Es legt den Dialog oben auf die Seite (in die sogenannte Top-Layer, ganz ohne z-index), sperrt den Rest der Seite für Klicks, fängt den Tastatur-Fokus im Dialog und schließt bei Escape automatisch. Ein <form method="dialog"> schließt beim Absenden und schreibt den value des Buttons nach dialog.returnValue.
Das Overlay stylen mit ::backdrop
Den abgedunkelten Hintergrund gibt es gratis – du stylst ihn über das Pseudo-Element ::backdrop:
dialog {
border: none;
border-radius: 14px;
padding: 24px;
box-shadow: 0 20px 50px rgba(0,0,0,.25);
}
dialog::backdrop {
background: rgba(0,0,0,.5);
backdrop-filter: blur(2px);
}Wichtig: ::backdrop erscheint nur bei showModal(), nicht bei dialog.show() (nicht-modal, ohne Overlay).
Klick auf den Hintergrund schließt
Ein Detail, das Nutzer erwarten: Klick neben den Dialog schließt ihn. Das ist der einzige Teil, den du noch selbst ergänzt:
dlg.addEventListener("click", (e) => {
if (e.target === dlg) dlg.close(); // Klick traf das Backdrop, nicht den Inhalt
});<dialog> wird von allen aktuellen Browsern unterstützt. Weniger Code, bessere Barrierefreiheit (Fokus + Escape inklusive) – ich baue Modals in neuen Projekten nur noch so.
Quellen
Du brauchst mehr als ein Snippet?
Ich entwickle Android-Apps in Kotlin und moderne Websites für Selbstständige und kleine Unternehmen — von der ersten Idee bis zum Release.
Projekt anfragen →Verwandte Snippets
@layer in CSS: Kaskadenebenen statt !important-Wettrüsten
Irgendwann steht in jedem gewachsenen Stylesheet das erste !important – und ein halbes Jahr später das dreißigste. Mit @layer legst du die Reihenfolge einmal fest, und ab da gewinnt nicht mehr der längste Selektor, sondern die Ebene, die du bestimmt hast.
Tooltips ohne JavaScript – CSS Anchor Positioning
Ein Tooltip an einen Button hängen, der ausweicht, wenn oben kein Platz ist, und nicht am overflow: hidden der Elternbox scheitert – das brauchte jahrelang eine Bibliothek. Seit Firefox 147 kann das jeder große Browser in reinem CSS.
Schöne Zeilenumbrüche in CSS – text-wrap balance und pretty
Eine Überschrift, bei der ein einzelnes Wort einsam in der letzten Zeile hängt, sieht unruhig aus. Mit text-wrap balance und pretty überlässt du dem Browser das saubere Umbrechen – ohne manuelle <br> und ohne JavaScript.