Comment ça marche
Simplement, cela va transformer ceci :
<h2 class="js-expandmore">Lorem dolor si amet</h2>
<div class="js-to_expand">
Ici le contenu caché
</div>
En ceci :
<h2 class="js-expandmore">
<button aria-controls="expand_1" aria-expanded="false" class="expandmore__button">
<span class="expandmore__symbol" aria-hidden="true"></span>
Lorem dolor si amet
</button>
</h2>
<div id="expand_1" class="js-to_expand" aria-labelledby="label_expand_1">
Ici le contenu caché
</div>
Les attributs et leurs valeurs sont générés à la volée (data-controls="expand_1"
, id="expand_1"
, data-labelledby="label_expand_1"
), pas besoin de vous en soucier
Comment l’utiliser
Téléchargez le script
Vous pouvez utiliser la commande npm : npm i van11y-accessible-hide-show-aria
.
Vous pouvez aussi utiliser Bower : bower install van11y-accessible-hide-show-aria
.
Conventions
Ensuite, suivez cette convention (qui peut être adaptée selon vos besoins, voir « Configuration par défaut ») :
<h2 class="js-expandmore">Lorem dolor si amet</h2>
<div class="js-to_expand">
Ici le contenu caché
</div>
Pour des raisons d’accessibilité, vous devez poser la classe class="js-expandmore"
sur un élément Hx
(h1
, h2
, h3
, etc.).
Les éléments qui ont les classes js-expandmore
et js-to_expand
doivent être adjacents.
Ensuite, utilisez le script qui fera le reste.
Le script est lancé au chargement de la page. Si vous avez besoin de l’exécuter sur du contenu généré en AJAX, vous pourrez utiliser par exemple sur <div id="newContent">la source des panneaux dépliants</div>
:
var my_expand = van11yAccessibleHideShowAria();
my_expand.attach(document.getElementById('newContent'));
Styles nécessaires pour que cela marche
Le style minimum nécessaire est :
.js-to_expand[aria-hidden=true],
.js-to_expand[data-hidden=true] {
display: none;
}
Cependant, comme le script ajoute un button
dans le Hx
, vous devrez styler cet élément. Voici un exemple :
.expandmore__button {
background: none;
font-size: inherit;
color: inherit;
}
.expandmore__symbol::before {
content : '+ ';
}
.expandmore__button[aria-expanded=true] > .expandmore__symbol::before {
content : '− ';
}
Logique des classes pour styler
Comment créer différents styles dans la même page ?
C’est possible et même très simple, utilisez l’attribut data-hideshow-prefix-class="<votre_valeur>"
comme ceci :
<h2 class="js-expandmore" data-hideshow-prefix-class="mini-combo">Lorem dolor si amet</h2>
<div class="js-to_expand">
Ici le contenu caché
</div>
Cela préfixera les classes générées, <votre_valeur>-expandmore__button
et <votre_valeur>-expandmore__to_expand
, comme suit :
<h2 class="js-expandmore" data-hideshow-prefix-class="mini-combo">
<button id="label_expand_2" class="mini-combo-expandmore__button js-expandmore-button" data-controls="expand_2" aria-expanded="false" type="button">
Lorem dolor si amet
</button>
</h2>
<div id="expand_2" class="js-to_expand mini-combo-expandmore__to_expand" data-hidden="true" data-labelledby="label_expand_2">
Ici le contenu caché
</div>
Le script va préfixer toutes les classes, et donc vous pourrez les styler comme bon vous semble. Si vous n’utilisez pas cet attribut, le script n’y verra aucun problème.
Configuration par défaut
const CONFIG = {
HIDESHOW_EXPAND: 'js-expandmore',
HIDESHOW_BUTTON_EXPAND: 'js-expandmore-button',
HIDESHOW_BUTTON_EXPAND_STYLE: 'expandmore__button',
HIDESHOW_BUTTON_LABEL_ID: 'label_expand_',
DATA_PREFIX_CLASS: 'data-hideshow-prefix-class',
HIDESHOW_BUTTON_EMPTY_ELEMENT_SYMBOL: 'expandmore__symbol',
HIDESHOW_BUTTON_EMPTY_ELEMENT_TAG: 'span',
ATTR_HIDESHOW_BUTTON_EMPTY_ELEMENT: 'aria-hidden',
HIDESHOW_TO_EXPAND_ID: 'expand_',
HIDESHOW_TO_EXPAND_STYLE: 'expandmore__to_expand',
ATTR_CONTROL: 'data-controls',
ATTR_EXPANDED: 'aria-expanded',
ATTR_LABELLEDBY: 'data-labelledby',
ATTR_HIDDEN: 'data-hidden',
IS_OPENED_CLASS: 'is-opened',
DISPLAY_FIRST_LOAD: 'js-first_load',
DISPLAY_FIRST_LOAD_DELAY: '1500',
...config
};
Si vous avez besoin d’une autre configuration, il faut appeler le plugin ainsi :
var other_expand = van11yAccessibleHideShowAria({
HIDESHOW_EXPAND: 'js-expandmore2',
DATA_PREFIX_CLASS: 'data-hideshow-prefix-class2'
});
other_expand.attach();
Et tout fonctionnera comme vous le souhaitez.
Bonus
Ouvert par défaut
Pas de souci, c’est possible et même très simple, utilisez la classe is-opened
sur :
<h2 class="js-expandmore">Lorem dolor si amet</h2>
<div class="js-to_expand is-opened">
Ici le contenu caché
</div>
Le script va le détecter, et faire que cela soit ouvert par défaut. Aussi simple qu’un copier/coller.
Animations
Pas de souci, c’est possible en utilisant des transitions CSS. Vous devez avoir à l’esprit plusieurs choses pour faire que cela soit accessible :
- Vous ne pouvez pas animer la propriété
display
, et la propriété height
peut être très compliquée à animer également (sans hauteur connue).
- Donc dans ce cas, il est impossible d’utiliser
display: none;
pour cacher un contenu (même pour les technologies d’assistance).
- Donc vous devez passer la propriété
visibility
à visible
ou hidden
pour afficher/cacher un contenu.
- En clair, vous devez animer
max-height
, opacity
(si besoin), et utiliser visibility
pour cacher le contenu aux technologies d’assistance.
Si vous avez cliqué sur cette section, vous aurez pu voir l’animation en action. Partons de l’idée qu’on a cette source :
<h2 class="js-expandmore mb0 mt0" data-hideshow-prefix-class="animated">Bonus : des animations ?</h2>
<div class="js-to_expand">
…
</div>
Voici donc le code CSS pour les transitions (non préfixé) :
.animated-expandmore__to_expand {
display: block;
overflow: hidden;
opacity: 1;
transition: visibility 0s ease, max-height 2s ease, opacity 2s ease ;
max-height: 80em;
visibility: visible;
transition-delay: 0s;
}
[data-hidden=true].animated-expandmore__to_expand {
display: block;
max-height: 0;
opacity: 0;
visibility: hidden;
transition-delay: 2s, 0s, 0s;
}
Voici l’astuce : de l’état « fermé » à l’état « ouvert », la propriété visibility
est immédiatement mise à visible
, et max-height
/opacity
sont « normalement » animées.
De l’état « ouvert » à l’état « fermé », l’animation de la propriété visibility
a un délai. Donc le contenu sera caché… à la fin de l’animation de max-height
/opacity
.
Attributs ARIA ou attributs data
?
Pas de souci. Au début du code du script, voici la configuration par défaut :
ATTR_CONTROL: 'data-controls',
ATTR_EXPANDED: 'aria-expanded',
ATTR_LABELLEDBY: 'data-labelledby',
ATTR_HIDDEN: 'data-hidden',
Cette configuration par défaut est recommandée par les experts accessibilité (et pour fonctionner dans le plus de cas possibles).
Si vous avez besoin de faire autrement, vous pouvez, le script s’adaptera. Exemple :
var my_expand = van11yAccessibleHideShowAria({
ATTR_CONTROL: 'aria-controls',
ATTR_EXPANDED: 'aria-expanded',
ATTR_LABELLEDBY: 'aria-labelledby',
ATTR_HIDDEN: 'aria-hidden',
});
my_expand.attach();
Bien sûr, il faudra mettre à jour votre CSS en utilisant les bons attributs si besoin est.