Dialogfeld durch Tippen außerhalb des Dialogfelds schließen

Webfunktionen: <dialog closedby>

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:

  1. Fügen Sie dem <dialog>-Element closedby="any" hinzu.
  2. Öffnen Sie das Dialogfeld mit dialog.showModal().

Attributwerte

  • any: Ermöglicht das Schließen durch Klicken auf den Hintergrund, „Schließen-Anfragen“ (die Taste Esc) 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 die Esc-Taste verarbeitet wird.
  • EMPFOHLEN: Verwenden Sie aria-labelledby oder aria-label, um einen barrierefreien Namen für das Dialogfeld anzugeben.
  • NICHT EMPFOHLEN: closedby für nicht modale Dialogfelder verwenden (geöffnet mit show()), da sie keinen Hintergrund haben und kein Light Dismiss auslösen.
  • NICHT EMPFOHLEN: Verwenden Sie das Ereignis click nicht für kritische Logik, die vor dem Schließen ausgeführt werden soll. Verwenden Sie stattdessen die Ereignisse close oder cancel.

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();
  });
}