W3docs

La balise HTML <dialog>

Découvrez la balise HTML <dialog> : show() vs showModal(), le motif form method="dialog", les événements close et cancel, et l'accessibilité.

La balise <dialog> est l'un des éléments HTML5. Elle crée une boîte de dialogue native — un panneau contextuel tel qu'un message de confirmation, une alerte ou un formulaire — avec lequel l'utilisateur interagit avant de continuer. La boîte de dialogue est masquée par défaut et s'affiche ou se cache via une petite API JavaScript.

Cette page couvre les deux façons d'ouvrir une boîte de dialogue (show() et showModal()), comment la fermer et lire son résultat, le motif <form method="dialog">, les événements close et cancel, l'accessibilité et le style du backdrop.

Pourquoi utiliser <dialog> natif plutôt qu'un modal <div> personnalisé ?

Avant <dialog>, les développeurs construisaient manuellement des modaux à partir d'un <div> accompagné d'un empilement de CSS et de JavaScript. L'élément natif effectue ce travail à votre place et de façon plus fiable :

  • Piégeage du focus intégré. Lorsqu'il est ouvert avec showModal(), le focus clavier (Tab / Shift+Tab) reste à l'intérieur de la boîte de dialogue. Un modal <div> doit piéger le focus manuellement, et une erreur à ce niveau est un bug d'accessibilité courant.
  • Empilement sur la couche supérieure. Un dialog modal s'affiche dans la couche supérieure du navigateur, de sorte qu'il peint toujours au-dessus du reste de la page, quel que soit le z-index. Fini les guerres de z-index.
  • Backdrop automatique. showModal() dessine un pseudo-élément ::backdrop derrière la boîte de dialogue qui bloque les clics sur la page en dessous — aucun élément de superposition supplémentaire n'est nécessaire.
  • Fermeture par Échap. Appuyer sur Esc ferme automatiquement un dialog modal (en déclenchant un événement cancel auquel vous pouvez réagir).
  • Sémantique réelle. L'élément porte un role="dialog" implicite, de sorte que les technologies d'assistance l'annoncent correctement sans ARIA supplémentaire.

Syntaxe

La balise <dialog> fonctionne en paires. Placez le contenu de la boîte de dialogue entre les balises ouvrante (<dialog>) et fermante (</dialog>). Vous l'ouvrez depuis un script avec l'une des deux méthodes de l'objet DOM de l'élément :

  • dialog.show() — ouvre une boîte de dialogue non modale.
  • dialog.showModal() — ouvre une boîte de dialogue modale.
  • dialog.close([returnValue]) — ferme la boîte de dialogue et enregistre optionnellement une valeur de retour.

L'attribut boolean open indique si la boîte de dialogue est actuellement affichée. En général, vous ne le définissez pas manuellement ; les méthodes ci-dessus le gèrent pour vous.

Boîtes de dialogue non modales : show()

show() ouvre la boîte de dialogue en place, sans bloquer la page. Le reste du document reste interactif, il n'y a pas de ::backdrop, le focus n'est pas piégé et Esc ne la ferme pas. C'est le bon choix pour les panneaux non critiques et dismissibles comme une petite boîte à outils, une note « nouveautés » ou un sélecteur en ligne.

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

Boîtes de dialogue modales : showModal()

showModal() ouvre la boîte de dialogue en tant que modal. Cela change le comportement de quatre façons importantes :

  1. L'interaction est bloquée. Tout ce qui se trouve en dehors de la boîte de dialogue devient inerte — les clics et les saisies clavier ne peuvent pas atteindre la page derrière elle.
  2. Un backdrop apparaît. Le navigateur affiche le pseudo-élément ::backdrop derrière la boîte de dialogue, que vous pouvez styliser.
  3. Le focus est piégé. La navigation par Tab cycle uniquement parmi les éléments focalisables à l'intérieur de la boîte de dialogue.
  4. Elle rejoint la couche supérieure. La boîte de dialogue s'affiche au-dessus de tout autre contenu, en ignorant le z-index. Appuyer sur Esc la ferme.
<!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>
Result

Le motif <form method="dialog">

Un <form> à l'intérieur d'un <dialog> peut utiliser method="dialog". Soumettre un tel formulaire ferme la boîte de dialogue sans envoyer de requête réseau, et la valeur du <button> de soumission cliqué est stockée dans la propriété DOM returnValue de la boîte de dialogue. Cela facilite la détection du bouton choisi par l'utilisateur.

<!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 est une propriété de l'élément DOM, pas un attribut HTML — vous la lisez ou la définissez depuis JavaScript. Vous pouvez également la définir directement lors de la fermeture dans le code : dialog.close("delete").

Les événements close et cancel

Un <dialog> déclenche deux événements que vous pouvez écouter :

ÉvénementQuand il se déclenche
closeChaque fois que la boîte de dialogue est fermée — par close(), en soumettant un formulaire method="dialog", ou par Esc. Lisez returnValue ici.
cancelLorsque l'utilisateur ferme un dialog modal avec la touche Esc. Se déclenche avant close. Appelez event.preventDefault() pour garder la boîte de dialogue ouverte.
<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>

Pour en savoir plus sur la connexion de ces écouteurs, consultez les événements JavaScript et le DOM HTML JavaScript.

Accessibilité

Un <dialog> possède un role="dialog" implicite, mais vous devez tout de même lui donner un nom accessible et gérer le focus :

  • Nommez la boîte de dialogue. Pointez aria-labelledby sur l'id du titre de la boîte de dialogue afin que les lecteurs d'écran annoncent son titre. Utilisez aria-describedby pour une description plus longue.
  • Focus à l'ouverture. showModal() déplace automatiquement le focus dans la boîte de dialogue — sur le premier élément focalisable, ou sur un élément que vous marquez avec l'attribut autofocus. Préférez placer autofocus sur un contrôle sûr (comme Annuler) plutôt que sur un contrôle destructeur.
  • Retour du focus à la fermeture. Lorsque la boîte de dialogue se ferme, renvoyez le focus au contrôle qui l'a ouverte afin que les utilisateurs clavier ne se retrouvent pas en haut de la page. Avec <dialog> natif, le navigateur fait cela pour vous ; pour des résultats optimaux, stockez et restaurez vous-même le déclencheur.
<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>

Consultez les considérations d'accessibilité du DOM pour en savoir plus sur la création de widgets interactifs accessibles.

Styliser la boîte de dialogue et son backdrop

Vous pouvez styliser la boîte de dialogue elle-même et, pour les dialogs modaux, la zone derrière elle avec le pseudo-élément ::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);
}

Attributs

AttributValeurDescription
openopenAttribut boolean indiquant que la boîte de dialogue est actuellement affichée. Généralement défini pour vous par show() / showModal().

La balise <dialog> prend également en charge les attributs globaux et les attributs d'événement.

Pratique

Pratique
Quelles affirmations concernant l'élément HTML <dialog> sont correctes ?
Quelles affirmations concernant l'élément HTML <dialog> sont correctes ?
Was this page helpful?