Chiudi una finestra di dialogo con un tocco

Funzionalità web: <dialog closedby>

Le finestre di dialogo modali moderne spesso supportano la "chiusura rapida", che consente agli utenti di chiudere una finestra di dialogo facendo clic o toccando lo sfondo (l'area all'esterno della finestra di dialogo). L'attributo closedby fornisce un modo dichiarativo per attivare questo comportamento senza JavaScript personalizzato.

Implementazione

Per attivare la chiusura semplice:

  1. Aggiungi closedby="any" all'elemento <dialog>.
  2. Apri la finestra di dialogo utilizzando dialog.showModal().

Valori degli attributi

  • any: attiva la chiusura automatica (facendo clic sullo sfondo), le "richieste di chiusura" (il tasto Esc) e i meccanismi per gli sviluppatori (ad es. dialog.close()).
  • closerequest: attiva solo le "richieste di chiusura" e i meccanismi per gli sviluppatori. Questa è l'impostazione predefinita per le finestre di dialogo modali.
  • none: solo i meccanismi dello sviluppatore possono chiudere la finestra di dialogo.

Stile dello sfondo

Quando una finestra di dialogo viene aperta come modale utilizzando showModal(), il browser genera uno pseudo-elemento ::backdrop. Questo sfondo copre l'intera area visibile e si trova direttamente dietro la finestra di dialogo.

/* 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 */
}

Esempio

<!-- 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>

Vincoli e accessibilità

  • OBBLIGATORIO: utilizza closedby="any" per attivare la chiusura semplice in modo dichiarativo.
  • OBBLIGATORIO: apri sempre le finestre di dialogo modali con showModal(). In questo modo, la finestra di dialogo si trova nel livello superiore, lo stato attivo è bloccato e il tasto Esc viene gestito.
  • DA FARE: utilizza aria-labelledby o aria-label per fornire un nome accessibile per la finestra di dialogo.
  • NON: utilizzare closedby per le finestre di dialogo non modali (aperte con show()), poiché non hanno uno sfondo e non attivano la chiusura automatica.
  • NON: utilizzare l'evento click per la logica critica che deve verificarsi prima della chiusura; ascolta invece gli eventi close o cancel.

Strategie di riserva

OBBLIGATORIO: per i browser che non supportano ancora closedby, devi implementare un comportamento di riserva per la chiusura automatica controllando se è stato fatto clic al di fuori dei limiti dei contenuti della finestra di dialogo utilizzando il seguente script:

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