# Le futur élément HTML dialog natif face aux fenêtres modales JavaScript

> Un élément HTML standard gère désormais nativement une bonne partie de ce que nos scripts de fenêtre modale s'efforcent de reproduire depuis des années. Voici ce qu'il fait vraiment, et ce qu'il ne fait pas encore.

- Auteur : Clément Hadrot
- Publié le : 2023-02-08
- Mis à jour le : 2023-02-08
- Catégorie : Accessibilité
- URL : https://wpmoderne.dev.wordpress-developpement.fr/accessibilite/element-dialog-natif-face-modales-javascript/

## L’essentiel

- dialog gère nativement le piège de focus et la fermeture à Échap
- La méthode showModal() diffère fondamentalement de open
- Certains comportements avancés restent encore à la charge du développeur

Depuis des années, chaque nouvelle fenêtre modale d'un thème WordPress sur mesure repart du même chantier : piéger le focus à l'intérieur, gérer la fermeture avec la touche Échap, restaurer le focus sur l'élément déclencheur à la fermeture, empêcher le défilement de la page en arrière-plan. Un élément HTML standard, `<dialog>`, promet de prendre en charge nativement une bonne partie de ce travail. Ce billet fait le point sur ce que cet élément apporte réellement, et sur ce qu'il laisse encore à la charge du développeur.

Le support navigateur de `<dialog>` s'est nettement amélioré ces derniers mois, avec une prise en charge désormais correcte sur les versions récentes de Chrome, Firefox et Safari, ce qui rend son usage envisageable en production pour un site qui ne vise pas les navigateurs les plus anciens.

## Ce que fait l'élément dialog par défaut

L'élément `<dialog>` peut être affiché de deux façons distinctes, avec des comportements très différents. La méthode `show()` l'affiche comme un simple élément flottant, sans piéger le focus ni bloquer l'interaction avec le reste de la page. La méthode `showModal()`, en revanche, l'affiche en tant que véritable fenêtre modale : elle piège automatiquement le focus à l'intérieur de la boîte de dialogue, désactive l'interaction avec le reste du document via la pseudo-couche `::backdrop`, et ferme la boîte à l'appui de la touche Échap, sans qu'aucune ligne de JavaScript supplémentaire ne soit nécessaire pour ces trois comportements précis.

```
<dialog id="modale-newsletter">
  <h2>Inscription à la newsletter</h2>
  <p>Recevez nos articles chaque mois.</p>
  <button id="fermer">Fermer</button>
</dialog>

<script>
document.getElementById('bouton-ouvrir').addEventListener('click', function () {
  document.getElementById('modale-newsletter').showModal();
});
document.getElementById('fermer').addEventListener('click', function () {
  document.getElementById('modale-newsletter').close();
});
</script>
```

## Fonctionnement interne du piège de focus

> L'essentiel à retenir : dialog gère nativement le piège de focus et la fermeture à Échap ; La méthode showModal() diffère fondamentalement de open ; Certains comportements avancés restent encore à la charge du développeur

Contrairement à un piège de focus construit à la main en JavaScript, qui doit intercepter chaque pression sur Tab et calculer manuellement le premier et le dernier élément focusable de la boîte, le navigateur gère ce cycle directement au niveau du moteur de rendu. Le focus reste confiné aux éléments focusables présents à l'intérieur de la balise `<dialog>`, sans qu'aucun gestionnaire d'événement `keydown` ne soit requis pour ce comportement précis, ce qui élimine une source fréquente de bugs subtils dans les implémentations maison.

## Cas d'usage pertinents

- Fenêtres de confirmation avant suppression d'un contenu
- Formulaires courts d'inscription ou de connexion
- Affichage d'un message d'alerte bloquant nécessitant une action explicite
- Visionneuses d'image en plein écran depuis une galerie

## Les pièges qui restent à la charge du développeur

L'élément `<dialog>` ne gère pas tout automatiquement. Le focus initial, posé par défaut sur le premier élément focusable de la boîte, ne correspond pas toujours à l'élément le plus pertinent : il est souvent préférable de positionner le focus initial explicitement sur le titre de la modale avec `autofocus`, plutôt que sur le premier bouton venu. Le nom accessible de la boîte de dialogue n'est pas non plus automatique : il faut associer un titre via `aria-labelledby` pour qu'un lecteur d'écran annonce correctement l'objet de la fenêtre à l'ouverture.

```
<dialog id="modale-newsletter" aria-labelledby="titre-modale">
  <h2 id="titre-modale" tabindex="-1" autofocus>Inscription à la newsletter</h2>
  ...
</dialog>
```

Le style visuel du fond `::backdrop` hérite de valeurs par défaut assez ternes selon les navigateurs, et nécessite presque toujours une personnalisation CSS pour correspondre à une charte graphique. Enfin, l'animation d'ouverture et de fermeture, souvent attendue par les clients, demande un peu de CSS supplémentaire, l'élément ne proposant par défaut qu'une apparition immédiate sans transition.

## Comparaison rapide avec les solutions JavaScript existantes

| Comportement | dialog natif | Bibliothèque JS classique |
| --- | --- | --- |
| Piège de focus | Automatique avec showModal() | À implémenter |
| Fermeture à Échap | Automatique | À implémenter |
| Nom accessible | À poser manuellement | À poser manuellement |
| Poids ajouté au site | Aucun script tiers | Quelques kilo-octets par bibliothèque |

## Notre verdict

L'élément `<dialog>` ne remplace pas encore intégralement une bibliothèque JavaScript spécialisée dans les cas les plus complexes, comme des modales imbriquées ou des interactions très personnalisées. Mais pour la grande majorité des cas d'usage rencontrés dans un thème WordPress classique, il réduit fortement le code à écrire et surtout les erreurs d'accessibilité les plus fréquentes, celles liées au piège de focus mal implémenté. Nous suivrons de près l'évolution de son support navigateur avant de le généraliser sur nos futurs projets.
