Tag HTML <dialog>
Scopri il tag HTML <dialog>: show() vs showModal(), il pattern form method="dialog", eventi close e cancel, e accessibilità.
Il tag <dialog> è uno degli elementi HTML5. Crea una finestra di dialogo nativa — un pannello a comparsa come un messaggio di conferma, un avviso o un modulo — con cui l'utente interagisce prima di continuare. La finestra di dialogo è nascosta per impostazione predefinita e viene mostrata e nascosta tramite una piccola API JavaScript.
Questa pagina tratta i due modi per aprire una finestra di dialogo (show() e showModal()), come chiuderla e leggerne il risultato, il pattern <form method="dialog">, gli eventi close e cancel, l'accessibilità e lo stile del backdrop.
Perché usare <dialog> nativo invece di un modal <div> personalizzato?
Prima di <dialog>, gli sviluppatori costruivano i modal manualmente con un <div> e una serie di CSS e JavaScript. L'elemento nativo svolge questo lavoro al posto tuo e lo fa in modo più affidabile:
- Intrappolamento del focus integrato. Quando aperto con
showModal(), il focus da tastiera (Tab / Shift+Tab) rimane all'interno della finestra di dialogo. Un modal<div>deve intrappolare il focus manualmente, e sbagliarlo è un bug di accessibilità comune. - Stacking nel top layer. Una finestra di dialogo modale viene renderizzata nel top layer del browser, quindi viene sempre disegnata sopra il resto della pagina indipendentemente dal
z-index. Niente più conflitti conz-index. - Backdrop automatico.
showModal()disegna un pseudo-elemento::backdropdietro la finestra di dialogo che blocca i clic sulla pagina sottostante — nessun elemento overlay aggiuntivo necessario. - Esc per chiudere. Premere Esc chiude automaticamente una finestra di dialogo modale (attivando un evento
cancela cui puoi reagire). - Semantica reale. L'elemento porta un
role="dialog"implicito, quindi le tecnologie assistive lo annunciano correttamente senza ARIA aggiuntiva.
Sintassi
Il tag <dialog> va in coppia. Metti il contenuto della finestra di dialogo tra il tag di apertura (<dialog>) e quello di chiusura (</dialog>). La apri dallo script con uno dei due metodi sull'object DOM dell'elemento:
dialog.show()— apre una finestra di dialogo non modale.dialog.showModal()— apre una finestra di dialogo modale.dialog.close([returnValue])— chiude la finestra di dialogo e registra facoltativamente un valore di ritorno.
L'attributo boolean open indica se la finestra di dialogo è attualmente visualizzata. In genere non lo si imposta manualmente; i metodi sopra lo gestiscono per te.
Finestre di dialogo non modali: show()
show() apre la finestra di dialogo in posizione, senza bloccare la pagina. Il resto del documento rimane interattivo, non c'è ::backdrop, il focus non è intrappolato e Esc non la chiude. Questa è la scelta giusta per pannelli non critici e richiudibili come una piccola casella degli strumenti, una nota "novità" o un selettore inline.
<!DOCTYPE html>
<html>
<head>
<title>Non-modal dialog with show()</title>
</head>
<body>
<button id="open">Open non-modal dialog</button>
<dialog id="info">
<p>You can still click and scroll the page behind me.</p>
<button id="close">Close</button>
</dialog>
<script>
const dialog = document.getElementById("info");
document.getElementById("open").addEventListener("click", () => {
dialog.show();
});
document.getElementById("close").addEventListener("click", () => {
dialog.close();
});
</script>
</body>
</html>Finestre di dialogo modali: showModal()
showModal() apre la finestra di dialogo come modale. Questo modifica il comportamento in quattro modi importanti:
- L'interazione è bloccata. Tutto ciò che è fuori dalla finestra di dialogo diventa inerte — clic e input da tastiera non possono raggiungere la pagina sottostante.
- Appare un backdrop. Il browser renderizza lo pseudo-elemento
::backdropdietro la finestra di dialogo, che puoi stilizzare. - Il focus è intrappolato. La tabulazione scorre solo tra gli elementi focalizzabili all'interno della finestra di dialogo.
- Entra nel top layer. La finestra di dialogo viene disegnata sopra tutto il resto del contenuto, ignorando il
z-index. Premere Esc la chiude.
<!DOCTYPE html>
<html>
<head>
<title>Modal dialog with showModal()</title>
<style>
dialog {
width: 40%;
border: 1px solid #ccc;
border-radius: 0.5em;
padding: 1em;
}
dialog::backdrop {
background-color: rgba(0, 0, 0, 0.5);
}
</style>
</head>
<body>
<button id="open">Open modal dialog</button>
<dialog id="confirm">
<p>The page behind is blocked. Press Esc or a button to close.</p>
<button id="close">Close dialog</button>
</dialog>
<script>
const dialog = document.getElementById("confirm");
document.getElementById("open").addEventListener("click", () => {
dialog.showModal();
});
document.getElementById("close").addEventListener("click", () => {
dialog.close();
});
</script>
</body>
</html>Il pattern <form method="dialog">
Un <form> all'interno di un <dialog> può usare method="dialog". Inviare tale modulo chiude la finestra di dialogo senza inviare una richiesta di rete, e il valore del <button> di invio cliccato viene memorizzato nella proprietà DOM returnValue della finestra di dialogo. Questo rende facile capire quale pulsante ha scelto l'utente.
<!DOCTYPE html>
<html>
<head>
<title>Dialog with a form</title>
</head>
<body>
<button id="open">Delete file</button>
<p id="result"></p>
<dialog id="confirm">
<form method="dialog">
<p>Are you sure you want to delete this file?</p>
<button value="cancel">Cancel</button>
<button value="delete">Delete</button>
</form>
</dialog>
<script>
const dialog = document.getElementById("confirm");
const result = document.getElementById("result");
document.getElementById("open").addEventListener("click", () => {
dialog.showModal();
});
dialog.addEventListener("close", () => {
// returnValue is the value of the button that submitted the form
result.textContent = "You chose: " + dialog.returnValue;
});
</script>
</body>
</html>returnValue è una proprietà dell'elemento DOM, non un attributo HTML — lo si legge o imposta da JavaScript. Puoi anche impostarlo direttamente alla chiusura nel codice: dialog.close("delete").
Gli eventi close e cancel
Un <dialog> attiva due eventi a cui puoi stare in ascolto:
| Evento | Quando si attiva |
|---|---|
close | Ogni volta che la finestra di dialogo viene chiusa — tramite close(), inviando un modulo method="dialog", o con Esc. Leggi returnValue qui. |
cancel | Quando l'utente chiude una finestra di dialogo modale con il tasto Esc. Si attiva prima di close. Chiama event.preventDefault() per mantenere aperta la finestra di dialogo. |
<dialog id="editor">
<p>Unsaved changes — Esc would normally close me.</p>
<button onclick="this.closest('dialog').close()">Done</button>
</dialog>
<script>
const dialog = document.getElementById("editor");
dialog.addEventListener("cancel", (event) => {
// Prevent Esc from discarding unsaved work
event.preventDefault();
});
dialog.addEventListener("close", () => {
console.log("Dialog closed");
});
</script>Per ulteriori informazioni su come collegare questi listener, consulta JavaScript Events e JavaScript HTML DOM.
Accessibilità
Un <dialog> ha un role="dialog" implicito, ma hai comunque bisogno di dargli un nome accessibile e gestire il focus:
- Nomina la finestra di dialogo. Punta
aria-labelledbyall'id dell'intestazione della finestra di dialogo in modo che i lettori di schermo ne annuncino il titolo. Usaaria-describedbyper una descrizione più lunga. - Focus all'apertura.
showModal()sposta il focus nella finestra di dialogo automaticamente — sul primo elemento focalizzabile, o su un elemento che contrassegni con l'attributoautofocus. Preferisci posizionareautofocussu un controllo sicuro (come Annulla) piuttosto che su uno distruttivo. - Ripristina il focus alla chiusura. Quando la finestra di dialogo si chiude, riporta il focus al controllo che l'ha aperta in modo che gli utenti da tastiera non si ritrovino in cima alla pagina. Con il
<dialog>nativo, il browser lo fa per te; per i risultati più sicuri, salva e ripristina il trigger tu stesso.
<button id="open">Edit profile</button>
<dialog id="profile" aria-labelledby="profile-title" aria-describedby="profile-desc">
<h2 id="profile-title">Edit profile</h2>
<p id="profile-desc">Update your display name, then save.</p>
<form method="dialog">
<input type="text" aria-label="Display name" autofocus>
<button value="save">Save</button>
</form>
</dialog>
<script>
const openButton = document.getElementById("open");
const dialog = document.getElementById("profile");
openButton.addEventListener("click", () => dialog.showModal());
// Explicitly return focus to the trigger when the dialog closes
dialog.addEventListener("close", () => openButton.focus());
</script>Consulta considerazioni sull'accessibilità del DOM per ulteriori informazioni sulla creazione di widget interattivi accessibili.
Stilizzare la finestra di dialogo e il suo backdrop
Puoi stilizzare la finestra di dialogo stessa e, per le finestre di dialogo modali, l'area dietro di essa con lo pseudo-elemento ::backdrop.
dialog {
border: 1px solid #ccc;
border-radius: 0.5em;
padding: 1em;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
}
/* Only rendered for dialogs opened with showModal() */
dialog::backdrop {
background-color: rgba(0, 0, 0, 0.5);
}Attributi
| Attributo | Valore | Descrizione |
|---|---|---|
open | open | Attributo boolean che indica che la finestra di dialogo è attualmente visualizzata. Di solito impostato da show() / showModal(). |
Il tag <dialog> supporta anche gli Attributi Globali e gli Attributi Evento.