Chapitre 2
Interface et menus

Retour Accueil CSS

18 Menu à coulisse

Termes CSS clés employés : linear-gradient, transition, border-radius, text-shadow
Compatibilité navigateurs : IE10+, Firefox16+, Chrome26+, Safari avec préfixe, Opera12.1+.

Problématique

Créer un menu qui en cas de survol des éléments s’élargit en coulissant pour procurer des informations complémentaires.

Résolution théorique

Un élément div conteneur va renfermer des éléments div, dont une partie seulement sera affichée par défaut. Le mot survol employé dans la problématique indique qu’il sera employé la pseudo-classe :hover. Lors du survol, l’élément conteneur sera élargi, de même que l’élément enfant concerné, afin d’afficher tout le contenu. Pour ne pas afficher le contenu lorsque la largeur est insuffisante, la propriété overflow sera fixée à hidden.

Résolution pratique

Le code HTML est composé d’un élément div conteneur qui renferme le contenu (quelconque, mais ici un élément img suivi d’un élément p renfermant du texte).
<div class="menu"> <div><img src="adresse_image1"> <P>Texte explicatif 1</P> </div> … <div><img src="adresse_imagen"> <P>Texte explicatif n</P> </div> </div>
Remarquez qu’en toute logique, comme il s’agit d’un menu, le premier élément (ici l’image) devrait être placé dans une ancre a pour pointer vers une autre page… La structure serait alors :
<div><A url="adresse de la page"> <img src="adresse_image"> <P>Texte explicatif</P> </A> </div>
Cela ne change toutefois rien à ce qui suit.
Comme d’habitude, le code CSS commence par définir les propriétés de l’élément conteneur :
div.menu{ position:relative; width:290px; height:60px; margin:60px auto; border: 1px solid grey; border-radius:5px; overflow:hidden; background:linear-gradient( to left, white, black); transition:all .8s ease .25s; }
La plupart de ces propriétés sont uniquement esthétiques, ou dépendent des caractéristiques du menu : nous reviendrons plus loin sur la largeur. Sont importantes ici la déclaration overflow :hidden et la définition d’un effet de transition lors de la modification de largeur. Vient ensuite l’élément div qui renfermera le contenu individuel de chaque élément de menu. Les propriétés de bordure et de fond sont purement esthétiques. L’élément est déclaré comme flottant à gauche, et ses dimensions sont (au début !) exactement celles de l’image qui devra être affichée seule. Comme pour l’élément précédent, la propriété overflow est fixée à hidden et il est défini un effet de transition lors de la modification de largeur.
.menu div{ float:left; width:50px; height:50px; margin:3px; border: 1px solid black; border-radius:5px; background:#bdc7d0; overflow:hidden; background:linear-gradient( to left, white, black); transition:all 1s ease 0.1s; }
Les éléments img et p n’offrent rien de particulier, si ce n’est qu’ils sont définis avec une position absolue comme blocs en ligne. En outre, l’élément p est décalé vers le haut pour afficher correctement son texte et un espacement de ligne important permet de bien masquer le texte.
.menu div img { position:relative; display:inline-block; width :50px; height:50px; border: 1px solid black; border-radius: 5px; } .menu div P{ position:relative; display:inline-block; top : -22px; line-heght:3rem; padding-left: 5px; color: white; font-size:.8rem; text-shadow: black 0.1em 0.1em 0.2em; }

Menu à coulisse

Il faut maintenant gérer les modifications à apporter à la largeur tant d’un élément individuel qu’à celle du conteneur, lorsqu’un élément de menu est survolé par le pointeur :
.menu div:hover{width:320px;} .menu:hover{width:560px;}
Nous avions dit que nous reviendrions sur la largeur de l’élément conteneur. En effet, la détermination de ses différentes largeurs demande un peu de calcul.

Menu à coulisse

Variante

Une variante intéressante peut être obtenue à l’aide du modèle CSS3 de boîte coulissante (flexbox). Ce modèle va avoir pour effet de simplifier quelque peu le code, et surtout d’éviter le fastidieux calcul de la largeur de l’élément conteneur en fonction de celle des enfants : ceux-ci seront en effet automatiquement ajustés en fonction de l’élément conteneur. Le squelette HTML reste parfaitement identique. Dans le code CSS, nous ajoutons dans la définition de l’élément div.menu les instructions display: flex; pour activer le modèle de boîte flexible et flex-wrap:nowrap; pour interdire tout retour à la ligne des enfants, ainsi que l’instruction justify-content: baseline; pour aligner en haut ces éléments enfants. Nous éliminons l’instruction overflow et modifions l’instruction transition de façon à l’appliquer à toutes les modifications, et non seulement à un élargissement :
div.menu{ display: flex; flex-wrap:nowrap; justify-content: baseline; … transition:all .8s ease .25s; }
Pour l’élément div enfant du menu, nous supprimons l’instruction float :left ainsi que la définition de la largeur, pour les remplacer par l’instruction flex:1; qui signifie que chaque enfant occupera automatiquement le même pourcentage de la largeur disponible, soit 100% divisé par le nombre d’enfants. L’instruction transition est également modifiée.
.menu div{ flex:1; … transition:all 1s ease 0.1s; }
Les définitions CSS des petits-enfants img et p restent inchangées.
Enfin, nous modifions la définition en cas de survol d’un enfant div, en affectant un coefficient flex de 15 : une largeur quinze fois supérieure à celle de tout autre élément. Nous conservons l’augmentation de taille générale du menu.
.menu div:hover{flex:15;} .menu:hover{width:560px;}
Remarquez qu’il serait possible avec ce modèle de s’affranchir de cette dernière déclaration, en définissant dès le départ une largeur de menu suffisante pour afficher le texte de chaque bouton. Le survol aurait alors pour effet de redimensionner dynamiquement les largeurs des différents éléments. Remarquez également que ce menu ressemble fortement au menu de cette page : c'est en effet cette technique que j'ai appliquée à mon propre site.

Menu à coulisse (modèle flexbox)


Retour Accueil CSS

© 1999-2014 Fabrice "Fyndhorn Elder" Lemainque