Intégration web angularforall.com

- HTML details et summary : accordéons natifs sans JS

Html-Details Html-Summary Accordeon-Html Faq-Html Html5-Natif Accessibilite Seo-Technique Schema-Org Integration-Web Front-End No-Javascript Progressive-Enhancement Ui-Natif Menu-Mobile
HTML details et summary : accordéons natifs sans JS

Créez des accordéons et FAQ accessibles avec details et summary : attribut name pour exclusivité, animations CSS, SEO et 8 patterns réels production.

Pourquoi details et summary ?

Pendant des années, créer un accordéon nécessitait Bootstrap, jQuery, Alpine ou React, des classes .collapse, des attributs data-bs-toggle, des listeners JavaScript et des managers d'état. Tout ça pour un simple bouton qui montre ou cache du contenu.

Les balises HTML <details> et <summary> remplacent ce stack entier par 4 lignes de HTML pur. Pas de JS, pas de framework, accessibilité gratuite, SEO impeccable, performance maximale. En 2026, ces balises sont supportées par 100% des navigateurs modernes et ont gagné de nouvelles capacités majeures (attribut name pour accordéon exclusif, animations CSS natives).

Comparaison rapide

<!-- ❌ Bootstrap 5 — 8+ lignes, 1 dépendance JS -->
<div class="accordion" id="myAccordion">
  <div class="accordion-item">
    <h2 class="accordion-header">
      <button class="accordion-button" type="button"
              data-bs-toggle="collapse" data-bs-target="#item1">
        Question 1
      </button>
    </h2>
    <div id="item1" class="accordion-collapse collapse">
      <div class="accordion-body">Réponse 1</div>
    </div>
  </div>
</div>

<!-- ✅ HTML natif — 4 lignes, 0 JS -->
<details>
  <summary>Question 1</summary>
  <p>Réponse 1</p>
</details>

Syntaxe et anatomie

Un widget <details> contient toujours un <summary> en premier enfant (l'en-tête cliquable), suivi d'un contenu libre (paragraphes, listes, tableaux, vidéos, autres composants).

Structure de base

<details>
  <summary>Cliquez pour développer</summary>
  <p>Contenu masqué par défaut. Visible après clic sur summary.</p>
  <ul>
    <li>Liste autorisée</li>
    <li>Tableaux, images, vidéos aussi</li>
  </ul>
</details>

Attributs disponibles

Attribut Description Exemple
open Ouvre le widget par défaut <details open>
name Crée un groupe exclusif (radio-like) <details name="faq">

Événement toggle

Lorsqu'un <details> s'ouvre ou se ferme, il déclenche l'événement toggle. Utile pour analytics, lazy-loading de contenu, ou synchronisation d'état.

<details id="terms">
  <summary>Conditions générales d'utilisation</summary>
  <p>Texte des CGU…</p>
</details>

<script>
  document.getElementById('terms').addEventListener('toggle', (e) => {
    if (e.target.open) {
      console.log('CGU consultées par l\'utilisateur');
      // Tracker analytics, débloquer le bouton « accepter », etc.
    }
  });
</script>
Le summary est toujours focusable au clavier. Tab pour y accéder, Espace ou Entrée pour ouvrir/fermer. Le navigateur gère tout.

Accordéon exclusif avec name

Depuis fin 2023 (Chrome 120, Safari 17.2, Firefox 117), l'attribut name permet de regrouper plusieurs <details> en accordéon exclusif : ouvrir l'un ferme automatiquement les autres du même groupe. C'est le comportement « FAQ » classique, désormais natif.

Exemple FAQ exclusive

<details name="faq" open>
  <summary>Quels sont les délais de livraison ?</summary>
  <p>Livraison standard sous 3 à 5 jours ouvrés en France métropolitaine.</p>
</details>

<details name="faq">
  <summary>Comment retourner un article ?</summary>
  <p>Vous disposez de 30 jours pour retourner votre commande.</p>
</details>

<details name="faq">
  <summary>Acceptez-vous les paiements en plusieurs fois ?</summary>
  <p>Oui, paiement en 3x ou 4x sans frais via Klarna ou Alma.</p>
</details>

Plusieurs groupes indépendants sur la même page

<!-- Groupe FAQ Livraison -->
<details name="livraison">
  <summary>Délais</summary>
  <p>…</p>
</details>
<details name="livraison">
  <summary>Suivi</summary>
  <p>…</p>
</details>

<!-- Groupe FAQ Paiement (indépendant) -->
<details name="paiement">
  <summary>Modes acceptés</summary>
  <p>…</p>
</details>
<details name="paiement">
  <summary>Sécurité</summary>
  <p>…</p>
</details>
Avant 2023 : Le comportement exclusif demandait du JavaScript pour fermer manuellement les autres details au moment de l'événement toggle. L'attribut name rend ce code obsolète.

Styling moderne avec CSS

Par défaut, summary affiche un petit triangle (▸) qui pivote à l'ouverture. Vous pouvez le personnaliser entièrement avec ::marker, ::before/::after et le sélecteur [open].

Reset minimal

/* Supprime le triangle natif */
summary {
  list-style: none;
  cursor: pointer;
}
summary::-webkit-details-marker { display: none; } /* Safari */

Personnaliser le marqueur avec ::marker

summary::marker {
  content: '▸ ';
  color: #0d6efd;
  font-size: 1.2em;
}

details[open] summary::marker {
  content: '▾ ';
}

Icône custom avec ::after — chevron Bootstrap

details {
  border: 1px solid #dee2e6;
  border-radius: 0.5rem;
  margin-bottom: 0.5rem;
  background: #fff;
  overflow: hidden;
}

summary {
  list-style: none;
  cursor: pointer;
  padding: 1rem 1.25rem;
  font-weight: 600;
  display: flex;
  justify-content: space-between;
  align-items: center;
  transition: background 0.2s ease;
}

summary:hover { background: #f8f9fa; }

summary::after {
  content: '+';
  font-size: 1.5rem;
  font-weight: 300;
  transition: transform 0.3s ease;
}

details[open] summary {
  background: #e7f1ff;
  color: #084298;
  border-bottom: 1px solid #dee2e6;
}

details[open] summary::after {
  transform: rotate(45deg); /* + devient × */
}

details > *:not(summary) {
  padding: 1rem 1.25rem;
}

Style par état avec :has()

/* Container highlight quand un details est ouvert */
.faq-section:has(details[open]) {
  background: #fff8e7;
}

/* Style spécial pour le premier details ouvert */
details[open]:first-of-type {
  box-shadow: 0 4px 12px rgba(13, 110, 253, 0.15);
}

Animations natives

Animer l'ouverture d'un <details> a longtemps été le talon d'Achille de cette balise : la transition height: auto n'était pas animable. Trois solutions modernes existent en 2026.

Solution 1 : interpolate-size (Chrome 129+)

:root {
  interpolate-size: allow-keywords;
}

details > *:not(summary) {
  height: 0;
  overflow: hidden;
  transition: height 0.3s ease;
}

details[open] > *:not(summary) {
  height: auto; /* maintenant animable */
}

Solution 2 : ::details-content (Chrome 131+)

details::details-content {
  opacity: 0;
  height: 0;
  overflow: hidden;
  transition: height 0.3s ease, opacity 0.3s ease;
  transition-behavior: allow-discrete;
}

details[open]::details-content {
  opacity: 1;
  height: auto;
}

Solution 3 : grid-template-rows (compatible large)

details {
  display: grid;
  grid-template-rows: auto 0fr;
  transition: grid-template-rows 0.3s ease;
}

details[open] {
  grid-template-rows: auto 1fr;
}

details > *:not(summary) {
  overflow: hidden;
}

Animation rotation du chevron

summary .chevron {
  display: inline-block;
  transition: transform 0.3s ease;
}

details[open] summary .chevron {
  transform: rotate(180deg);
}
<details>
  <summary>
    Plus de détails
    <span class="chevron">▼</span>
  </summary>
  <p>Contenu</p>
</details>
prefers-reduced-motion doit être respecté. Englobez vos transitions dans une media query : @media (prefers-reduced-motion: no-preference) { ... }.

Accessibilité ARIA

<details> et <summary> apportent l'accessibilité gratuitement : focus clavier, rôle group implicite sur details, état aria-expanded géré par le navigateur, annonce vocale par les lecteurs d'écran (NVDA, JAWS, VoiceOver).

Améliorer le contexte avec ARIA

<section aria-labelledby="faq-title">
  <h2 id="faq-title">Questions fréquentes</h2>

  <details name="faq">
    <summary>Comment créer un compte ?</summary>
    <p>Cliquez sur « Inscription » en haut à droite…</p>
  </details>

  <details name="faq">
    <summary>Comment réinitialiser mon mot de passe ?</summary>
    <p>Sur la page de connexion, cliquez sur « Mot de passe oublié »…</p>
  </details>
</section>

Indicateur de focus visible

summary:focus-visible {
  outline: 3px solid #0d6efd;
  outline-offset: 2px;
  border-radius: 0.25rem;
}

Test au lecteur d'écran

Annonce vocale standard :
  • NVDA : « Question, bouton, réduit » → après clic → « Question, bouton, développé »
  • VoiceOver : « Bouton de divulgation, fermé » → « Bouton de divulgation, ouvert »
  • Focus clavier : Tab arrive sur summary, Espace ou Entrée bascule l'état

FAQ, SEO et Schema.org

Google et Bing indexent intégralement le contenu replié de <details> depuis 2020. Combinez avec un balisage Schema.org FAQPage pour obtenir des rich snippets dans les résultats de recherche.

FAQ avec Schema.org JSON-LD

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "FAQPage",
  "mainEntity": [
    {
      "@type": "Question",
      "name": "Quels sont les délais de livraison ?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "Livraison standard sous 3 à 5 jours ouvrés en France métropolitaine."
      }
    },
    {
      "@type": "Question",
      "name": "Comment retourner un article ?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "Vous disposez de 30 jours pour retourner votre commande."
      }
    }
  ]
}
</script>

<section>
  <h2>FAQ Livraison</h2>
  <details name="faq-livraison">
    <summary>Quels sont les délais de livraison ?</summary>
    <p>Livraison standard sous 3 à 5 jours ouvrés en France métropolitaine.</p>
  </details>
  <details name="faq-livraison">
    <summary>Comment retourner un article ?</summary>
    <p>Vous disposez de 30 jours pour retourner votre commande.</p>
  </details>
</section>

Microdata inline (alternative)

<div itemscope itemtype="https://schema.org/FAQPage">
  <details itemprop="mainEntity" itemscope itemtype="https://schema.org/Question">
    <summary itemprop="name">Quels sont les délais de livraison ?</summary>
    <div itemprop="acceptedAnswer" itemscope itemtype="https://schema.org/Answer">
      <div itemprop="text">Livraison sous 3 à 5 jours ouvrés.</div>
    </div>
  </details>
</div>
Vérification : Testez votre balisage avec l'outil de validation Schema.org et la console Search Central de Google. Les rich snippets FAQ apparaissent généralement sous 1 à 2 semaines après indexation.

8 patterns réels

1. Notice cookies repliable

<details class="alert alert-info">
  <summary>Pourquoi nous utilisons des cookies</summary>
  <p>Les cookies nous aident à mesurer l'audience et personnaliser votre expérience.</p>
</details>

2. Métadonnées d'un article

<details>
  <summary>Métadonnées de cet article</summary>
  <ul>
    <li>Auteur : Saïd Mezgani</li>
    <li>Publié le : 7 mai 2026</li>
    <li>Temps de lecture : 8 min</li>
  </ul>
</details>

3. Code source replié

<details>
  <summary>Voir le code complet</summary>
  <pre><code>function hello() {
  console.log('Hello world');
}</code></pre>
</details>

4. Filtre de recherche avancée

<details>
  <summary>Filtres avancés</summary>
  <div class="row g-2">
    <div class="col-md-4">
      <label>Prix min <input type="number" class="form-control"></label>
    </div>
    <div class="col-md-4">
      <label>Prix max <input type="number" class="form-control"></label>
    </div>
    <div class="col-md-4">
      <label>Catégorie <select class="form-select">...</select></label>
    </div>
  </div>
</details>

5. Spoiler tag pour blog

<details class="spoiler">
  <summary>⚠️ Spoiler — cliquez pour révéler</summary>
  <p>Le héros meurt à la fin du chapitre 12.</p>
</details>

6. Menu mobile sans JS

<details class="mobile-menu d-md-none">
  <summary>☰ Menu</summary>
  <nav>
    <a href="/">Accueil</a>
    <a href="/blog">Blog</a>
    <a href="/contact">Contact</a>
  </nav>
</details>

7. Section help contextuelle

<label for="iban">
  IBAN
  <details class="d-inline help-tip">
    <summary>?</summary>
    <p class="small text-muted">Format : 27 caractères, ex. FR76 1234…</p>
  </details>
</label>
<input id="iban" type="text" class="form-control">

8. Liste imbriquée pour documentation

<details name="docs" open>
  <summary>Installation</summary>
  <details name="docs-install">
    <summary>Sur Linux</summary>
    <pre><code>apt install nodejs</code></pre>
  </details>
  <details name="docs-install">
    <summary>Sur macOS</summary>
    <pre><code>brew install node</code></pre>
  </details>
</details>
<details name="docs">
  <summary>Configuration</summary>
  <p>…</p>
</details>

Conclusion

<details> et <summary> sont parmi les balises HTML les plus sous-utilisées. Elles remplacent des centaines de lignes de JavaScript par 4 lignes de HTML, gèrent l'accessibilité automatiquement, indexent parfaitement le contenu pour le SEO et bénéficient en 2026 de nouveautés majeures : attribut name pour accordéons exclusifs, animations natives via ::details-content et interpolate-size.

Adoptez-les dès maintenant pour vos FAQ, vos sections optionnelles, vos menus mobiles, vos help-tips, vos spoilers blog. Combinez avec Schema.org FAQPage pour gagner des rich snippets Google. Vous éliminez Bootstrap accordion, jQuery slideToggle, et un pan entier de votre dépendance JavaScript.

Récapitulatif :
  • <details> + <summary> = accordéon natif sans JS
  • open ouvre par défaut, name crée un groupe exclusif
  • Événement toggle pour analytics ou lazy-load
  • Personnaliser avec ::marker ou ::after
  • Animer avec ::details-content ou interpolate-size
  • Accessibilité gratuite (focus, ARIA, lecteurs d'écran)
  • Indexé par Google même replié — combiner avec FAQPage Schema.org
  • Cas réels : FAQ, menus mobile, help-tips, spoilers, métadonnées

Partager