Kodokon kodokon.com

HTML interactif moderne : dialog, details, popover, contenteditable

Remplacez vos bibliothèques d'UI par les primitives natives du HTML moderne : dialogues modaux, accordéons exclusifs, popovers et zones éditables.

10 min · 3 questions

Ouvrir cette leçon dans Kodokon

<dialog> résout nativement ce que des années de bibliothèques modales ont bricolé. showModal() projette l'élément dans le top layer - au-dessus de tout z-index -, rend le reste du document inerte (ni focus ni clic possibles) et expose le pseudo-élément ::backdrop. show(), lui, affiche un dialogue non modal, sans inertie ni backdrop. L'attribut récent closedby=any ajoute la fermeture par clic extérieur.

HTML
<dialog id="confirm-dlg">
  <form method="dialog">
    <p>Supprimer cet élément ?</p>
    <button value="cancel">Annuler</button>
    <button value="ok">Confirmer</button>
  </form>
</dialog>
Un formulaire method=dialog ferme le dialogue sans requête réseau.

Un <form method=dialog> ferme le dialogue sans soumission réseau : la value du bouton déclencheur devient dialog.returnValue, que l'événement close vous laisse lire. La touche Échap ferme un dialogue modal en émettant d'abord cancel, que vous pouvez annuler avec preventDefault() si une saisie est en cours.

JAVASCRIPT
const dlg = document.getElementById("confirm-dlg");
dlg.showModal();
dlg.addEventListener("close", () => {
  console.log(dlg.returnValue); // "ok" ou "cancel"
});
Récupération du choix de l'utilisateur à la fermeture.

L'API Popover couvre menus, infobulles riches et toasts sans JavaScript : posez popover sur l'élément et popovertarget sur un bouton, et le navigateur gère le top layer, le light dismiss (clic extérieur, Échap) et la fermeture mutuelle des popovers auto. Contrairement à showModal(), un popover ne rend pas la page inerte. Les événements beforetoggle et toggle permettent d'annuler ou d'observer chaque transition.

HTML
<button popovertarget="user-menu">Menu</button>
<div id="user-menu" popover>
  <button>Profil</button>
  <button>Déconnexion</button>
</div>
Un menu complet, sans une seule ligne de JavaScript.

<details> fournit un contenu dépliable accessible sans script, et un attribut name partagé crée un groupe exclusif : ouvrir l'un ferme les autres. L'événement toggle s'y déclenche à chaque changement d'état. Côté édition, contenteditable transforme n'importe quel élément en zone de saisie riche ; sa variante plaintext-only interdit tout balisage, et l'événement beforeinput remplace avantageusement l'API dépréciée document.execCommand.

HTML
<details name="faq" open>
  <summary>Délai de livraison ?</summary>
  <p>Sous 48 heures.</p>
</details>
<details name="faq">
  <summary>Politique de retour ?</summary>
  <p>Sous 30 jours.</p>
</details>
Le name partagé produit un accordéon exclusif natif.

Quiz de validation

Vérifiez que vous avez bien retenu les points clés de cette leçon.

  1. Qu'apporte showModal() par rapport à show() ?
    • Il bloque l'exécution JavaScript jusqu'à la fermeture du dialogue
    • Il place le dialogue dans le top layer, rend le reste du document inerte et active ::backdrop
    • Il empêche uniquement le défilement de la page
  2. Que produit un attribut name identique sur plusieurs <details> ?
    • Ils sont soumis ensemble dans le formulaire parent
    • Rien : name n'est pas un attribut valide sur details
    • Un accordéon exclusif : ouvrir l'un ferme automatiquement les autres
  3. Quelle différence de comportement entre un popover auto et un popover manual ?
    • auto bénéficie du light dismiss (clic extérieur, Échap) et ferme les autres popovers auto ; manual reste ouvert tant qu'il n'est pas fermé explicitement
    • manual ne peut pas être placé dans le top layer
    • auto s'ouvre tout seul au chargement de la page