Des menus déroulants grâce aux CSS
Date de publication : 01/06/2004 , Date de mise à jour : 18/02/2007
Par
Marc Hertzog
Objectif : réaliser un menu déroulant XHTML + CSS (sans javascript)
avec fonds transparents.
Inconvénients : seuls quelques navigateurs récents (Mozilla/Firebird,
Safari) seront capables de rendre ce menu correctement. En contre-partie,
comme IE Windows n'affichera pas les sous-menu, il y a possibilité
d'utiliser des PNG avec transparence alpha.
La structure
Le style
Le Menu Magique
Le résultat
La structure
La première étape consiste à définir la structure de notre menu.
Dans mon cas, je vais faire simple pour ce premier essai et faire
un seul sous niveau. On aura donc le premier niveau visible, et
un sous-niveau déroulant.
Je vais commencer par le menu principal avec une liste non-ordonnée
qui commence par un élément <ul>. Chaque item de
cette liste de premier niveau démarre par un élément <li>
et contient des liens <a> vers les rubriques de tout
premier niveau. Ces liens sont importants pour les navigateurs
qui n'afficheront pas les menus-déroulants :
<ul>
<li><a href="#">Partie 1</a></li>
<li><a href="#">Partie 2 </a></li>
<li><a href="#">Partie 3</a></li>
<li><a href="#">Partie 4</a></li>
</ul>
|
J'enchaîne en imbriquant des sous-niveaux. Dans la structure du
code, ça va se traduire par une autre liste dans chaque item
<li> de ma première liste :
<ul>
<li>
<a href="#">Partie 1</a>
<ul>
<li><a href="#">castor</a></li>
<li><a href="#">aligator</a></li>
<li><a href="#">musclor</a></li>
</ul>
</li>
<li>
<a href="#">Partie 2</a>
<ul>
<li><a href="#">whisky</a></li>
<li><a href="#">vodka</a></li>
<li><a href="#">gin</a></li>
<li><a href="#">vin</a></li>
<li><a href="#">champagne</a></li>
</ul>
</li>
<li>
<a href="#">Partie 3</a>
<ul>
<li><a href="#">pommes</a></li>
<li><a href="#">poires</a></li>
<li><a href="#">ananas</a></li>
<li><a href="#">pamplemousse</a></li>
<li><a href="#">banane</a></li>
<li><a href="#">raisins</a></li>
<li><a href="#">framboises</a></li>
<li><a href="#">fraises</a></li>
<li><a href="#">mirabelles</a></li>
<li><a href="#">groseilles</a></li>
</ul>
</li>
<li>
<a href="#">Partie 4</a>
<ul>
<li><a href="#">tomates</a></li>
<li><a href="#">haricots</a></li>
<li><a href="#">carrottes</a></li>
<li><a href="#">choux</a></li>
<li><a href="#">concombres</a></li>
<li><a href="#">courgettes</a></li>
<li><a href="#">endives</a></li>
<li><a href="#">navets</a></li>
<li><a href="#">epinards</a></li>
<li><a href="#">avocat</a></li>
</ul>
</li>
</ul>
|
Avant de commencer à mettre du style, je vais donner des
identifiants et des classes à mes éléments pour
pouvoir y accéder sans ambiguïté via ma feuille de style CSS.
Comme mon menu de navigation va être unique sur ma page,
je peux me permettre de donner un identifiant id unique à
l'élément <ul> de premier niveau. Par contre je vais
styler tous mes sous menu de la même façon. Je vais donc devoir
leur affecter une même classe, pas d'id car ce dernier
doit-être unique. Si je ne différencie pas mes sous-niveaux avec
des classes, ils vont hériter de certaines propriétés de leur(s)
élément(s) parent(s) dans l'arbre du document. Au final, on a le
code suivant :
<ul id="menuDeroulant">
<li>
<a href="#">Partie 1</a>
<ul class="sousMenu">
<li><a href="#">castor</a></li>
<li><a href="#">aligator</a></li>
<li><a href="#">musclor</a></li>
</ul>
</li>
<li>
<a href="#">Partie 2</a>
<ul class="sousMenu">
<li><a href="#">whisky</a></li>
<li><a href="#">vodka</a></li>
<li><a href="#">gin</a></li>
<li><a href="#">vin</a></li>
<li><a href="#">champagne</a></li>
</ul>
</li>
[...]
</ul>
|
Le style
A partir de maintenant, tout se passe dans la feuille de style.
Pour cet exemple je vais définir la taille des caractères
directement sur body histoire de ne pas alourdir le reste du
code. Je vais définir la taille de mon texte en pixels (oui, je
sais qu'il y a mieux comme unité). Pour bien voir la future
transparence de mes sous-menus, je vais mettre une image de fond
sur la page. Finalement, pour que ma page colle aux bords de la
fenêtre du navigateur, je donne 0 comme valeur aux propriétés
margin et padding de <body> :
body
{
font: 11px verdana, sans-serif;
background: #AFA99B url("fond.jpg") top left no-repeat;
margin: 0;
padding: 0;
}
|
Ensuite, on s'occupe du style des listes.
Il faut que ma liste principale s'affiche de façon horizontale
et ne présente pas de puces comme elle le fait par défaut, et
que ses items <li> soient alignées horizontalement.
Il y a deux méthodes répandues pour faire ça : utiliser
display: inline ou faire flotter les éléments
<li>. Chaque méthode a ses avantages et ses
inconvénients. J'ai choisi de faire flotter les éléments. Pour
cet exemple, comme l'image de fond que j'ai collé sur <body>
fait 644px, je donne une largeur de 644px à ma liste. Important
également, les bords, les marges et le remplissage à 0 pour
homogénéiser le rendu en fonction des différents navigateurs :
#menuDeroulant
{
width: 644px;
list-style-type: none;
margin: 0;
padding: 0;
border: 0;
}
#menuDeroulant li
{
float: left;
margin: 0;
padding: 0;
border: 0;
}
|
Occupons-nous de nos sous-menus. Commençons par empêcher
l'affichage des puces en utilisant list-style-type: none;
sur les éléments <ul> de nos sous-menus. Comme nous
avons fait flotter à gauche les éléments <li> parents de
nos sous-menus, ces derniers vont hériter de cette
propriété. Il faut que nous empêchions les éléments <li>
de notre sous-menu de flotter, pour cela on utilise float: none :
#menuDeroulant .sousMenu
{
list-style-type: none;
margin: 0;
padding: 0;
border: 0;
}
#menuDeroulant .sousMenu li
{
float: none;
margin: 0;
padding: 0;
border: 0;
}
|
Nous sommes maintenant confrontés à un problème si nous voulons
que notre menu ait une apparence correcte dans IE5 Mac.
Dans la majorité des navigateurs récents, lorsqu'un élément
flottant contient un autre élément, la largeur de l'élément
flottant conteneur est réduite à la largeur de son contenu.
Dans IE5 Mac, il y a un bug qui fait que lorsqu'un élément de
type block et de largeur automatique (width: auto)
est contenu dans un élément flottant, IE5 Mac fait prendre à cet
élément et à son conteneur flottant toute la largeur disponible
dans la fenêtre du navigateur.
Dans notre cas, les éléments conteneur flottants sont les éléments
<li> de notre liste de premier niveau. Les éléments
contenus de type block sont les éléments <li> de nos
listes de second niveau. Par défaut leur largeur est définie en
automatique si nous ne la spécifions pas.
La seule solution que j'ai trouvée à l'heure actuelle c'est de
donner une largeur explicite aux éléments <li> de notre
menu de premier niveau qui sera héritée par nos menus de second
niveaux.
#menuDeroulant li
{
float: left;
width: 150px;
margin: 0;
padding: 0;
border: 0;
}
|
Maintenant, je vais m'occuper de l'apparence du menu déroulant
en donnant du style aux liens contenus dans nos listes. Je vais
faire passer les éléments <a> de leur type inline
par défaut à un type block via display: block; et styler
les différents états des liens.
Pour donner un fond transparent, il faut créer dans un logiciel
de création d'image un rectangle de couleur uni avec un niveau
de transparence alpha à 60% par exemple et l'enregistrer au
format PNG. Puis je le place en tant qu'image de fond des liens
de nos sous-menus :
#menuDeroulant li a:link, #menuDeroulant li a:visited
{
display: block;
height: auto;
color: #FFF;
background: #3B4E77;
margin: 0;
padding: 4px 8px;
border-right: 1px solid #fff;
text-decoration: none;
}
#menuDeroulant li a:hover { background-color: #F2462E; }
#menuDeroulant li a:active { background-color: #5F879D; }
#menuDeroulant .sousMenu li a:link,
#menuDeroulant .sousMenu li a:visited
{
display: block;
color: #FFF;
margin: 0;
border: 0;
text-decoration: none;
background: transparent url("fondTR.png") repeat;
}
#menuDeroulant .sousMenu li a:hover
{
background-image: none;
background-color: #F2462E;
}
|
Pour plus de raffinement et dans l'esprit de la transparence,
nous pouvons donner un bord supérieur et un bord droit
transparents aux éléments <li> de nos sous-menus.
Comme nous ajoutons 1px de bord droit, il ne faut pas oublier de
redéfinir la taille de nos sous-menus en leur retranchant 1px,
car la largeur totale d'un élément = width + margin + border
+ padding :
#menuDeroulant .sousMenu li
{
float: none;
margin: 0;
padding: 0;
border: 0;
width: 149px;
border-top: 1px solid transparent;
border-right: 1px solid transparent;
}
|
Le Menu Magique
Nous allons maintenant profiter des avancées technologiques des
navigateurs récents alternatifs.
Masquons nos sous-menus avec display: none :
#menuDeroulant .sousMenu
{
display: none;
list-style-type: none;
margin: 0;
padding: 0;
border: 0;
}
|
Enfin, appliquons un état :hover à nos éléments <li>
de notre liste de premier niveau :
#menuDeroulant li:hover > .sousMenu { display: block; }
|
Le résultat
Voir le
résultat
en ligne dans une nouvelle fenêtre.
| (1) |
Cet article a été publié à l'origine sur le site de l'auteur et est
encore visible à l'adresse suivante : http://marcarea.com/tuto/menu01.php
|


Copyright © 2004 Marc Hertzog. Aucune reproduction, même partielle, ne peut être faite
de ce site et de l'ensemble de son contenu : textes, documents, images, etc
sans l'autorisation expresse de l'auteur.
Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E
de dommages et intérêts.
Cette page est déposée à la
SACD.