Robuste et accessible

  • Comme c’est basé sur une structure HTML de base (Hx et contenus), même si le JavaScript n’est pas chargé, la page marchera, c’est le miracle de l’amélioration progressive ;
  • C’est basé sur le Design Pattern ARIA pour les accordéons ;
  • Pas de CSS/JavaScript injecté en ligne, le DOM reste propre, ce qui cool pour le responsive.

C’est (hautement) personnalisable

  • Vous pouvez le styler comme vous voulez ;
  • Vous pouvez utiliser des transitions ou animations… comme vous voulez ;
  • Vous pouvez créer un namespace pour les classes générées si vous avez besoin de différents comportements dans la même page ;
  • Chaque aspect du script peut être personnalisé, si vous transpilez le script en ES5, ce sera compatible IE9+.

Libre et sous une license permissive

  • Pas de problème : c’est placé sous licence MIT, donc c’est libre, open-source et vous pouvez faire ce que vous voulez avec, incluant une utilisation commerciale. Cette note de permission doit être incluse dans toutes les copies complètes ou partielles du script.
  • Cependant, il n’est pas interdit de me dire que vous l’avez utilisé, ou de m’envoyer un petit « merci ». ;)

Léger

  • 19kb (développement, lisible par les humains) ;
  • ~5kb (minifié, lisible par des machines) ;
  • ~3kb minifié et gzippé (lisible par… des mutants ‽‽)

Comment ça marche

Simplement, cela va transformer ceci :

<div class="js-accordion" data-accordion-prefix-classes="your-prefix-class">
 <h2 class="js-accordion__header">Premier élément</h2>
 <div class="js-accordion__panel">
   <p>Contenu du premier élément</p>
 </div>
 <h2 class="js-accordion__header">Deuxième élément</h2>
 <div class="js-accordion__panel">
   <p>Contenu du deuxième élément</p>
 </div>
 <h2 class="js-accordion__header">Troisième élément</h2>
 <div class="js-accordion__panel">
   <p>Contenu du troisième élément</p>
 </div>
</div>

En ceci :

<div class="your-prefix-class" 
   data-accordion-prefix-classes="your-prefix-class"
   role="tablist" aria-multiselectable="true">

 <button id="accordion1_tab1" 
     class="js-accordion__header your-prefix-class__header" 
     aria-controls="accordion1_panel1" aria-expanded="false" 
     role="tab" aria-selected="true" type="button">
       Premier élément
 </button>

 <div id="accordion1_panel1" 
     class="js-accordion__panel your-prefix-class__panel" 
     aria-labelledby="accordion1_tab1" 
     role="tabpanel" aria-hidden="true">

   <h2 class="your-prefix-class__title" tabindex="0">Premier élément</h2>
   <p>Contenu du premier élément</p>

 </div>
 … etc…
</div>

Le script fera tout le boulot (les ids, les attributs ARIA, les buttons sont générés à la volée).

Comment l’utiliser

Vous pouvez utilisez la commande npm : npm i van11y-accessible-accordion-aria.
Vous pouvez aussi utiliser Bower : bower install van11y-accessible-accordion-aria.

Ensuite, il faut suivre les conventions données dans cet exemple minimaliste.

<div class="js-accordion" data-accordion-prefix-classes="your-prefix-class">
 <h2 class="js-accordion__header">Premier élément</h2>
 <div class="js-accordion__panel">
   <p>Content of 1st tab</p>
 </div>
 <h2 class="js-accordion__header">Deuxième élément</h2>
 <div class="js-accordion__panel">
   <p>Content of 2nd tab</p>
 </div>
 <h2 class="js-accordion__header">Troisième élément</h2>
 <div class="js-accordion__panel">
   <p>Content of 3rd tab</p>
 </div>
</div>

Le style minimum nécessaire est le suivant :

.your-prefix-class__panel[aria-hidden=true] {
  display: none;
}

Comment (bien) le styler

Dans cette page d’exemple, j’ai utilisé data-accordion-prefix-classes="minimalist-accordion", donc toutes les classes générées commenceront par .minimalist-accordion (.minimalist-accordion__header, .minimalist-accordion__panel et .minimalist-accordion__title).

.minimalist-accordion__panel[aria-hidden=true] {
  display: none;
}

.minimalist-accordion__header {
  display: block;
}

/* titre ouvert */
.minimalist-accordion__header[aria-expanded="true"]:before {
  content: "- ";
}
/* titre fermé */
.minimalist-accordion__header[aria-expanded="false"]:before {
  content: "+ ";
}

/* titre sélectionné */
.minimalist-accordion__header[aria-selected="true"]:after {
  content: " (sel)";
}
/* titre non sélectionné */
.minimalist-accordion__header[aria-selected="false"]:after {
  content: " (unselc)";
}

Raccourcis clavier

La navigation au clavier est également supportée, voici les raccourcis :

Si le focus est sur les “boutons” de l’accordéon:

  • utilisez Haut/Gauche pour mettre le focus sur le bouton précédent de l’accordéon,
  • utilisez Bas/Droite pour mettre le focus sur le bouton suivant de l’accordéon
  • utilisez Home pour mettre le focus sur le premier bouton de l’accordéon (où qu’on soit sur les boutons de l’accordéon)
  • utilisez End pour mettre le focus sur le dernier bouton de l’accordéon (où qu’on soit sur les boutons de l’accordéon)

Et appuyez sur espace ou entrée sur un bouton de l’accordéon pour les ouvrir/fermer.

Si le focus est sur les contenus de l’accordéon :

  • utilisez Ctrl Haut pour remettre le focus sur le bouton correspondant au contenu
  • utilisez Ctrl PageUp pour remettre le focus sur le bouton précédent celui qui correspond au contenu
  • utilisez Ctrl PageDown pour remettre le focus sur le bouton suivant celui qui correspond au contenu

Attention : la combinaison Ctrl+PageUp/PageDown peut activer un changement d’onglet dans le navigateur. On ne peut rien y faire à ma connaissance (si vous avez une solution, tenez-moi au courant).

Bonus

Contenu ouvert par défaut

Si vous voulez qu’un contenu de l’accordéon soit ouvert par défaut, ajoutez l’attribut data-accordion-opened="true" sur un hx, exemple :

<h2 class="js-accordion__header" data-accordion-opened="true">
 Deuxième élément
</h2>

Et le script fera que le contenu soit ouvert.

Autre options

Le design pattern ARIA pour les accordéons autorise d’avoir plusieurs panels ouvert en même temps (ce qui est indiqué par l’attribut aria-multiselectable="true"). Cependant, vous pouvez avoir besoin d’éviter ce comportement. Pour ce faire, vous pouvez spécifier l’attribut sur le conteneur de l’accordéon : data-accordion-multiselectable="none". Exemple :

<div class="js-accordion" data-accordion-multiselectable="none">

Cette option ajouter l’attribut aria-multiselectable="false" et le script n’autorisera qu’un seul contenu ouvert en même temps.