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:
11
px 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:
644
px;
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.
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. En passant on règle un problème relatif à Internet Explorer 7 en ajoutant une hauteur de 1% à nos 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:
1
%;
color:
#FFF
;
background:
#3B4E77
;
margin:
0
;
padding:
4
px 8
px;
border-right:
1
px 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:
149
px;
border-top:
1
px solid
transparent
;
border-right:
1
px 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
;
}
Pour éviter un décalage du contenu lorsque le menu est déroulé▲
Le menu dispose d'une position statique par défaut. En l'état, à chaque fois qu'il sera déroulé, il décalera tout le contenu déclaré après le menu dans le code (X)HTML. Pour y remédier, nous allons lui donner une position absolue :
Le résultat▲
Voir le résultat en ligne dans une nouvelle fenêtre.