Avancé15 min de lecture

L'élément Dialog

Apprends à créer des dialogues modaux et non-modaux natifs en utilisant l'élément HTML dialog, avec piégeage de focus intégré, stylisation du backdrop et intégration de formulaires.

L'élément <dialog>

L'élément <dialog> représente une boîte de dialogue ou une fenêtre popup. Il est masqué par défaut et peut être affiché dans deux modes :

  1. Modal (showModal()) — Recouvre toute la page avec un backdrop, piège le focus à l'intérieur du dialogue et bloque l'interaction avec le reste de la page. Appuie sur Échap pour fermer.
  2. Non-modal (show()) — S'ouvre sans backdrop. L'utilisateur peut toujours interagir avec le reste de la page.
html
<dialog id="myDialog">
  <h2>Dialog Title</h2>
  <p>This is a native HTML dialog.</p>
  <button onclick="this.closest('dialog').close()">Close</button>
</dialog>

<button onclick="document.getElementById('myDialog').showModal()">
  Open Modal
</button>

Le dialogue est un élément HTML standard — pas besoin de bibliothèque JavaScript pour les modales !

Ouverture et fermeture

Ouverture

  • dialog.showModal() — Ouvre comme modal avec backdrop et piégeage de focus.
  • dialog.show() — Ouvre comme dialogue non-modal.
  • L'attribut open — L'ajouter directement rend le dialogue visible (non-modal), mais showModal() est préférable pour les modales.

Fermeture

  • dialog.close() — Ferme le dialogue.
  • dialog.close('result') — Ferme et définit dialog.returnValue à la chaîne de caractères passée.
  • Appuyer sur Échap ferme un dialogue modal.
  • Un formulaire avec method="dialog" à l'intérieur du dialogue le ferme lors de la soumission.

L'événement close

js
dialog.addEventListener('close', () => {
  console.log('Return value:', dialog.returnValue);
});

Form method="dialog"

Quand un formulaire à l'intérieur d'un dialogue a method="dialog", le soumettre ferme le dialogue. La value du bouton de soumission devient le returnValue du dialogue :

html
<dialog id="confirm">
  <form method="dialog">
    <p>Are you sure?</p>
    <button value="yes">Yes</button>
    <button value="no">No</button>
  </form>
</dialog>

Stylisation avec ::backdrop

Les dialogues modaux créent un pseudo-élément backdrop qui recouvre la page derrière le dialogue. Tu peux le styliser avec le pseudo-élément ::backdrop :

css
dialog::backdrop {
  background: rgba(0, 0, 0, 0.6);
  backdrop-filter: blur(4px);
}

Le dialogue lui-même peut être stylisé comme n'importe quel élément :

css
dialog {
  border: none;
  border-radius: 12px;
  padding: 2rem;
  max-width: 500px;
  box-shadow: 0 10px 40px rgba(0, 0, 0, 0.3);
}

Les navigateurs modernes gèrent automatiquement le piégeage de focus pour les dialogues modaux — le focus ne peut pas quitter le dialogue tant qu'il est ouvert, et le focus revient à l'élément déclencheur quand il se ferme.

Accessibilité

L'élément <dialog> a une excellente accessibilité intégrée :

  • role="dialog" est implicite — les lecteurs d'écran l'annoncent comme un dialogue.
  • Ajoute aria-label ou aria-labelledby pour fournir un nom accessible :
html
<dialog aria-labelledby="dialog-title">
  <h2 id="dialog-title">Confirm Deletion</h2>
  <p>This action cannot be undone.</p>
</dialog>
  • La gestion du focus est automatique pour showModal() — le focus se déplace dans le dialogue et est piégé.
  • La touche Échap ferme le dialogue — c'est le comportement attendu.
  • Pour les dialogues non-modaux (show()), tu devras peut-être gérer le focus manuellement.

Assure-toi toujours que le dialogue a un moyen clair d'être fermé (un bouton fermer, un bouton annuler ou une soumission de formulaire).

Exemple complet de dialogue

html
<!-- Trigger button -->
<button id="openBtn">Delete Account</button>

<!-- Modal dialog -->
<dialog id="confirmDialog" aria-labelledby="dlg-title">
  <h2 id="dlg-title">Confirm Deletion</h2>
  <p>Are you sure you want to delete your account? This cannot be undone.</p>

  <form method="dialog">
    <button value="cancel">Cancel</button>
    <button value="confirm">Delete</button>
  </form>
</dialog>

<script>
  const dialog = document.getElementById('confirmDialog');
  const openBtn = document.getElementById('openBtn');

  openBtn.addEventListener('click', () => dialog.showModal());

  dialog.addEventListener('close', () => {
    if (dialog.returnValue === 'confirm') {
      console.log('Account deleted');
    }
  });
</script>

Quelle est la différence entre dialog.show() et dialog.showModal() ?

Prêt à pratiquer ?

Crée ton compte gratuit pour accéder à l'éditeur de code interactif, lancer les défis et suivre ta progression.