Créez un accordéon exclusif avec plusieurs éléments <details>
ayant le même name
.
L'accordéon
Un modèle d'interface utilisateur courant sur le Web est le composant en accordéon. Il s'agit d'un composant qui se compose de plusieurs widgets de communiqués, que vous pouvez développer (ou réduire) individuellement pour afficher (ou masquer) leur contenu.
Pour implémenter ce modèle sur le Web, vous devez combiner quelques éléments <details>
et les regrouper visuellement pour indiquer qu'ils vont ensemble.
L'accordéon exclusif
Navigateurs pris en charge
- 120
- 120
- x
- 17.2
Une variante du modèle d'accordéon est l'accordéon exclusif, dans lequel un seul des widgets d'information peut être ouvert à la fois.
Pour ce faire sur le Web, vous pouvez désormais ajouter un attribut name
aux éléments <details>
. Lorsque cet attribut est utilisé, plusieurs éléments <details>
ayant la même valeur name
forment un groupe sémantique et se comportent comme un accordéon exclusif. Lorsque vous ouvrez l'un des éléments <details>
du groupe, l'élément précédemment ouvert se ferme automatiquement.
<details name="learn-css">
<summary>Welcome to Learn CSS!</summary>
<p>…</p>
</details>
<details name="learn-css">
<summary>Box Model</summary>
<p>…</p>
</details>
<details name="learn-css">
<summary>Selectors</summary>
<p>…</p>
</details>
Une page peut comporter plusieurs accordéons exclusifs. Chaque fois que vous utilisez une nouvelle valeur name
sur un élément <details>
, un groupe logique est créé.
Notez que les éléments <details>
qui font partie d'un accordéon exclusif n'ont pas nécessairement besoin d'être frères. Ils peuvent être éparpillés dans le document. C'est l'attribut name
qui les regroupe, et non leur ordre DOM.
Sublimez l'accordéon exclusif
Le JavaScript suivant permet d'émuler le comportement de l'accordéon exclusif. Le code repose sur l'événement toggle
de l'élément <details>
.
Lorsqu'un élément <details>
avec un élément name
s'ouvre, le code trouve les autres éléments <details>
ouverts qui présentent la même valeur pour l'attribut name
, puis les ferme.
document.querySelectorAll("details[name]").forEach(($details) => {
$details.addEventListener("toggle", (e) => {
const name = $details.getAttribute("name");
if (e.newState == "open") {
document
.querySelectorAll(`details[name=${name}][open]`)
.forEach(($openDetails) => {
if (!($openDetails === $details)) {
$openDetails.removeAttribute("open");
}
});
}
});
});
Certaines anciennes versions de navigateurs ne déclenchent pas cet événement toggle
. Dans ces navigateurs, le code du polyfill ne fait rien. En termes d'amélioration progressive, ce comportement est acceptable.