Accordéon

Un accordéon permet l'affichage d'une liste d'éléments empilés dont le contenu est révélé par un système de plier / déplier.

Règles d’implémentation pour l’accessibilité

  • Le titre de chaque en-tête de l’accordéon est contenu dans un élément button avec un attribut aria-controls qui fait référence à l’id de l’élément qu’il contrôle et un attribut aria-expanded qui prend la valeur true quand la zone que gère l’en-tête de l’accordéon est visible et false quand la zone que gère l’en-tête de l’accordéon est invisible.
  • L’élément bouton est le seul élément à l’intérieur de l’élément titre. Autrement dit, s’il existe d’autres éléments visuellement persistants, ils ne sont pas inclus dans l’élément d’en-tête.
  • Si le panneau d’accordéon associé à un en-tête d’accordéon est visible, et si l’accordéon ne permet pas de réduire le panneau, l’élément du bouton d’en-tête a aria-disabled défini sur true.
  • Chaque élément qui sert de conteneur pour le contenu du panneau a le rôle region et un id avec une valeur qui fait référence au bouton qui contrôle l’affichage du panneau. La région de rôle est particulièrement utile pour la perception de la structure par les utilisateurs de lecteurs d’écran lorsque les panneaux contiennent des éléments d’en-tête ou un accordéon imbriqué.

Visuel

Extraits de code

Code HTML

<div class="accordeon">
    <h3>
        <button type="button" aria-expanded="true" class="accordeon-bouton" aria-controls="contenu1" id="accordeon1">
            Intitulé accordéon 1
        </button>
    </h3>
    <div id="contenu1" role="region" aria-labelledby="accordeon1" class="accordeon-panneau">
            <p>Consectetur cupidatat nisi amet exercitation quis mollit. Incididunt labore voluptate labore
                nostrud incididunt fugiat labore est anim tempor et Lorem dolor ea. Est aute sint velit deserunt
                qui adipisicing magna cillum fugiat et exercitation. Consectetur excepteur aliquip duis
                consectetur minim tempor amet sint fugiat duis irure do. Laboris magna cupidatat sint enim non
                occaecat cillum anim consectetur mollit laboris anim. Ea velit fugiat nisi aliquip labore sit
                Lorem laborum mollit sit culpa non sunt.</p>
            <p>Consectetur cupidatat nisi amet exercitation quis mollit. Incididunt labore voluptate labore
                nostrud incididunt fugiat labore est anim tempor et Lorem dolor ea. Est aute sint velit deserunt
                qui adipisicing magna cillum fugiat et exercitation. Consectetur excepteur aliquip duis
                consectetur minim tempor amet sint fugiat duis irure do. Laboris magna cupidatat sint enim non
                occaecat cillum anim consectetur mollit laboris anim. Ea velit fugiat nisi aliquip labore sit
                Lorem laborum mollit sit culpa non sunt.</p>
    </div>
    <h3>
        <button type="button" aria-expanded="false" class="accordeon-bouton" aria-controls="contenu2" id="accordeon2">
            Intitulé accordéon 2
        </button>
    </h3>
    <div id="contenu2" role="region" aria-labelledby="accordeon2" class="accordeon-panneau" hidden="">
            <p>Consectetur cupidatat nisi amet exercitation quis mollit. Incididunt labore voluptate labore
                nostrud incididunt fugiat labore est anim tempor et Lorem dolor ea. Est aute sint velit deserunt
                qui adipisicing magna cillum fugiat et exercitation. Consectetur excepteur aliquip duis
                consectetur minim tempor amet sint fugiat duis irure do. Laboris magna cupidatat sint enim non
                occaecat cillum anim consectetur mollit laboris anim. Ea velit fugiat nisi aliquip labore sit
                Lorem laborum mollit sit culpa non sunt.</p>
            <p>Consectetur cupidatat nisi amet exercitation quis mollit. Incididunt labore voluptate labore
                nostrud incididunt fugiat labore est anim tempor et Lorem dolor ea. Est aute sint velit deserunt
                qui adipisicing magna cillum fugiat et exercitation. Consectetur excepteur aliquip duis
                consectetur minim tempor amet sint fugiat duis irure do. Laboris magna cupidatat sint enim non
                occaecat cillum anim consectetur mollit laboris anim. Ea velit fugiat nisi aliquip labore sit
                Lorem laborum mollit sit culpa non sunt.</p>
    </div>
    <h3>
        <button type="button" aria-expanded="false" class="accordeon-bouton" aria-controls="contenu3" id="accordeon3">
            Intitulé accordéon 3
        </button>
    </h3>
    <div id="contenu3" role="region" aria-labelledby="accordeon3" class="accordeon-panneau" hidden="">
            <p>Consectetur cupidatat nisi amet exercitation quis mollit. Incididunt labore voluptate labore
                nostrud incididunt fugiat labore est anim tempor et Lorem dolor ea. Est aute sint velit deserunt
                qui adipisicing magna cillum fugiat et exercitation. Consectetur excepteur aliquip duis
                consectetur minim tempor amet sint fugiat duis irure do. Laboris magna cupidatat sint enim non
                occaecat cillum anim consectetur mollit laboris anim. Ea velit fugiat nisi aliquip labore sit
                Lorem laborum mollit sit culpa non sunt.</p>
            <p>Consectetur cupidatat nisi amet exercitation quis mollit. Incididunt labore voluptate labore
                nostrud incididunt fugiat labore est anim tempor et Lorem dolor ea. Est aute sint velit deserunt
                qui adipisicing magna cillum fugiat et exercitation. Consectetur excepteur aliquip duis
                consectetur minim tempor amet sint fugiat duis irure do. Laboris magna cupidatat sint enim non
                occaecat cillum anim consectetur mollit laboris anim. Ea velit fugiat nisi aliquip labore sit
                Lorem laborum mollit sit culpa non sunt.</p>
    </div>
</div>

Code CSS

Pour adapter la couleur de la barre de navigation et des liens, modifier les codes couleurs dans la déclaration :root.

:root {
    --accordeon-width: 50%;
    --acccordeon-border-radius: 0;
    --accordeon-border-color: #858585;
    --accordeon-entete-color: #212121;
    --accordeon-entete-hover-background-color: #e1edfe;
    --accordeon-entete-hover-color: #0759d5;
    --accordeon-focus-border-color: #0759d5;
    --accordeon-focus-within-background-color: #f7f7f7;
}

.accordeon {
    margin: 0;
    padding: 0;
    border-top: 1px solid var(--accordeon-border-color);
    border-bottom: 1px solid var(--accordeon-border-color);
    width: var(--accordeon-width);
}

.accordeon h3 {
    margin: 0 !important;
    padding: 0;
}

.accordeon>*+* {
    border-top: 1px solid var(--accordeon-border-color);
}

.accordeon-bouton {
    color: var(--accordeon-entete-color);
    background-color: transparent;
    border:0;
    font-size: 1rem;
    font-weight: 500;
    line-height: 1.5rem;
    margin: 0;
    max-height: none;
    max-width: 100%;
    min-height: 3rem;
    overflow: initial;
    padding: .75rem 1rem;
    text-align: left;
    width: 100%;
}
.accordeon-bouton::after {
  --icon-size: 1.25rem;
    content: "";
    background-color: currentColor;
    float: right;
    flex: none;
    height: var(--icon-size);
    -webkit-mask-size: 100% 100%;
    mask-size: 100% 100%;
    vertical-align: calc((.55em - var(--icon-size)) * .5);
    width: var(--icon-size);
    -webkit-mask-image: url(../images/caret-right-fill.svg);
    mask-image: url(../images/caret-right-fill.svg);
    transform: rotate(90deg);
    transition: transform .2s ease-out;
}
.accordeon-bouton[aria-expanded="true"] {
    font-weight: bold;
    background-color: var(--accordeon-entete-hover-background-color);
}
.accordeon-bouton[aria-expanded="true"]::after {
    transform: rotate(-180deg);
}
.accordeon-bouton:focus,
.accordeon-bouton:hover {
    background: var(--accordeon-entete-hover-background-color);
}

.accordeon-panneau {
    margin: 0;
    padding: 1em 0;
}

/* For Edge bug https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/4806035/ */
.accordeon-panneau[hidden] {
    display: none;
}

Image SVG servant de flèche

flèche SVG : Télécharger l’image

Code javascript


"use strict";

class Accordion {
  constructor(domNode) {
    this.rootEl = domNode;
    this.buttonEl = this.rootEl.querySelector("button[aria-expanded]");

    const controlsId = this.buttonEl.getAttribute("aria-controls");
    this.contentEl = document.getElementById(controlsId);

    this.open = this.buttonEl.getAttribute("aria-expanded") === "true";

    // add event listeners
    this.buttonEl.addEventListener("click", this.onButtonClick.bind(this));
  }

  onButtonClick() {
    this.toggle(!this.open);
  }

  toggle(open) {
    // don't do anything if the open state doesn't change
    if (open === this.open) {
      return;
    }

    // update the internal state
    this.open = open;

    // handle DOM updates
    this.buttonEl.setAttribute("aria-expanded", `${open}`);
    if (open) {
      this.contentEl.removeAttribute("hidden");
    } else {
      this.contentEl.setAttribute("hidden", "");
    }
  }

  // Add public open and close methods for convenience
  open() {
    this.toggle(true);
  }

  close() {
    this.toggle(false);
  }
}

// init accordions
const accordions = document.querySelectorAll(".accordion h3");
accordions.forEach((accordionEl) => {
  new Accordion(accordionEl);
});