« encore une bibliothèque de trois cents kilo-octets pour ouvrir une fenêtre modale » : c’est le constat qui a motivé ce test sur une boutique WooCommerce déjà surveillée de près sur son poids JavaScript. L’aperçu rapide produit, affiché depuis la grille catalogue, ne nécessitait en réalité qu’un comportement assez simple : ouvrir une fenêtre superposée, piéger le focus clavier à l’intérieur, et la fermer proprement.
La balise HTML <dialog>, avec sa méthode showModal(), couvre exactement ce périmètre nativement, sans bibliothèque tierce, tout en gérant elle-même plusieurs comportements d’accessibilité qu’il fallait auparavant coder à la main.
Structurer l’aperçu produit avec dialog
La structure de base reste minimale : une balise <dialog> par produit, ou une seule balise réutilisée et remplie dynamiquement selon le produit survolé. Ce projet a retenu la seconde option, plus légère en mémoire pour un catalogue de plusieurs centaines de références.
<dialog id="apercu-produit">
<h2 id="apercu-titre"></h2>
<p id="apercu-prix"></p>
<button id="apercu-fermer" type="button">Fermer</button>
</dialog>
Ouvrir la fenêtre avec showModal()

La méthode showModal(), appelée en JavaScript natif, ouvre la balise en mode modal : elle place automatiquement un fond assombri généré par le navigateur via le pseudo-élément ::backdrop, et déplace le focus clavier à l’intérieur de la fenêtre, sans code supplémentaire pour piéger la tabulation.
const dialogueApercu = document.getElementById( 'apercu-produit' );
const boutonFermer = document.getElementById( 'apercu-fermer' );
document.querySelectorAll( '.bouton-apercu-rapide' ).forEach( ( bouton ) => {
bouton.addEventListener( 'click', () => {
document.getElementById( 'apercu-titre' ).textContent = bouton.dataset.titre;
document.getElementById( 'apercu-prix' ).textContent = bouton.dataset.prix;
dialogueApercu.showModal();
} );
} );
boutonFermer.addEventListener( 'click', () => {
dialogueApercu.close();
} );
La fermeture au clavier via la touche Échap fonctionne également sans aucune ligne de code additionnelle : le navigateur l’implémente nativement dès lors que la fenêtre a été ouverte via showModal(), contrairement à une simple boîte construite avec une div positionnée en superposition.
Ce que la balise gère seule, et ce qui reste à la charge du développeur
- Piégeage du focus clavier à l’intérieur de la fenêtre : géré nativement.
- Fermeture à la touche Échap : gérée nativement.
- Restitution du focus à l’élément déclencheur après fermeture : à vérifier selon le navigateur, un ajout manuel via
focus()sur le bouton d’origine reste une sécurité raisonnable. - Étiquetage accessible du titre de la fenêtre pour les lecteurs d’écran : à la charge du développeur, via un attribut
aria-labelledbypointant vers le titre affiché.
Vérifier le support navigateur avant de généraliser
La balise <dialog> bénéficie d’un support large dans les navigateurs modernes depuis 2022, mais un projet qui doit encore composer avec un parc de navigateurs plus ancien gagne à vérifier ce support avant de retirer toute solution de repli. Une détection simple permet de basculer vers un comportement dégradé raisonnable :
if ( typeof HTMLDialogElement === 'function' ) {
dialogueApercu.showModal();
} else {
dialogueApercu.setAttribute( 'open', '' );
}
Ce repli n’offre plus le piégeage de focus ni le fond assombri automatique, mais il évite au moins que la fenêtre ne reste invisible sur un navigateur qui ne connaît pas encore la balise.
Un style minimal pour le fond assombri
dialog::backdrop {
background-color: rgba(0, 0, 0, 0.5);
}
dialog {
border: none;
border-radius: 0.5rem;
padding: 1.5rem;
max-width: 32rem;
}
Avant d’installer une bibliothèque de modale sur un projet WooCommerce, je vérifie systématiquement si la balise dialog native ne couvre pas déjà le besoin : sur un aperçu rapide produit sans contenu chargé dynamiquement en arrière-plan, c’est presque toujours le cas.
Ce que ce composant ne couvre pas
Cette implémentation reste volontairement limitée à un contenu déjà présent dans la page ou rempli via des attributs simples portés par le bouton déclencheur. Un aperçu produit dont le contenu proviendrait d’un chargement asynchrone après ouverture demande une gestion d’état supplémentaire, avec un indicateur de chargement et une gestion des erreurs réseau, non traitée ici.
Notre verdict
Pour un aperçu rapide produit au contenu simple, la balise <dialog> remplace avantageusement une bibliothèque de modale tierce : elle réduit le poids JavaScript du site, tout en gérant nativement plusieurs aspects d’accessibilité auparavant sources d’erreurs fréquentes dans les implémentations maison.