Moderne modale Dialogfelder unterstützen häufig das Schließen durch Tippen oder Klicken auf den Hintergrund (den Bereich außerhalb des Dialogfelds). Das Attribut closedby bietet eine deklarative Möglichkeit, dieses Verhalten ohne benutzerdefiniertes JavaScript zu aktivieren.
Implementierung
So aktivieren Sie das Schließen durch Tippen:
- Fügen Sie dem
<dialog>-Elementclosedby="any"hinzu. - Öffnen Sie das Dialogfeld mit
dialog.showModal().
Attributwerte
any: Ermöglicht das Schließen durch Klicken auf den Hintergrund, „Schließen-Anfragen“ (die TasteEsc) und Entwicklermechanismen (z.B.dialog.close()).closerequest: Aktiviert nur „Anfragen schließen“ und Entwicklermechanismen. Dies ist die Standardeinstellung für modale Dialogfelder.none: Das Dialogfeld kann nur über Entwicklermechanismen geschlossen werden.
Hintergrund gestalten
Wenn ein Dialogfeld mit showModal() als modales Fenster geöffnet wird, generiert der Browser ein Pseudoelement ::backdrop. Dieser Hintergrund deckt den gesamten Darstellungsbereich ab und befindet sich direkt hinter dem Dialogfeld.
/* Style the backdrop to indicate the dialog is modal */
dialog::backdrop {
background-color: rgba(0, 0, 0, 0.5);
backdrop-filter: blur(2px); /* Optional: add blur for modern browsers */
}
Beispiel
<!-- MANDATORY: Use closedby="any" to enable light-dismiss behavior -->
<dialog id="myDialog" closedby="any" aria-labelledby="dialogTitle">
<form method="dialog">
<h2 id="dialogTitle">Feedback</h2>
<p>Click outside this box or press Esc to dismiss.</p>
<button type="submit">Close</button>
</form>
</dialog>
<button onclick="document.getElementById('myDialog').showModal()">Open Dialog</button>
Einschränkungen und Barrierefreiheit
- OBLIGATORISCH: Verwenden Sie
closedby="any", um das Schließen durch Tippen deklarativ zu aktivieren. - OBLIGATORISCH: Modale Dialogfelder immer mit
showModal()öffnen. So wird sichergestellt, dass sich das Dialogfeld in der obersten Ebene befindet, der Fokus eingeschlossen ist und dieEsc-Taste verarbeitet wird. - EMPFOHLEN: Verwenden Sie
aria-labelledbyoderaria-label, um einen barrierefreien Namen für das Dialogfeld anzugeben. - NICHT EMPFOHLEN:
closedbyfür nicht modale Dialogfelder verwenden (geöffnet mitshow()), da sie keinen Hintergrund haben und kein Light Dismiss auslösen. - NICHT EMPFOHLEN: Verwenden Sie das Ereignis
clicknicht für kritische Logik, die vor dem Schließen ausgeführt werden soll. Verwenden Sie stattdessen die Ereignissecloseodercancel.
Fallback-Strategien
OBLIGATORISCH: Für Browser, die closedby noch nicht unterstützen, müssen Sie ein Fallback für das Schließen durch Klicken außerhalb des Dialogfelds implementieren. Prüfen Sie dazu mit dem folgenden Script, ob ein Klick außerhalb der Grenzen des Dialogfeldinhalts erfolgt ist:
const dialog = document.querySelector('dialog');
// Fallback for browsers without closedby support
if (!('closedBy' in HTMLDialogElement.prototype)) {
dialog.addEventListener('click', (event) => {
// 1. When clicking the backdrop, the event target is the dialog element itself.
// Ignore clicks where the target is a child element inside the dialog.
if (event.target !== dialog) return;
// 2. Check if the click coordinates fall within the dialog's content box.
// This distinguishes between a click on the backdrop vs a click on the dialog's background/padding.
const rect = dialog.getBoundingClientRect();
const isDialogContent = (
rect.top <= event.clientY &&
event.clientY <= rect.top + rect.height &&
rect.left <= event.clientX &&
event.clientX <= rect.left + rect.width
);
if (isDialogContent) return;
// 3. Since the click was outside the content area (on the backdrop), manually close the dialog.
dialog.close();
});
}