Go to Hackademy website

Création d'un menu en accordéon avec CSS

Victor Darras

Posté par Victor Darras dans les catégories design

Bonjour à tous, l’article d’aujourd’hui , dans la lignée de celui concernant la barre de chargement en CSS portera sur la création d’un élément bien connu des intégrateurs, en particulier sur les applications métier : Le menu accordéon.

L’idée de cet article sera de se passer de Javascript, nous n’aurons besoin que de quelques astuces à base de balises HTML et de selecteurs CSS. Voici un exemple du menu que nous pourrions obtenir à la fin de cet article.

Le markup HTML

Tout d’abord, créons un menu en HTML standard, à base de liste imbriquées :

<ul>
  <li> 
    Menu #1
    <ul>  
      <li>Sous-menu #1</li>
      <li>Sous-menu #2</li>
    </ul>
  </li>
  <li> 
    Menu #2
    <ul>  
      <li>Sous-menu #1</li>
      <li>Sous-menu #2</li>
    </ul>
  </li>
  <li> 
    Menu #3
    <ul>  
      <li>Sous-menu #1</li>
      <li>Sous-menu #2</li>
    </ul>
  </li>
</ul>

Ajoutons quelques classes afin de clarifier le markup et les CSS qui suivront, nous aurions pu n’utiliser que les éléments HTML mais le CSS aurait été plus abstrait. Notre menu global sera donc un .accordion , contenant lui même des éléments avec un autre menu imbriqué que nous définirons avec .has-sub. Chaque sous-menu sera appelé .sub.

<ul class="accordion">
  <li class="has-sub">
    Menu #1
    <ul class="sub">
      <li></li>
    </ul>
  </li>
[...]
</ul>

Afin de savoir si un .has-sub est selectionné, pour afficher son menu enfant, nous utiliserons un input, de type checkbox ou radio. Les 2 sont utilisables mais n’aurons pas exactement le même résultat en terme d’expérience utilisateur, nous verrons par la suite quelle est la différence. Afin de modifier la valeur de ces input, nous utiliserons des label avec un attribut for désignant l’input concerné. Chaque input se verra assigné un attribut name qui nous permettra de définir des groupes d’input. Il est possible en règle générale de placer l’input à l’intérieur du label afin de ne pas avoir à définir d’attribut for mais nous aurons besoin d’avoir l’input et le .sub au même niveau pour jouer avec les CSS.

<ul class="accordion">
  <li class="has-sub">
    <label for="menu1">Menu #1</label>
    <input#menu1 type="checkbox" name="menu" />
    <ul class="sub">
      <li></li>
      <li></li>
    </ul>
  </li>
  <li class="has-sub">
    <label for="menu2">Menu #2</label>
    <input#menu2 type="checkbox" name="menu" />
    <ul class="sub">
      <li></li>
      <li></li>
    </ul>
  </li>
</ul>

Vous devriez obtenir un rendu dans ce style là :

Accordéon sans HTML

Les CSS pour l’interaction

Tout d’abord pour avoir un accordéon nous devons faire en sorte de n’afficher que les éléments parents qui afficheront leurs enfants. Nous aurions pu utiliser un simple display: none; sur chaque .sub mais cela nous empêcherait de gérer une transition entre les 2 états. Nous allons donc commencer par appliquer une hauteur nulle à chaque élément de nos sous-menus avec un overflow: hidden; pour être sûr de ne pas afficher leur contenu, quelqu’il soit.

.sub > li {
    height: 0;
    overflow: hidden;
}

Ensuite nous dissimulons les inputs qui nous permettrons de connaitre le(s) sous-menu(s) affiché(s).

input[type="radio"],
input[type="checkbox"] {
    display: none
}

Et enfin nous affichons les sous-menus lorsque l’input qui les précéde est checké.

input:checked + .sub > li {
    height: 2em;
}

Checkbox ou Radio

Comme je vous l’expliquais plus tôt nous avons la possibilité d’utiliser des inputs de type checkbox ou radio afin de modifier le comportement du menu.

Checkbox

L’utilisation de checkbox nous permet d’ouvrir en parallèle plusieurs sous-menu, pratique pour les menu avec peu d’entrées et permet d’avoir une vision globale de tous les sous-menus. Cette solution permet aussi de refermer chacun des menus, pour afficher un élément sous ce dernier sans scroller par exemple.

Radio

En utilisant des input de type radio nous pourrons faire en sorte de n’afficher qu’un seul sous-menu à la fois, ce qui peut-être utilie lorsque tous les sous-menu comportent beaucoup d’entrées et qu’il est inutile d’en afficher plusieurs à la fois. Cette solution ne permet pas, par contre, de refermer tous les menus.

Après l’interaction, ajoutons un peu de styles

Si on a tout suivi à la lettre nous devrions nous retrouver avec une liste très moche contenant des labels permettant d’afficher ou non une sous-liste.

Comme je disais plus haut, ce genre d’intéraction aurait très bien pu être effectuée avec un display: none; sur chaque .sub. Mais la plupart du temps nous aimerions bien avoir un vrai effet d’accordéon, où chaque sous-liste se déploie élégamment. Dans un premier temps nous allons donc mettre en place une transition.

.sub > li {
    transition: all 0.25s ease-in-out // n'hésitez pas à jouer avec ces valeurs
}

Nous remarquons maintenant que chaque sous-listes se déploie avec une transition, cela permet de renvoyer à l’utilisateur un indice visuel sur sa dernière action. Nous pouvons affiner la transition en ajoutant un changement d’opacité, et pourquoi pas de padding afin de modifier légèrement la taille et la position des entrées de notre sous-menu.

.sub > li {
    opacity: 0;
    height: 0;
    padding: 0;
    transition: all 0.25s ease-in-out;
}
input:checked + .sub > li {
    padding: 0.7em 1em
    height: 1.4em
    opacity: 1
}

Je vous laisse tester le résultat, bien plus fluide n’est-ce pas ? Evidemment l’ensemble reste visuellement proche d’une liste en HTML pure, nous pourrions modifier les couleurs de l’ensemble, ajuster des marges ou peaufiner encore les transitions. Ce que je me suis empréssé de faire, je vous invite à découvrir mon exemple sur codepen :

See the Pen Pure CSS accordions by Victor Darras (@victordarras) on CodePen.


N’hésitez pas à forker le codepen ou à refaire l’exercice et à nous partager vos propres expérimentations, je suis curieux de voir ce que ça pourrait donner ! J’espère que cet exercice vous a plu, si tel est le cas n’hésitez pas à le partager autour de vous. À bientot.

L’équipe Synbioz.

Libres d’être ensemble.

Articles connexes

Exporter des assets pour Android avec Sketch

17/04/2015

Bien le bonjour intrépides lecteurs, aujourd’hui je vais vous faire part d’un plugin pour Sketch (que je présente depuis quelques temps sur ce blog). Baptisé Sketch Android Assets, ce plugin vous...

Création d'une barre de chargement avec CSS

28/01/2015

Bonjour à tous, aujourd’hui je vais vous présenter une petite astuce pour mettre en place une barre de chargement avec un tooltip qui affichera de façon élégante où elle en est, le tout avec quelques...

Client, designer, développeur: un workflow qui fonctionne

12/03/2014

Arrivé depuis maintenant plus d’un an chez Synbioz, j’ai eu l’occasion de travailler sur plusieurs projets avec plusieurs développeurs. En tant que webdesigner et intégrateur j’ai la possibilité de...

Une carte de France en SVG

06/02/2014

Bonjour à vous, aujourd’hui nous allons mettre à disposition une ressource bien pratique pour celles et ceux qui auraient besoin d’une carte pour leur application / site. Nous voyons de plus en plus...