Stephan Böni - Dialoge

Dialoge

Dialoge

In einer modernen Web-Anwendung werden viele Arten von Dialogboxen verwendet. Unter dem Begriff Dialog werden alle Popups, Toasts, Sliders, Flyouts usw. zusammengefasst. Das HTML-Element <dialog> sollte für alle diese Dialogvarianten verwendet werden, um sowohl modale als auch nicht-modale Dialogboxen zu erstellen. Modale Dialogboxen unterbrechen die Interaktion mit dem Rest der Seite, die als inaktiv betrachtet wird, während nicht-modale Dialogboxen die Interaktion mit dem Rest der Seite erlauben.

Es ist also an der Zeit, alles unter einen Hut zu bringen.

Dialoge aufrufen

In den meisten Fällen öffnet sich ein Dialog bei Klick auf einen Button. Das können wir ganz einfach automatisieren, indem wir dem Button das Attribut data-dialog-target="selector" geben. Als Selector ist die DOM-Adresse zum Dialog (QuerySelector) zu hinterlegen.

HTML <button data-dialog-target="#myDialog">Dialog öffnen</button> <dialog id="myDialog">Das ist ein Dialog.</dialog>

Damit sich bei Klick ein modaler Dialog öffnet, braucht es noch etwas Javascript. Und damit das Ganze optisch stimmt, auch etwas CSS.

Dialoge per Javascript laden

Das erforderliche Javascript sollte erst initialisiert werden, nachdem die Seite geladen ist. Dabei lagern wir die eigentliche Magie in ein separates Modul aus.

default.js // Load Module async function loadModule(module) { const file = './modules/' + module.charAt(0).toLowerCase() + module.slice(1) + '.js'; const mod = await import(file); return new mod[module]; } // Load Dialogs async function loadDialogs() { const Dialog = await loadModule('Dialog'); document.addEventListener('click', (event) => Dialog.init('click', event)); document.addEventListener('resize', (event) => Dialog.init('resize', event)); document.addEventListener('scroll', (event) => Dialog.init('scroll', event)); const tooltips = document.querySelectorAll('[title]'); for (const tooltip of tooltips) { tooltip.addEventListener('mouseenter', (event) => Dialog.init('mouseenter', event)); tooltip.addEventListener('focus', (event) => Dialog.init('focus', event)); } } // Do on DOM Ready document.addEventListener('DOMContentLoaded', () => { loadDialogs(); });

Ich sammle die Klassenmodule im Unterordner modules und nenne die Dateien wie die Klasse, aber mit Kleinbuchstaben beginnend. Die Klasse Dialog befindet sich also in ./modules/dialog.js.

Im Grunde enthält die Klasse Dialog neben dem Constructor nur die Methoden Init für die EventListeners, sowie Open und Close zum Öffnen und Schliessen eines Dialogs. Du kannst diese Datei gerne zur Verwaltung deiner Dialoge verwenden.

dialog.js herunterladen

Dialoge stylen

Der ganze Rest ist nun noch etwas CSS, damit die Dialoge schön aussehen. Doch da gibt es viel zu beachten.

Wir bauen auf einem Standard-Dialog auf, der modal und zentriert ausgerichtet ist.

CSS dialog { max-height: calc(100vh - 3.2rem); min-width: 28rem; max-width: clamp(28rem, calc(100vw - 3.2rem), 80rem); box-shadow: 0 0 1.6rem var(--default-color); outline: 0; border: none; border-radius: 0.8rem; padding: 0; background-color: var(--bg-color); color: var(--text-color); flex-direction: column; &::backdrop { background-color: transparent; } &[open]:last-of-type::backdrop { backdrop-filter: blur(0.4rem) brightness(80%); -webkit-backdrop-filter: blur(0.4rem) brightness(80%); } &[open], &:popover-open { display: flex; &:has(~ dialog[open])::backdrop { backdrop-filter: none; -webkit-backdrop-filter: none; } } } body:has(:modal) { overflow: hidden; padding-right: var(--scrollbar-width); }

Über ::backdrop dunkeln wir den Hintergrund etwas ab und machen ihn unscharf. Dabei stellen wir sicher, dass bei mehreren überlagernden Dialogen nur der oberste diesen Hintergrundfilter verwendet. Dass die Seite im Hintergrund nicht scrollbar ist, stellen wir über :modal sicher.

Wir erwarten, dass der Dialoginhalt aus einem Kopfbereich und einem Inhaltsbereich besteht und stellen sicher, dass letzterer scrollbar ist.

CSS .dialogHeader { display: flex; border-bottom: 0.1rem solid var(--default1-color); background-color: var(--default2-color); p { margin: auto 0.8rem auto 1.6rem; flex-grow: 1; font-size: 2rem; text-wrap: balance; } button { /* set close button styles here */ } } .dialogContent { min-width: 100%; max-width: 100%; min-height: 8rem; padding: 1.6rem 0; overflow: auto; resize: both; p { margin: 0.8rem 1.6rem; } }

Dialoge testen

Damit ist bereits alles Notwendige getan und wir können den Standard-Dialog testen.

Dialoge nachladen

Es ist nicht sehr sinnvoll, Dialoge im initialen Quelltext auszuliefern, da sie vielleicht gar nie geöffnet werden. Daher sollten sie erst nachgeladen werden, wenn sie wirklich gebraucht werden. Dies lösen wir, indem wir dem aufrufenden Button im Attribut data-dialog-target statt einem Selektor den Namen des zu landenden Bausteins geben. Als Präfix ist dazu ein Tilde-Zeichen erforderlich.

HTML <button data-dialog-target="~dialogSample">Dialog öffnen</button>

Die dialog.js lädt dann die Datei /includes/components/dialogSample.html, die den HTML-Code des Dialogs enthält.

dialogSample.html <dialog> <header class="dialogHeader"> <p>Beispiel</p> <button class="icon icon-close" data-dialog-close="1" title="Dialog schliesssen"></button> </header> <div class="dialogContent"> <p>Das ist ein Dialog.</p> <p><button data-dialog-close="1">Schliessen</button></p> </div> </dialog>

Damit ist bereits alles Notwendige getan und wir können den Dialog testen.

Weitere Dialogvarianten

Natürlich gibt es neben dem hier gezeigten modalen Standard-Dialog noch viele weitere Dialogvarianten, modale und nicht-modale. Die oben angebotene dialog.js deckt alle wichtigen ab. Und nachfolgend findest du die Anleitungen.

Slide

Slider

Der Slider schiebt sich von rechts in die Seite und nimmt die gesamte Höhe ein, während links immer etwas Hintergrund sichtbar bleibt. Bei gestapelten Sliders ist links noch etwas des direkt darunterliegenden Sliders sichtbar.

Slider

Context

Kontextmenü

Das Kontextmenü ist ein modaler Dialog, der sich am geklickten Button ausrichtet. Der Hintergrund wird nicht gefiltert. Jeder Klick auf einen Link oder Button schliesst das Kontextmenü. Bei Smartphones (kleiner als 480 Pixel Breite oder Höhe) wird das Kontextmenü aus Platzgründen wie ein Standard-Dialog behandelt.

Kontextmenü

Cookie

Cookie-Bestätigung

Die Cookie-Bestätigung ist ein spezieller modaler Dialog. Sie wird am unteren Rand eingeblendet und kann nicht ohne Entscheidung geschlossen werden.

Cookie-Bestätigung

Toast

Toast

Ein klassischer nicht-modaler Dialog ist der Toast. Toasts sind Benachrichtigungen, die üblicherweise unten links oder rechts eingeblendet werden und die Bedienbarkeit der Seite nicht unterbrechen. Wir unterscheiden vier Arten von Toast-Benachrichtigungen: Information (info), Erfolg (success), Warnung (warning) und Fehler (error). Informations- und Erfolgsmeldungen werden nach fünf Sekunden automatisch ausgeblendet.

Toast

Flyout

Flyout

Das Flyout ist eine spezielle und nicht-modale Art eines Kontextmenüs. Wenn der Benutzer mit der Maus über ein bestimmtes Element (einen Menüpunkt) fährt, klappt ein Untermenü aus.

Flyout

Tooltipp

Tooltipp

Der Tooltipp ist ein nicht-modaler Dialog und verhält sich mehrheitlich analog zum Flyout, bekommt aber keinen Fokus. Gegenüber dem nativen Tooltipp erscheint er bei Mouseover weniger verzögert. Zudem erscheint er ebenfalls bei Tastatur-Fokus.

Tooltipp

Dran bleiben

Du hast es geschafft. Abonniere meine Benachrichtigungen, um weitere News und Anleitungen von mir zu erhalten.

Feed einbinden