Vous êtes ici > CSS Débutant | Tutoriels CSS | Menu horizontal déroulant

Un menu horizontal, c'est bien... Un menu horizontal qui déroule, c'est mieux !... Oh enfin, mieux... Ça dépend des goûts et des besoins. Mais ça peut être utile.

Comme précédemment, le menu sera fait sous forme d'une liste à puces que l'on va contraindre à devenir horizontale, mais ce sera, en plus, une liste à puces imbriquée qui va donc être démasquée par rollover.

Menu horizontal déroulant en CSS

Fonctionne avec :

  • Firefox 3
  • IE 7
  • SeaMonkey
  • Opéra 9
  • Safari 3
  • Camino 1.6

Attributs utilisés :

  • background-color
  • color
  • display
  • float
  • height
  • list-style-type
  • padding
  • position
  • margin
  • text-align, text-decoration
  • width

Note importante

Comme indiqué ci-dessus, cette technique, basée uniquement sur des propriétés CSS (notamment la pseudo-classe :hover), ne fonctionnera que sur des navigateurs récents. Pour obtenir un menu déroulant avec des navigateurs plus anciens, comme IE6 par exemple, il faudra rajouter une « couche » de javascript.
D'un point de vue ergonomie/accessibilité, si ce menu est accessible avec un lecteur d'écran, il ne pourra par contre pas se dérouler avec une navigation clavier. Aussi, là encore, un script javascript sera nécessaire.

Code (x)html

<div id="menu">
<ul>
  <li><a href="#">Item 1</a></li>
  <li><a href="#">Item 2</a>
    <ul>
      <li><a href="#">Sous-item 1</a></li>
      <li><a href="#">Sous-item 2</a></li>
      <li><a href="#">Sous-item 3</a></li>
    </ul>
  </li>
  <li><a href="#">Item 3</a></li>
</ul>
</div>

Code CSS

Dans un premier temps, on transforme donc cette liste à puces verticale en une liste horizontale. Je ne reviens pas sur les détails, le principe a déjà été expliqué dans le tuto menu horizontal. Ici chaque item occupera une largeur de 100 pixels, aura un fond noir, et l'écriture blanche deviendra jaune au survol de la souris.

#menu ul {
 margin:0;
 padding:0;
 list-style-type:none;
 text-align:center;
 }
#menu li {
 float:left;
 margin:auto;
 padding:0;
 background-color:black;
 }
#menu li a {
 display:block;
 width:100px;
 color:white;
 text-decoration:none;
 padding:5px;
 }
#menu li a:hover {
 color:#FFD700;
 }

A ce stade, le résultat est le suivant :

Sous-items 1, 2 et 3 en ligne surmontés des items 1,2 et 3

Pour faire disparaître les sous-items, on rajoute un display:none à la sous-liste (on lit en remontant : le ul inclus dans le li du ul du cadre id="menu") :

#menu ul li ul {
 display:none;
 }

Et hop, sous-items disparus !

Il faut maintenant réaliser deux choses :

  • Remettre en vertical le sous menu (car pour l'instant, il est toujours horizontal, vu qu'il a hérité des propriétés de la liste principale)
  • Faire en sorte qu'au survol de l'item 2, les sous-items se déroulent.

Pour le comportement au survol, on utilise la pseudo-classe :hover sur le li de la liste principale, auquel on va attribuer un display:block qui va contrarier le display:none précédemment déclaré.
Et pour perdre la disposition en ligne qui était due au float:left, on va tout simplement déclarer un float:none

#menu ul li:hover ul {
 display:block;
 }
#menu li:hover ul li {
 float:none;
 }

Reste un tout petit problème : en se déroulant, la sous liste occupe son espace, tout ce qui est en dessous se trouve donc décalé vers le bas. Pour éviter ce désagrément, il faut attribuer une position:absolute à la sous liste. Elle viendra se superposer aux éléments situés en dessous, et non plus les faire "sauter".

#menu li ul {
 position:absolute;
 }
Internet Explorer 7

Ca vous étonnait qu'on ne parle pas de lui, hein ? Bien évidemment, IE7 ne fait rien comme tout le monde, et la position:absolute décrite ci-dessus peut donner des résultats inattendus. En fait IE7 n'a pas besoin d'une position absolue si la hauteur du menu a été déclarée. On peut donc rajouter ceci à la feuille de style :

#menu {
 height:50px;
 }

Et mettre la déclaration de la position absolue dans un commentaire conditionnel, qui exclura IE, entre les balises d'en-tête <head></head>.

<!--[if !IE]> <-->
<style type="text/CSS">
#menu li ul {
 position:absolute;
 }
</style>
<!--><![endif]-->

[Edit Mai 2009]

Mais avec l'arrivée d'IE8, ça se complique. En effet, pour cette partie IE8 se comporte "normalement", donc ce test conditionnel pose problème... On peut donc rajouter cette rustine :

<!--[if IE 8]>
<style type="text/CSS">
#menu li ul {
 position:absolute;
 }
</style>
<![endif]--> 
Remarque

Vu que ce menu ne fonctionne qu'avec des navigateurs récents, il convient bien entendu de mettre un vrai lien sur l'item survolé, afin que le navigation ne perde rien en cas de non fonctionnement du déroulement du menu. C'est une règle à appliquer aussi si on met une surcouche javascript. Simple histoire de bon sens...

Résultat attendu

Tester le résultat

précédent suivant

Haut

Contact : pascale at mammouthland.net

Creative Commons License

En cas de reproduction (partielle ou totale) de cet article, prière de faire un lien vers la page originale : http://css.mammouthland.net/menu-horizontal-deroulant-en-css.php