Accordion

Composant de contenu dépliable organisé en items. Chaque item révèle son contenu au clic via une animation fluide. Supporte le mode "single" pour n'ouvrir qu'un panneau à la fois.

Stable JS requis Accessible

Aperçu


LIVE PREVIEW — ACCORDION PAR DÉFAUT

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Accusamus alias, consectetur culpa cumque debitis dolorum fugiat iste, iusto magnam mollitia nam numquam obcaecati praesentium quae quos reiciendis similique tempora voluptatum ?

Structure HTML


CODE HTML

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Accusamus alias, consectetur culpa cumque debitis dolorum fugiat iste, iusto magnam mollitia nam numquam obcaecati praesentium quae quos reiciendis similique tempora voluptatum ?

💡 Indispensable

Chaque data-target doit correspondre exactement à l’ id du panneau associé. Vous pouvez utiliser # ou non — le JavaScript gère les deux cas.


⚠️ Ne pas ajouter de margin ou de padding directement sur le panneau pour garantir une animation fluide. Utilisez .accordion-body pour gérer les espacements.

👉 Pour l’accessibilité

Les attributs suivants sont automatiquement ajoutés à l’initialisation :

Vous n’avez rien à gérer manuellement côté accessibilité — mais c’est toujours mieux d’y penser 😉

Classes CSS


CLASSE ÉLÉMENT DESCRIPTION
.accordion <div> Conteneur principal avec bordure, border-radius et gestion du débordement.
.accordion-item <div> Conteneur d’un item (structure uniquement, pas de style direct).
.accordion-btn <button> Bouton déclencheur en pleine largeur avec gestion des bordures et de l’état via aria-expanded.
.accordion-body <div> Contenu du panneau avec padding via variables CSS.
.accordion-indicator <span> Icône via ::after, animée selon l’état du bouton (.is-open).
.accordion-btn-sm <button> Paddings réduits.
.accordion-btn-md <button> Paddings intermédiaires (par défaut).
.accordion-btn-lg <button> Paddings augmentés.

Variantes


Mode multi (défaut)

Plusieurs panneaux peuvent être ouverts simultanément.

MULTI-OUVERTURE HTML

Mode single

Un seul panneau ouvert à la fois. Le JS ferme automatiquement les autres panneaux à l'ouverture d'un nouveau.

SINGLE HTML

Tailles


Les modificateurs de taille s'appliquent sur chaque .accordion-btn individuellement via les tokens CSS dédiés.

LIVE PREVIEW - TAILLES

États


ÉTAT ÉLÉMENT DESCRIPTION
Ouvert [aria-expended="true"] L'indicateur change de contenu. Le panneau est visible (hidden retiré).
Fermé [aria-expended="false"] Panneau avec attribut hidden. C'est l'état initial par défaut.
En animation [data-animating] Attribut temporaire posé par le JS. Bloque les clics répétés pendant l'animation (200 ms).
Focus :focus-visible Contour visible sur le bouton lors de la navigation clavier (à styler via CSS).

JavaScript


Le composant est piloté par la classe Collapse. Elle s'appuie sur la délégation d'événements (un seul listener sur document) et utilise l'API Web Animations pour les transitions.

INITIALISATION

SCRIPT D'INITIALISATION JS
import Collapse from './Collapse.js';

// A single instance is enough for the entire page.
new Collapse();

ℹ️ Singleton

La classe implémente un guard Collapse.initialized : instancier Collapse plusieurs fois n'entraîne aucun doublon de listeners.

ATTRIBUTS DE DONNÉES REQUIS

ATTRIBUT ÉLÉMENT DESCRIPTION
data-ui="accordion" .accordion Marque le wrapper pour la gestion du mode single.
data-type="single" .accordion Active le mode exclusif : un seul panneau ouvert à la fois.
data-ui="collapse" .accordion-btn Identifie le bouton comme déclencheur du "collapse".
data-target .accordion-btn Sélecteur de l'élément panneau cible. Accepte #id ou id.

MÉTHODES STATIQUES

MÉTHODE DESCRIPTION
Collapse.init() Initialise aria-controls et aria-expanded sur tous les boutons [data-ui="collapse"] du DOM.
Collapse.toggle(panel, button) Bascule l'état du panneau. Appelle open ou close selon panel.hidden.
Collapse.open(panel, button) Ouvre un panneau avec animation. Met à jour aria-expanded="true". Appelle handleAccordion.
Collapse.close(panel, button) Ferme un panneau avec animation. Repose hidden en fin d'animation.
Collapse.handleAccordion(button) Si le parent est data-type="single", ferme tous les autres panneaux ouverts.

ANIMATION

L'ouverture et la fermeture sont gérées par panel.animate() (Web Animations API), avec une durée de 200 ms et un easing ease. Un attribut data-animating est posé pendant la transition pour éviter les clics parasites.

UTILISATION MANUELLE (OPTIONNELLE) JS
// Open a panel programmatically
const panel = document.getElementById('mon-panel');
const btn = document.querySelector('[data-target="#mon-panel"]');
Collapse.open(panel, btn);

// Close programmatically
Collapse.close(panel, btn);

CSS Custom Properties


TOKEN RÔLE
--accordion-border-width Épaisseur des bordures
--accordion-border-style Style de bordure (solid, dashed…)
--accordion-border-radius Rayon des coins du wrapper
--accordion-border-color Couleur des bordures
--accordion-background-color Couleur de fond de l’accordéon
--accordion-body-padding-x Padding horizontal du corps
--accordion-body-padding-y Padding vertical du corps
--accordion-button-padding-x Padding horizontal du bouton (défaut)
--accordion-button-padding-y Padding vertical du bouton (défaut)
--accordion-button-padding-x-sm Padding horizontal — taille sm
--accordion-button-padding-y-sm Padding vertical — taille sm
--accordion-button-padding-x-md Padding horizontal — taille md
--accordion-button-padding-y-md Padding vertical — taille md
--accordion-button-padding-x-lg Padding horizontal — taille lg
--accordion-button-padding-y-lg Padding vertical — taille lg
--accordion-button-background-color Couleur de fond de l’accordéon bouton
--accordion-indicator-content Contenu de l'indicateur
EXEMPLE DE PERSONNALISATION CSS
/* Global variables */
:root {
  --accordion-border-radius: 8px;
  --accordion-button-padding-x: 1.5rem;
  --accordion-button-padding-y: 1.125rem;
}

/* Light theme */
:root[data-theme="light"] {
  color-scheme: light;
  --accordion-border-color: #222222;
}

/* Dark theme */
:root[data-theme="dark"] {
  color-scheme: dark;
  --accordion-border-color: #888888;
}

Accessibilité

PRATIQUE DÉTAIL
aria-expanded Posé et mis à jour automatiquement par le JS sur chaque bouton. Communique l'état ouvert/fermé aux lecteurs d'écran.
aria-controls Lie le bouton à son panneau via l'id. Initialisé par Collapse.init() si absent.
aria-labelledby Associe le panneau à son bouton déclencheur via l'id du bouton. Permet aux lecteurs d'écran d'annoncer correctement le libellé du panneau. Ajouté automatiquement par Collapse.init() lorsque le bouton possède un id.
hidden L'attribut HTML natif masque le panneau aux technologies d'assistance et aux moteurs de recherche.
Élément <button> Utilisez toujours un <button> (pas un <div>) pour assurer la navigation clavier native (Tab, Entrée, Espace).
Focus visible Stylez :focus-visible sur .accordion-btn pour les utilisateurs clavier.
role="region" Définit le panneau comme une région accessible pour les technologies d’assistance. À rajouter si le panel est important.

⚠️ Attention

N'utilisez pas display: none à la place de hidden : le JS anime la hauteur et repose l'attribut natif en fin d'animation. Toute surcharge CSS peut casser le comportement.

Notes & bonnes pratiques


✅ À faire

Toujours ajouter hidden sur les panneaux fermés au chargement. Sans cet attribut, les panneaux sont considérés comme ouverts par défaut.

✅ À faire

Placer l'.accordion-indicator en dernier dans le bouton pour qu'il soit poussé à droite avec par le justify-content: space-between; du .accordion-btn.

❌ À éviter

Ne pas instancier Collapse avant le chargement du DOM. Utilisez DOMContentLoaded ou placez le script en bas de page.

ℹ️ Compatibilité

L'animation repose sur la Web Animations API (element.animate()), supportée par tous les navigateurs modernes. Pour IE11, un polyfill est nécessaire.


Accordion · WEBDEV-UI DOCS / V1