Détails et résumé

Découvrez comment fonctionnent les éléments "details" et "summary", et où les utiliser.

Une flèche d'expansion, parfois appelée widget de divulgation, est un contrôle d'interface utilisateur qui masque et affiche du contenu. Si vous lisez cet article sur web.dev et que votre fenêtre d'affichage a une largeur inférieure à 106 ems, le sommaire de cette section s'affiche lorsque vous cliquez sur "Sur cette page". Si vous ne le voyez pas, réduisez la taille de la fenêtre du navigateur pour afficher la table des matières de cette page sous forme de flèche d'expansion.

L'interface utilisateur graphique accordéon est une série de widgets de divulgation empilés verticalement. Un cas d'utilisation courant de l'accordéon est une page de questions fréquentes. Dans ce cas, une FAQ en accordéon contient une liste de questions visibles. Lorsque l'utilisateur clique sur une question, la réponse s'affiche.

jQuery inclut un modèle d'interface utilisateur en accordéon depuis au moins 2009. La solution d'accordéon d'origine sans JavaScript consistait à faire de chaque question fréquente un <label> suivi de la coche qu'elle avait étiquetée, puis à afficher la réponse <div> lorsque la coche était cochée. Le code CSS ressemblait à ceci :

#FAQ [type="checkbox"] + div.answer {
  /* all the answer styles */
  display: none;
}
#FAQ [type="checkbox"]:checked + div.answer {
  display: block;
}

Pourquoi l'historique ? Les widgets de divulgation, tels que les accordéons, sans JavaScript ni hacks de contrôle de formulaire, sont une nouveauté relativement récente. Les éléments <details> et <summary> ne sont entièrement compatibles avec les navigateurs modernes que depuis janvier 2020. Vous pouvez désormais créer des widgets de divulgation fonctionnels, mais moins attrayants, avec du code HTML sémantique.

Les éléments <details> et <summary> sont tout ce dont vous avez besoin. Ils constituent un moyen intégré de gérer le développement et la réduction du contenu. Lorsqu'un utilisateur clique ou appuie sur un <summary>, ou relâche la touche Entrée lorsque le <summary> est sélectionné, le contenu du <details> parent devient visible.

Comme pour tout contenu sémantique, vous pouvez améliorer progressivement les fonctionnalités et l'apparence par défaut. Dans ce cas, un petit peu de CSS a été ajouté :

Cela signifie que ce CodePen (et tous les exemples CodePen) ne contient pas de code JavaScript.

Activer/Désactiver la visibilité avec l'attribut open

L'élément <details> est le conteneur du widget de divulgation. <summary> est le résumé ou la légende de son <details> parent. Le résumé est toujours affiché et sert de bouton pour afficher ou masquer le reste du contenu du parent. L'interaction avec <summary> permet d'afficher ou de masquer les éléments frères récapitulatifs auto-libellés en activant ou désactivant l'attribut open de l'élément <details>.

L'attribut open est un attribut booléen. Si elle est présente, quelle que soit sa valeur ou son absence, elle indique que tout le contenu <details> est affiché à l'utilisateur. Si l'attribut open n'est pas présent, seul le contenu de <summary> est affiché.

Étant donné que l'attribut open est ajouté et supprimé automatiquement lorsque l'utilisateur interagit avec le contrôle, il peut être utilisé dans CSS pour styliser l'élément différemment en fonction de son état.

Vous pouvez créer un accordéon avec une liste de plusieurs éléments <details>, chacun avec un enfant <summary>. Si vous omettez l'attribut open dans votre code HTML, tous les éléments <details> seront réduits ou fermés, et seuls les titres récapitulatifs seront visibles lorsque la page se chargera. Chaque titre sera l'élément d'ouverture du reste du contenu dans l'élément parent <details>. Si vous incluez l'attribut open dans votre code HTML, <details> s'affiche développé, avec le contenu visible, lorsque la page se charge.

Le contenu masqué dans l'état réduit est consultable dans certains navigateurs, mais pas dans d'autres, même s'il ne fait pas partie du DOM. Si vous effectuez une recherche dans Edge ou Chrome, les détails contenant un terme de recherche se développent pour afficher l'occurrence. Ce comportement ne se reproduit pas dans Firefox ni dans Safari.

L'élément <summary> doit être le premier enfant d'un élément <details>. Il représente un résumé, une légende ou une description pour le reste du contenu de l'élément <details> parent dans lequel il est imbriqué. Le contenu de l'élément <summary> peut être n'importe quel contenu d'en-tête, texte brut ou code HTML pouvant être utilisé dans un paragraphe.

Activer/Désactiver le repère de résumé

Dans les deux Codepens précédents, une flèche pointe vers le côté inline-start du résumé. Une flèche d'expansion est généralement affichée à l'écran. Il s'agit d'un petit triangle qui pivote (ou se tord) pour indiquer si l'élément est ouvert ou fermé, et d'un libellé à côté du triangle. Le contenu de l'élément <summary> sert de libellé au widget de divulgation.

La flèche rotative en haut de chaque section est un ::marker défini sur l'élément <summary>. Comme les éléments de liste, l'élément <summary> est compatible avec la propriété abrégée list-style et ses propriétés détaillées, y compris list-style-type. Vous pouvez styliser le triangle de développement avec CSS, y compris en remplaçant le repère utilisé (un triangle) par n'importe quel autre type de puce, y compris une image avec list-style-image.

Pour appliquer d'autres styles, utilisez un sélecteur semblable à details summary::marker. Le pseudo-élément ::marker n'accepte qu'un nombre limité de styles. Il est courant de supprimer l'élément ::marker et de le remplacer par l'élément ::before, plus facile à styliser. Les styles CSS modifient légèrement le style du contenu généré en fonction de la présence (ou de l'absence) de l'attribut "open". Vous pouvez supprimer l'icône du widget de divulgation en définissant list-style: none ou définir le contenu du repère sur none, mais vous devez toujours inclure des indicateurs visuels pour informer les utilisateurs voyants que le contenu du résumé bascule pour afficher et masquer le contenu.

details summary::before {
  /* all the styles */
}
details[open] summary::before {
  /* changes applied when open only */
}

Cet exemple supprime le repère par défaut et ajoute du contenu généré pour créer un + lorsque les détails sont fermés et un - lorsqu'ils sont ouverts.

Si vous souhaitez que le bloc de détails soit ouvert par défaut, incluez l'attribut open dans la balise d'ouverture <details>. Vous pouvez également ajouter un espace entre chaque boîte de dialogue et faire pivoter le repère créé avec le contenu généré pour améliorer l'apparence :

Gestion des erreurs

Si vous n'incluez pas de <summary>, le navigateur en crée un pour vous, avec un repère et le mot "details" (détails). Ce résumé fait partie d'une racine fantôme et, par conséquent, aucun style de résumé CSS d'auteur n'y est appliqué.

Si vous incluez un <summary>, mais qu'il ne s'agit pas du premier élément du <details>, le navigateur affiche quand même le résumé comme il se doit. L'opération ne sera pas interrompue si vous incluez un lien, un libellé ou un autre élément interactif dans le récapitulatif, mais les navigateurs gèrent différemment le contenu interactif dans le contenu interactif.

Par exemple, si vous incluez un lien dans un résumé, certains navigateurs ajoutent à la fois le résumé et le lien à l'ordre de tabulation par défaut, mais d'autres navigateurs ne mettent pas le lien en évidence par défaut. Si vous cliquez sur un <label> imbriqué dans un <summary>, certains navigateurs mettent le contrôle de formulaire associé au premier plan. D'autres navigateurs mettent l'accent sur le contrôle du formulaire et activent ou désactivent <details>.

Interface HTMLDetailsElement

Comme tous les éléments HTML, HTMLDetailsElement hérite de toutes les propriétés, méthodes et événements de HTMLElement, et ajoute la propriété d'instance open et un événement toggle. La propriété HTMLDetailsElement.open est une valeur booléenne qui reflète l'attribut HTML open. Elle indique si le contenu de l'élément (sans compter <summary>) doit être affiché à l'utilisateur. L'événement de bascule est déclenché lorsque l'élément <details> est ouvert ou fermé. Vous pouvez écouter cet événement à l'aide de addEventListener().

Si vous souhaitez écrire un script pour fermer les détails ouverts lorsque l'utilisateur en ouvre d'autres, supprimez l'attribut "open" à l'aide de removeAttribute("open") :

Il s'agit du seul exemple utilisant JavaScript. Vous n'avez probablement pas besoin de JavaScript, sauf pour fermer d'autres widgets ouverts.

N'oubliez pas que <details> et <summary> peuvent être fortement stylisés et même utilisés pour créer des info-bulles. Toutefois, si vous prévoyez d'utiliser ces éléments sémantiques pour des cas d'utilisation dans lesquels la sémantique native ne correspond pas, veillez toujours à maintenir l'accessibilité. Le HTML est, pour la plupart, accessible par défaut. En tant que développeurs, notre rôle est de veiller à ce que notre contenu reste accessible.

Vérifier que vous avez bien compris

Testez vos connaissances sur les détails et les résumés.

De quel élément <summary> doit-il être le premier enfant ?

<p>
Réessayez.
<details>
Bonne réponse !
<fieldset>
Réessayez.