Erstellen eines Dialogs mit nativem HTML

Hier ist er nun, der letzte Adventskalender-Blogbeitrag für 2024. Das bedeutet auch, dass viele von euch heute oder morgen Weihnachten feiern. Warum lest ihr also an einem solchen Tag Blogbeiträge? 😁

Im letzten Thema dieser Ausgabe geht es um ein weiteres HTML-Element, das ihr vielleicht noch nicht kanntet. Aber alle von euch kennen und hassen Cookie-Popups, richtig? Außer natürlich, ihr seid an der Entwicklung solcher Tools beteiligt. 😅

Das dialog HTML-Element

Wenn wir ein Popup erstellen „wollen“, haben wir in der Vergangenheit oft eine „Modal-Library“ verwendet. Aber jetzt haben wir ein eigenes HTML-Element dafür: das <dialog> Element. Es hat einige Gemeinsamkeiten mit dem details Element, über das ich vor vier Tagen gebloggt habe. Und wenn ihr die weiteren Ressourcen besucht habt, die ich dort verlinkt hatte, dann habt ihr das Element vielleicht schon kennengelernt. So würdet ihr es verwenden:

<dialog>
	Some Text inside the dialog.
</dialog>

Wenn ihr diesen Code in eure Seite einfügt, dann seht ihr … absolut nichts. Das Element ist nicht standardmäßig sichtbar. Ihr könnt das open Attribut hinzufügen, genau wie bei dem details Element, dann solltet ihr das hier sehen:

Chrome with open dev tools showing the properties of the open dialog element, that is centered on the page.

Wie ihr hier sehen könnt, erhalten wir mehr als nur ein leeres Element mit etwas Text. Das Dialogfeld hat einen Rahmen, einen Innenabstand und ist auf der Seite zentriert, wobei eine absolute Position und ein automatischer Außenabstand verwendet werden. Das würde sogar bedeuten, dass er über jedem Inhalt angezeigt wird, der nach ihm kommt.

Öffnen und Schließen des Dialogs

Ein Dialog, der standardmäßig geöffnet ist, ist nicht wirklich nützlich. Zum Glück gibt es einige JavaScript-Funktionen, mit denen wir ihn interaktiv gestalten können. Fügen wir also einen Button zum Öffnen des Dialogs und einen Button zum Schließen des Dialogs hinzu:

Chrome showing an open dialog element. The dev tools are open and at the bottom of the HTML markup tree, a "#top-layer" is shown after the closing html tag. The dialog has a paragraph and an undordered list. The page behind the dialog has an "Open dialog" button and inside the dialog, there is a "Read it" button at the end.

Dieser Screenshot zeigt mehrere Dinge auf einmal. Zuerst einmal haben wir die Webseite mit einem Button „Open Dialog“. Wenn dieser angeklickt wird, öffnet sich der Dialog, der dieses Mal etwas mehr HTML-Inhalt hat. Vielleicht ist euch auch aufgefallen, dass der Hintergrund der Website grau ist. Er ist eigentlich weiß, aber wenn der Dialog geöffnet ist, wird die Seite mit einem transparenten Overlay überlagert. Dies ist auch links mit der ::backdrop Pseudoelement zu sehen. Eine letzte Besonderheit ist der #top-layer nach dem HTML-Baum auf der linken Seite. Dies ist eine spezielle Ebene, die die gesamte Seite überdeckt und die Barrierefreiheit verbessert.

Wenn ihr auf den Button „Read it“ klickt, wird der Dialog geschlossen. Für die beiden Buttons benötigen wir etwas JavaScript, um diese Funktionalität umzusetzen:

const dialog = document.querySelector('dialog');
const openButton = document.querySelector('button#open-dialog');
const closeButton = document.querySelector('button#close-dialog');
openButton.addEventListener('click', () => {
	dialog.showModal();
});
closeButton.addEventListener('click', () => {
	dialog.close();
})

Wenn ihr die Funktion showModal() verwendet, spielt es keine Rolle, wo das Element im HTML-Baum platziert ist. Es wird immer in der Mitte der Seite geöffnet. Passt der Inhalt nicht hinein, wird eine Scrollbar angezeigt.

Alternative Möglichkeit zum Öffnen des Dialogs

Es gibt eine zweite Funktion zum Öffnen eines Dialogs. Sie heißt einfach show() und würde den Dialog „inline“ öffnen und nicht als „Modal“. In diesem Fall macht es einen Unterschied, wo der Dialog platziert wird. Es wird immer noch mit „position: absolute“ über dem Inhalt angezeigt, aber nicht mehr vertikal zentriert. Er wird genau dort angezeigt, wo sein HTML-Code im DOM platziert ist. Es gibt auch kein Hintergrund-Overlay und keinen #top-layer mehr, womit das Verhalten einige wichtige Unterschiede hat.

Schließen des Modals ohne JavaScript

Um den Dialog zu öffnen, benötigen ihr etwas JavaScript mit einer der beiden Funktionen, um es „anzuzeigen“. Es sei denn, ihr fügen das open Attribut hinzu, damit es standardmäßig geöffnet ist – ich frage mich wirklich, warum die Funktionen nicht openModal() und open() heißen, wenn das Element auch das open Attribut verwendet.

Um den Dialog zu schließen, brauchen ihr aber kein JavaScript. Ihr könnt ihn auch selbst schließen lassen, wenn du ein Formular als Inhalt hast:

<dialog open>
	<form method="dialog">
		Some text in the dialog.
		<button>OK</button>
	</form>
</dialog>

Siehst du den besonderen Trick mit dem Formular? Es verwendet den Wert dialog für das Attribut method. Dadurch wird der Dialog geschlossen, wenn das Formular mit einem Button darin abgeschickt wird. Ihr könnt also auch einfach nur ein Eingabefeld haben, dann wird der Dialog mit ENTER geschlossen.

Wenn der Dialog mit showModal() geöffnet wurde, kann dieses Modal auch mit der ESC-Taste geschlossen werden. Es gibt also verschiedene Möglichkeiten, es ohne JavaScript zu schließen.

Styling des Elements

Der Dialog selbst kann wie jeder andere „Container“ gestylt werden. Wie bereits gezeigt, verfügt es standardmäßig über einen Rahmen und einen Innenabstand. Spannender ist aber wahrscheinlich die Gestaltung des „Backdrops“. Hier ist ein Beispiel, welches den Dialog und den „Backdrop“ anpasst:

dialog {
	border-radius: 5px;
	border: 3px solid red;
	top: 30px;

	&::backdrop {
		background: black;
		opacity: 0.7;
	}
}

Wir ändern den Rahmen des Dialogs und auch den Hintergrund des „Backdrops“. Ach, und übrigens, was ihr hier seht, ist keine Sass-Syntax. Es handelt sich um natives verschachteltes CSS. Wenn ihr das noch nicht gesehen habt, lesen einfach den vorherigen Blogbeitrag „Verschachteltes CSS ohne Präprozessoren“ im Adventskalender. So würde es dann aussehen:

An open

Anstelle des rgba() Wertes für den Hintergrund verwenden wir nun eine bcakground-color in Kombination mit einer opactiy.

Noch mehr aus dem Element herausholen

Auf der Dokumentationsseite findet ihr viele weitere Beispiele dafür, wie ihr Formulare innerhalb des Elements verwenden, es gestalten und mit ihm interagieren könnt, und vieles mehr. Das alles wäre aber zu viel für diesen Blogbeitrag. Der CSS-Tricks-Blogbeitrag, der sich mit dem details Element beschäftigt, enthält auch einige Beispiele für das dialog Element.

Fazit

Ich hoffe, ich habe mir das beste Thema für heute aufgehoben. Zumindest fand ich dieses Element wirklich faszinierend und habe es in einem Projekt verwendet. Vielleicht blogge ich demnächst über diesen Anwendungsfall. Aber das ist etwas für das nächste Jahr. Dies war mein letzter Adventskalender-Blogbeitrag und auch der letzte für dieses Jahr, wenn ich meine zweiwöchige Blog-Routine einhalte.

Ich hoffe, ihr habt in den Adventskalender-Blogbeiträgen oder in den anderen Beiträgen, die ich in diesem Jahr geschrieben habe, ein paar neue Dinge gelernt. Es hat Spaß gemacht, aber es war auch viel mehr Arbeit, als ich dachte. Ich wünsche euch ein paar tolle Tage und wir sehen uns alle 2025! 🎇

Veröffentlicht von

Bernhard ist fest angestellter Webentwickler, entwickelt in seiner Freizeit Plugins, schreibt in seinem Blog über WordPress und andere Themen, treibt sich gerne bei den WP Meetups in Berlin und Potsdam herum und läuft nach Feierabend den ein oder anderen Halbmarathon.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert