Finestra di dialogo

L'elemento dialog è utile per rappresentare qualsiasi tipo di finestra di dialogo in HTML. Scopri come funziona.

Una finestra di dialogo modale è un tipo speciale di finestra popup in una pagina web: un popup che interrompe l'utente per attirare la sua attenzione. Esistono alcuni casi d'uso validi per la visualizzazione di una finestra di dialogo, ma prima di farlo è necessario valutare attentamente la situazione. Le finestre di dialogo modali costringono gli utenti a concentrarsi su contenuti specifici e, almeno temporaneamente, a ignorare il resto della pagina.

I dialoghi possono essere modali (è possibile interagire solo con i contenuti del dialogo) o non modali (è comunque possibile interagire con i contenuti esterni al dialogo). Le finestre di dialogo modali vengono visualizzate sopra il resto dei contenuti della pagina. Il resto della pagina è inerte e, per impostazione predefinita, è oscurato da uno sfondo semitrasparente.

L'elemento HTML semantico <dialog> per creare una finestra di dialogo è dotato di semantica, interazioni con la tastiera e tutte le proprietà e i metodi dell'interfaccia HTMLDialogElement.

Ecco un esempio di <dialog> modale. Apri la finestra di dialogo con il pulsante "Apri finestra di dialogo modale". Una volta aperta, esistono tre modi per chiudere la finestra di dialogo: il tasto Esc, l'invio di un modulo con un pulsante su cui è impostato formmethod="dialog" (o se il modulo stesso ha method="dialog" impostato) e il metodo HTMLDialogElement.close().

HTMLDialogElement ha tre metodi principali, oltre a tutti i metodi ereditati da HTMLElement.

dialog.show() /* opens the dialog */
dialog.showModal() /* opens the dialog as a modal */
dialog.close() /* closes the dialog */

Poiché questo <dialog> è stato aperto tramite il metodo HTMLDialogElement.showModal(), si tratta di una finestra di dialogo modale. L'apertura di una finestra di dialogo modale disattiva e oscura tutto tranne la finestra di dialogo stessa. Se scorri sopra l'interfaccia utente all'esterno della finestra di dialogo, noterai che tutti gli elementi si comportano come se fosse impostato pointer-events: none;. Anche il pulsante che apre la finestra di dialogo non reagisce alle interazioni.

Quando la finestra di dialogo viene aperta, lo stato attivo viene spostato al suo interno. Lo stato attivo viene impostato sul primo elemento nell'ordine di navigazione sequenziale della tastiera all'interno della finestra di dialogo. Se premi ripetutamente il tasto tab, noterai che solo i contenuti all'interno della finestra di dialogo possono acquisire lo stato attivo mentre la finestra di dialogo modale è aperta. Tutto ciò che si trova all'esterno della finestra di dialogo modale è inattivo finché la finestra di dialogo è aperta.

Quando una finestra di dialogo viene chiusa, modale o meno, lo stato attivo viene restituito all'elemento che ha aperto la finestra di dialogo. Se apri programmaticamente una finestra di dialogo non basata sull'azione dell'utente, riconsidera la tua scelta. Se necessario, assicurati che lo stato attivo venga ripristinato al valore precedente all'apertura della finestra di dialogo, soprattutto se l'utente chiude la finestra di dialogo senza interagire con essa.

Esiste un attributo inert globale che può essere utilizzato per disattivare un elemento e tutti i suoi discendenti, ad eccezione di eventuali dialoghi attivi. Quando viene aperta una finestra di dialogo modale utilizzando showModal(), l'inerzia o la disattivazione è senza costi; l'attributo non è impostato esplicitamente.

Lo sfondo che oscura tutto tranne la finestra di dialogo può essere personalizzato utilizzando lo pseudo-elemento ::backdrop. Lo sfondo viene visualizzato solo quando viene visualizzato un <dialog> con il metodo .showModal(). Questo pseudo-elemento corrisponde a tutti gli sfondi, incluso quello visualizzato quando viene utilizzata l'API Fullscreen, ad esempio quando si guarda un video in modalità a schermo intero che non ha le stesse proporzioni dello schermo o del monitor.

Finestre di dialogo non modali

Analogamente, HTMLDialogElement.show() apre una finestra di dialogo, ma senza aggiungere uno sfondo o causare l'inerzia di alcun elemento. Il tasto Esc non chiude le finestre di dialogo non modali. Per questo motivo, è ancora più importante assicurarsi di includere un metodo per chiudere la finestra di dialogo non modale. In questo modo, se il pulsante di chiusura si trova all'esterno della finestra di dialogo, lo stato attivo passerà all'elemento che ha aperto la finestra di dialogo, il che potrebbe non essere la migliore esperienza utente.

Sebbene un pulsante per chiudere la finestra di dialogo non sia ufficialmente richiesto dalla specifica, consideralo obbligatorio. Il tasto Esc chiude una finestra di dialogo modale, ma non una non modale. Un pulsante visibile in grado di ricevere lo stato attivo migliora l'accessibilità e l'esperienza utente.

Chiusura di una finestra di dialogo

Non è necessario il metodo HTMLDialogElement.close() per chiudere una finestra di dialogo. Non è necessario JavaScript. Per chiudere il <dialog> senza JavaScript, includi un modulo con un metodo di finestra di dialogo impostando method="dialog" su <form> o formmethod="dialog" sul pulsante.

Quando un utente invia i dati tramite il metodo dialog, lo stato dei dati inseriti dall'utente viene mantenuto. Anche se è presente un evento di invio, il form viene sottoposto a convalida dei vincoli (a meno che non sia impostato novalidate), ma i dati utente non vengono né cancellati né inviati. Un pulsante di chiusura senza JavaScript può essere scritto come segue:

<dialog open>
  <form method="dialog">
    <button type="submit" autofocus>close</button>
  </form>
</dialog>

In questo esempio potresti aver notato l'attributo autofocus impostato su <button> di chiusura. Gli elementi con l'attributo autofocus impostato all'interno di un <dialog> non riceveranno il focus al caricamento della pagina (a meno che la pagina non venga caricata con la finestra di dialogo visibile). Tuttavia, acquisiranno lo stato attivo quando la finestra di dialogo viene aperta.

Per impostazione predefinita, quando viene aperta una finestra di dialogo, lo stato attivo viene impostato sul primo elemento attivabile al suo interno, a meno che un altro elemento all'interno della finestra di dialogo non abbia l'attributo autofocus impostato. L'impostazione dell'attributo autofocus sul pulsante di chiusura garantisce che riceva lo stato attivo quando la finestra di dialogo viene aperta. Tuttavia, l'inclusione di autofocus in un <dialog> deve essere fatta con molta attenzione. Tutti gli elementi della sequenza che precedono l'elemento con lo stato attivo automatico vengono ignorati. Discutiamo ulteriormente di questo attributo nella lezione sul focus.

L'interfaccia HTMLDialogElement include una proprietà returnValue. L'invio di un modulo con un method="dialog" imposta il returnValue sul name, se presente, del pulsante di invio utilizzato per inviare il modulo. Se avessimo scritto <button type="submit" name="toasty">close</button>, returnValue sarebbe toasty.

Quando una finestra di dialogo è aperta, è presente l'attributo booleano open, il che significa che la finestra di dialogo è attiva e con essa è possibile interagire. Quando una finestra di dialogo viene aperta aggiungendo l'attributo open anziché tramite .show() o .showModal(), la finestra di dialogo non sarà modale. La proprietà HTMLDialogElement.open restituisce true o false, a seconda che la finestra di dialogo sia disponibile per l'interazione o meno, non se è modale o meno.

Sebbene JavaScript sia il metodo preferito per aprire una finestra di dialogo, l'inclusione dell'attributo open al caricamento della pagina e la relativa rimozione con .close() può contribuire ad assicurare che la finestra di dialogo sia disponibile anche quando JavaScript non è attivo.

Ulteriori dettagli

Non utilizzare tabindex

L'elemento attivato per aprire la finestra di dialogo e il pulsante di chiusura in essa contenuto (e possibilmente altri contenuti) possono ricevere il fuoco e sono interattivi. L'elemento <dialog> non è interattivo e non riceve lo stato attivo. Non aggiungere la proprietà tabindex alla finestra di dialogo stessa.

Ruoli ARIA

Il ruolo implicito è dialog. Se la finestra di dialogo è una finestra di conferma che comunica un messaggio importante che richiede una conferma o un'altra risposta dell'utente, imposta role="alertdialog". La finestra di dialogo deve avere anche un nome accessibile. Se il testo visibile può fornire il nome accessibile, aggiungi aria-labelledby="idOfLabelingText".

Valori predefiniti CSS

Tieni presente che i browser forniscono uno stile predefinito per dialog. Firefox, Chrome ed Edge impostano color: CanvasText; background-color: Canvas; e Safari imposta color: black; background-color: white; nei fogli di stile degli user-agent. color viene ereditato da dialog e non da body o :root, il che potrebbe essere inaspettato. La proprietà background-color non viene ereditata.

Verificare di aver compreso

Metti alla prova le tue conoscenze sull'elemento di dialogo.

Come si applica uno stile all'area dietro la finestra di dialogo?

Con lo pseudo-elemento ::backdrop.
Con la proprietà background.
Con lo pseudo-elemento ::background.