SELFHTML wird 30 Jahre alt! → Veranstaltungs-Ankündigung.
Infobox/modale Dialogfenster
Eine Dialog-Box ist ein neues Fenster, das sich über die Webseite legt, um eine Frage zu stellen, eine Eingabe abzufragen oder mehrere Optionen anzubieten. Dabei muss unterschieden werden:
- Popover (aus dem letzten Kapitel) zeigen Benachrichtigungen oder zusätzliche Informationen. Der Nutzer kann sie beachten, aber auch normal weiterarbeiten.
- Modale Dialogfenster erfordern wie alert() in JavaScript sofortige Aufmerksamkeit. Während sie geöffnet sind, ist die darunter liegende Webseite nicht aktiv und kann erst wiederverwendet werden, wenn die Dialog-Box geschlossen ist. Dies muss durch den Nutzer ausdrücklich bestätigt werden, was in der Regel durch Anklicken einer Schaltfläche innerhalb des Containers geschieht. In HTML5 wurde dafür das dialog-Element eingeführt, das seit 2022 von allen Browsern unterstützt wird.
Inhaltsverzeichnis
dialog - ein Offenlegungs-Widget
Das dialog-Element ist wie ein div ein Container-Element für die in der Popup-Box enthaltenen Inhalte. Standardmäßig ist das Element nicht sichtbar.
Dialoge können Formulare enthalten. Entweder gewöhnliche, die zu einem GET oder POST-Request an den Server führen und die Seite neu laden, oder mittels <form method="dialog">
spezielle Dialog-Formulare.
Mit einem Klick auf einen Button im Formular wird der Dialog ganz ohne JavaScript geschlossen. Der Inhalt des value
Attributs, das sich am geklickten Button befindet, wird dabei in die returnValue
Eigenschaft des HTMLDialogElement-Objekts übertragen.[1]
open-Attribut
Das boolesche Attribut open gibt an, ob der Dialog aktiv ist. Ist das Attribut vorhanden und enthält entweder den leeren String oder den String 'open'
, bedeutet dies, dass der Dialog aktiv ist. Wird das Attribut weggelassen, bedeutet dies, dass der Dialog inaktiv ist und vom Browser nicht angezeigt werden soll.
Ein Blick in den Seiteninspektor zeigt folgende Festlegung im Browser-Stylesheet:
/* Festlegung im Default-Stylesheet der Browser */
dialog:not([open]) {
display: none;
}
/* Styling der geöffneten Popup-Box */
dialog[open] {
width: 20em;
background: #fffbf0;
border: thin solid #e7c157;
margin: 5em auto;
}
Öffnen und Schließen
Ursprünglich war das dialog-Element dazu gedacht, im Zusammenspiel mit JavaScript geöffnet und auch wieder geschlossen zu werden. Das Dialog-Element besitzt sein eigenes DOM-Interface, das das Steuern von Ein-/Ausblenden und eventuellen Rückgabewerten ermöglicht.
Mittlerweile gibt es mehrere Möglichkeiten, Dialoge durch den Browser ohne JavaScript zu bedienen.
Öffnen mit showModal()
Für das Einblenden eines dialog-Elements mit JavaScript werden gleich zwei Optionen zur Verfügung gestellt:
dialog.show()
- wird verwendet, um einen Dialog zu öffnen.
dialog.showModal()
- öffnet den Dialog ebenfalls und macht ihn zusätzlich zum vordergründigsten Dialog der Anwendung. D.h. alle interaktiven Elemente der Webseite, außer den Kind-Elementen des modal geöffneten Dialogs, werden gesperrt. Es ist zulässig, weitere modale Dialoge zu öffnen. Jedes weitere Öffnen blockiert den bereits offenen modalen Dialog.
document.getElementById("show-dialog").addEventListener("click", () => {
document.getElementById("dialog").showModal();
});
document.getElementById("close-dialog").addEventListener("click", () => {
document.getElementById("dialog").close();
});
Das dialog-Element ist ursprünglich geschlossen. Durch einen Klick auf den Button mit der id show-dialog
wird das dialog-Element per JavaScript mit der showModal()
-Methode geöffnet.
Damit die Dialog-Box die volle Aufmerksamkeit des Nutzers bekommt, befindet sich zwischen Dokument und der geöffneten Dialog-Box nun eine durchscheinende Schicht, die einen Zugriff auf das darunterliegende Dokument solange verhindert, bis die Dialog-Box geschlossen wird.
Die Schicht wird durch das Pseudoelement ::backdrop
erzeugt, die den Seitenhintergrund mit einem durchscheinenden Overlay verdunkelt. Die dahinterliegende, eigentliche Webseite wird im Stack des Top-Layers versteckt und ist inaktiv.
dialog::backdrop {
background: hsl(201 50% 40% /.5) ;
}
document.getElementById("dialog").show();
und beobachte die Unterschiede.modal oder nichtmodal?
Wie in der Einführung bereits erwähnt, wird die Webseite bei einem modalen Dialogfenster inaktiv. Es wäre möglich, mehrere modale Dialogfenster zu öffnen, wobei das jeweils oberste die anderen ebenfalls inaktiv werden lässt.
Es gibt nichts Schlimmeres als auf der Suche nach Informationen erst ein Cookie-Banner wegklicken zu müssen, um dann nicht auf der Webseite selbst, sondern auf der Newsletter-Anmeldung hängenzubleiben.
Technisch ist dies möglich, aber für die Nutzer der Webseite ein Grund zum Abbruch.
Denke an die Benutzerfreundlichkeit (usability) deiner Webseite!
Öffnen mit command
Mit der oben vorgestellten Methode müssen Buttons neben dem showModal()-Aufruf noch entprechende aria-Attribute enthalten, damit das Öffnen des Dialogs barrierefrei wird.
Wäre es nicht einfacher, Buttons und Dialoge mit nativem Standardverhalten zu haben? Die open-ui.org hat analog zu popovertarget ein Öffnen und Schließen mit command und commandfor vorgeschlagen.[2][3]
Buttons mit command lösen - wenn sie angeklickt, berührt oder per Tastendruck ausgelöst werden - ein CommandEvent auf dem Element aus, auf das das commandfor-Attribut verweist:
<button command="show-modal" commandfor="my-dialog">
Öffne Dialog-Box!
</button>
<dialog id="my-dialog" closedby="any">
Ich bin eine Dialog-Box!
</dialog>
Die (ursprünglich versteckte) Dialog-Box kann durch den Button ohne JavaScript geöffnet werden. Dieser hat zwei Attribute:
- Mit
command="show-modal"
wird dialog.showModal() aufgerufen. - Mit
commandfor="my-dialog"
wird der Button der dialog-Box mit dieser id zugeordnet.
Neben show-modal
sind auch weitere Aufrufe möglich:
Wert für command | Aufruf | entspricht popovertargetaction |
---|---|---|
show-popover | showModal() | - |
show-popover | showPopover() | show |
hide-popover | hidePopover() | hide |
toggle-popover | togglePopover() | toggle |
Langfristig sollen popovertarget
und popovertargetaction
durch command und commandfor ersetzt werden.
Diese Attribute sollen dann auch für select, audio und video eingesetzt werden können, wobei dies noch Änderungen unterworfen ist.
Schließen mit JavaScript
Eigentlich war es Standard, die Dialog-Box mit JavaScript zu schließen und sie dann auszuwerten:
dialog.close( [result] )
- schließt einen Dialog und weist einen eventuellen Rückgabewert zu, der mit dem optionalen Parameter
result
übergeben werden kann.
dialog.returnValue
- liefert den Rückgabewert, der zuvor mit
dialog.close
gesetzt wurde. Wurde dort kein Rückgabewert angegeben, wird stattdessen der leere String zurückgegeben.
document.getElementById("show-dialog").addEventListener("click", () => {
document.getElementById("dialog").showModal();
});
document.getElementById("close-dialog").addEventListener("click", () => {
document.getElementById("dialog").close();
});
Die im dialog-Element enthaltenen Inhalte sind ursprünglich nicht sichtbar.
Erst ein Klick auf den Button mit der id show-dialog
öffnet die Dialog-Box.
Ein Klick auf den close-dialog
Button schließt das Dialog-Fenster wieder mit der close()
-Methode.
returnValue
Eigenschaft ihren Wert.light dismiss mit closedby
Im letzten Beispiel wurde kurz erwähnt, dass ESC eine Dialog-Box wieder schließt. Dies kennen Nutzer von anderen Programmen und Formularen und ist so erwartetes Verhalten. Ähnlich ist es mit einer light-dismiss-Funktionalität (leichtes Verlassen). Wenn man außerhalb des Dialog-Bereichs klickt, wird die Dialog-Box geschlossen.
Dies ist mit dem neuen closedby-Attribut möglich, wenn der Wert auf any
gesetzt wird:
<button command="show-modal" commandfor="my-dialog">
Öffne Dialog-Box!
</button>
<dialog id="my-dialog" closedby="any">
Ich bin eine Dialog-Box!
</dialog>
Manuel Matuzović hat die Möglichkeiten, eine Dialog-Box zu schließen, zusammengefasst:[4]
- Ein button in einem form method=dialog, wie im 1. Beispiel
- light dismiss mit
closedby="any"
- die ESC-Taste, wenn man eine Tastatur hat
- Bei Android
- mit einem Klick auf den back-Button.
- mit TalkBack on Android mit der “back” Geste/ nach unten und rechts wischen (Swipen).
Anwendungsbeispiel
::backdrop und :modal - Animation mit CSS
Bei modalen Dialogen ist die Webseite inaktiv, bis die Dialogbox geschlossen ist. Um dies zu kennzeichnen, wurde bereits im oberen Beispiel der Hintergrund ausge„blaut“.
Man kann den Hintergrund, aber auch das Öffnen mit CSS gestalten und auch animieren. Dabei wird häufig auf das vermeintlich Bewährte zurückgegriffen: Das Setzen und Entfernen einer Klasse. Zumindest für das Öffnen kannst du aber auch die :modal-Pseudoklasse als Selektor verwenden:
dialog:modal {
width: 20em;
background: #fffbf0;
border: thin solid #e7c157;
margin: 5em auto;
animation: show 1s ease normal;
}
@keyframes show{
from {
transform: translateY(-110%);
}
to {
transform: translateY(0%);
}
}
dialog::backdrop {
background: hsl(201 50% 40% /.5);
animation: none;
}
dialog[open]::backdrop {
animation: show-backdrop 2s ease forwards;
}
@keyframes show-backdrop {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
Die Dialog-Box wird beim Öffnen mit einer CSS-Animation von oben eingeschoben. Dies funktioniert in allen Browsern.
Das ::backdrop-Pseudoelement wird ebenfalls sanft eingeblendet. Dies funktioniert (Stand: März 2025) in allen Browsern außer dem Firefox. In diesem wird der Hintergrund ohne die Animation dargestellt. Eine Alternative wäre ein seitenfüllender box-shadow anstelle des ::backdrop-Elements oder ein seitenfüllendes, halbtransparentes Dialog-Element, das mit einem kleineren Kind-Element arbeitet.
Ein animiertes Schließen funktioniert (noch) nicht mit reinem CSS. Eine Alternative stellt Geckotang vor, der beim Schließen eine Klasse .hide
hinzufügt, die dialog und ::backdrop ausblendet und dann nach dem transitionend die Klasse wieder entfernt. [5][6]
Siehe auch
- Bildwechsler
- Lightbox
- Thumbnail und Großansicht
- Bildwechsler
- Lightbox
- Eigene modale Dialogfensteralert, confirm und prompt sind heute verpönt. Dieses Tutorial zeigt, wie man diese mit einem eigenen modalen Dialog nachbauen kann.
- Kontextmenü
- menu
- contextmenu-Event
- Zusammenfassung für längere Artikel
Weblinks
- ↑ WHATWG: dialog element
- ↑ open-ui.org: Invokers (Explainer)
- ↑ Invoker Commands: Additional Ways to Work With Dialog, Popover… and More? Daniel Schwarz on Nov 22, 2024 (css-tricks.com)
- ↑ Close requests, close watchers, and the dialog element Manuel Matuzović am 07.03.2025 (matuzo.at)
- ↑ <dialog> with animation by geckotang
- ↑ Dialogkomponente erstellen (und animieren) (web.dev)
- ↑ ::backdrop doesn’t inherit from anywhere (KilianValkhoff, 19 January 2023, )