Leçon 5 / 20

Créer une fenêtre de dialogue avec dialog

25 min HTML5 — accessibilité, composants natifs et métadonnées Gratuit

Objectif : Ouvrir et fermer une fenêtre de dialogue native pour l’inscription à la newsletter.

Une inscription à la newsletter doit pouvoir s’effectuer sans quitter la page, tout en restant utilisable au clavier et compréhensible avec un lecteur d’écran. Une fenêtre dessinée avec une simple div ne fournit pas, à elle seule, le comportement d’une véritable fenêtre modale. Vous allez utiliser dialog et conserver le parcours cohérent déjà établi dans les leçons précédentes.

Une fenêtre de dialogue native

L’élément HTML dialog représente une fenêtre de dialogue. Quand vous l’ouvrez avec showModal(), le navigateur la place au premier plan et rend le reste de la page inactif pour les interactions. La méthode close() la ferme ; la touche Échap ferme également une fenêtre modale ouverte ainsi. Ces comportements intégrés évitent de recréer manuellement une partie des interactions clavier.

Dans le projet fil rouge, le bouton de l’en-tête déclenche l’ouverture de la fenêtre identifiée par newsletter. L’attribut command="show-modal" demande au navigateur d’ouvrir cette fenêtre en mode modal, et commandfor désigne l’identifiant de la cible. Dans le formulaire, le bouton de fermeture utilise la commande close sur la même cible. Ces commandes déclaratives sont prises en charge par les navigateurs qui implémentent cette fonctionnalité HTML ; vérifiez leur prise en charge dans les navigateurs visés par votre site.

La page à cet état

Conservez le contenu et les identifiants du projet. Le titre de la fenêtre est relié à celle-ci par aria-labelledby, afin que son intitulé soit annoncé. La navigation, le lien d’évitement, le contenu de l’événement et le formulaire restent dans leur ordre source ; aucun script n’est nécessaire pour cette version de la page.

index.htmlHTML
<!doctype html>
<html lang="fr">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Association culturelle — événements</title>
  <meta name="description" content="Découvrez les événements et les activités de notre association culturelle.">
  <link rel="canonical" href="https://exemple.fr/evenements">
  <meta property="og:type" content="website">
  <meta property="og:locale" content="fr_FR">
  <meta property="og:title" content="Association culturelle — événements">
  <meta property="og:description" content="Découvrez les événements et les activités de notre association culturelle.">
  <meta property="og:url" content="https://exemple.fr/evenements">
  <meta property="og:image" content="https://exemple.fr/assets/affiche-evenement.jpg">
  <meta name="twitter:card" content="summary_large_image">
  <link rel="preload" as="image" href="assets/affiche-evenement.jpg">
  <link rel="stylesheet" href="style.css">
  <script type="application/ld+json">
  {
    "@context": "https://schema.org",
    "@type": "Event",
    "name": "Soirée des cultures",
    "startDate": "2026-06-20T18:00:00+02:00",
    "endDate": "2026-06-20T22:00:00+02:00",
    "eventStatus": "https://schema.org/EventScheduled",
    "eventAttendanceMode": "https://schema.org/OfflineEventAttendanceMode",
    "location": {
      "@type": "Place",
      "name": "Maison des associations",
      "address": {
        "@type": "PostalAddress",
        "streetAddress": "10 rue des Arts",
        "addressLocality": "Lyon",
        "postalCode": "69001",
        "addressCountry": "FR"
      }
    },
    "organizer": {
      "@type": "Organization",
      "name": "Association culturelle",
      "url": "https://exemple.fr/"
    },
    "image": "https://exemple.fr/assets/affiche-evenement.jpg",
    "description": "Une soirée de rencontres, de musique et de découvertes culturelles."
  }
  </script>
</head>
<body class="culture-page">
  <a class="culture-lien-evitement" href="#contenu">Aller au contenu principal</a>
  <header class="culture-entete">
    <a href="/" aria-label="Association culturelle, accueil">Association culturelle</a>
    <nav class="culture-navigation" aria-label="Navigation principale">
      <ul>
        <li><a href="#evenements">Événements</a></li>
        <li><a href="#association">L’association</a></li>
      </ul>
    </nav>
    <button class="culture-bouton" type="button" command="show-modal" commandfor="newsletter">S’inscrire à la newsletter</button>
  </header>
  <main class="culture-contenu" id="contenu">
    <h1>Nos événements</h1>
    <section class="culture-evenements" id="evenements" aria-labelledby="titre-evenements">
      <h2 id="titre-evenements">À venir</h2>
      <article class="culture-evenement">
        <h3>Soirée des cultures</h3>
        <img class="culture-image" src="assets/affiche-evenement.jpg" alt="Affiche illustrée de la soirée des cultures" width="1200" height="800" fetchpriority="high">
        <p><time datetime="2026-06-20T18:00:00+02:00">20 juin 2026, à 18 h</time></p>
        <p>Une soirée de rencontres, de musique et de découvertes culturelles.</p>
        <details class="culture-details">
          <summary>Informations pratiques</summary>
          <p>Rendez-vous à la Maison des associations, 10 rue des Arts, Lyon.</p>
        </details>
      </article>
    </section>
    <section id="association" aria-labelledby="titre-association">
      <h2 id="titre-association">Notre association</h2>
      <p>Nous créons des occasions de partager et de découvrir les cultures.</p>
    </section>
  </main>
  <dialog class="culture-dialogue" id="newsletter" aria-labelledby="titre-newsletter">
    <h2 id="titre-newsletter">Recevoir la newsletter</h2>
    <form action="/inscription" method="post">
      <label for="courriel">Adresse courriel</label>
      <input id="courriel" name="courriel" type="email" autocomplete="email" required>
      <button class="culture-bouton" type="submit">S’inscrire</button>
      <button class="culture-bouton" type="button" command="close" commandfor="newsletter">Fermer</button>
    </form>
  </dialog>
  <footer class="culture-pied">
    <p>Association culturelle — <a href="/mentions-legales">Mentions légales</a></p>
  </footer>
</body>
</html>
Aperçu du rendu
Chargement de l'aperçu…

Ajoutez les règles suivantes dans style.css. Elles définissent les styles de base des classes déjà utilisées par la page et conservent le focus clavier visible. Les valeurs de couleur, d’espacement, de largeur, de police et de rayon proviennent des variables CSS du contrat ; les mots-clés tels que block et flex indiquent le comportement de mise en page.

style.cssCSS
:root {
  --culture-couleur-texte: #202124;
  --culture-couleur-fond: #ffffff;
  --culture-couleur-accent: #713b8f;
  --culture-couleur-focus: #ffbf47;
  --culture-espace-1: 0.5rem;
  --culture-espace-2: 1rem;
  --culture-espace-3: 2rem;
  --culture-rayon: 0.5rem;
  --culture-police: system-ui, sans-serif;
  --culture-largeur: 70rem;
}

.culture-page {
  margin: 0;
  color: var(--culture-couleur-texte);
  background: var(--culture-couleur-fond);
  font-family: var(--culture-police);
}

.culture-lien-evitement {
  position: absolute;
  inset-block-start: var(--culture-espace-2);
  inset-inline-start: var(--culture-espace-2);
  z-index: 1;
  padding: var(--culture-espace-1);
  color: var(--culture-couleur-texte);
  background: var(--culture-couleur-fond);
  transform: translateY(-200%);
}

.culture-lien-evitement:focus {
  transform: translateY(0);
}

.culture-entete,
.culture-contenu,
.culture-pied {
  width: min(100% - var(--culture-espace-3), var(--culture-largeur));
  margin-inline: auto;
}

.culture-entete {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--culture-espace-2);
  padding-block: var(--culture-espace-2);
}

.culture-navigation ul {
  display: flex;
  flex-wrap: wrap;
  gap: var(--culture-espace-2);
  padding: 0;
  list-style: none;
}

.culture-bouton {
  padding: var(--culture-espace-1) var(--culture-espace-2);
  border: 0;
  border-radius: var(--culture-rayon);
  color: var(--culture-couleur-fond);
  background: var(--culture-couleur-accent);
  font: inherit;
  cursor: pointer;
}

.culture-contenu {
  padding-block: var(--culture-espace-2) var(--culture-espace-3);
}

.culture-evenements,
.culture-evenement {
  margin-block: var(--culture-espace-3);
}

.culture-evenement {
  max-width: var(--culture-largeur);
}

.culture-image {
  display: block;
  width: 100%;
  height: auto;
}

.culture-details {
  margin-block: var(--culture-espace-2);
}

.culture-dialogue {
  max-width: var(--culture-largeur);
  padding: var(--culture-espace-3);
  border: 0;
  border-radius: var(--culture-rayon);
  color: var(--culture-couleur-texte);
  background: var(--culture-couleur-fond);
}

.culture-dialogue::backdrop {
  background: var(--culture-couleur-texte);
  opacity: 0.75;
}

.culture-pied {
  padding-block: var(--culture-espace-2);
}

:focus-visible {
  outline: 0.2rem solid var(--culture-couleur-focus);
  outline-offset: 0.2rem;
}
Aperçu du rendu
Chargement de l'aperçu…

Aperçu appliqué au document HTML de cette leçon : la règle CSS est injectée dans la page pour voir son effet réel.

Vérifier le comportement

Chargez la page dans un navigateur qui prend en charge ces commandes. Activez le bouton de newsletter au clavier ou à la souris : la fenêtre doit apparaître au premier plan et le reste du document ne doit plus être interactif. Le bouton « Fermer » et la touche Échap doivent refermer la fenêtre ; le formulaire conserve son envoi vers /inscription et la validation native de l’adresse courriel requise.

La classe culture-dialogue ne remplace pas la sémantique de dialog : elle ne sert qu’à appliquer la présentation. De même, le titre associé nomme la fenêtre et les boutons restent de véritables contrôles natifs. Pour contrôler le parcours au clavier et le focus visible, appuyez-vous sur les vérifications déjà vues dans la leçon consacrée au lien d’évitement et au focus.

À retenir

  • dialog fournit une fenêtre de dialogue native.
  • showModal() ouvre la fenêtre en mode modal ; close() la ferme.
  • Les commandes déclaratives show-modal et close relient ici les boutons à la fenêtre.
  • La touche Échap ferme une fenêtre modale ; testez aussi le support des commandes dans vos navigateurs cibles.
  • Les styles s’ajoutent à style.css en réutilisant les variables et classes du projet.

Dans la leçon suivante, vous examinerez plus précisément le focus initial dans la fenêtre et sa restitution à l’élément déclencheur.

Envie d'aller plus loin ?

Les cours Enovatic sont gratuits et le resteront. Si vous cherchez un accompagnement encadré, nos formations professionnelles sont animées par les mêmes formateurs.