CSS: menu avec liste et image de fond qui change
29.05.2008 Tags: css,tutoriel,English version available here! Cette technique fonctionne avec tous les navigateurs (oui, même IE 6).Imaginons une liste avec un fond qui change lors du passage de la souris. Le désavantage par rapport à un système de type:
li a {
background: url(fond.png) left top no-repeat;
}
li a:hover {
background: url(fond-hover.png) left top no-repeat;
}
est que l'image de fond fond-hover.png n'est chargée que lors du premier passage de souris sur l'élément liste et non au chargement de la page, provoquant un petit lag dans l'affichage.
La solution? Soit charger toutes les images au chargement de la page avec du JavaScript par exemple, soit créer une seule grande image incluant l'élément fond.png et fond-hover.png, pour ensuite la 'déplacer' selon que l'on passe la souris sur l'élément liste ou pas. C'est ce que nous allons voir dans cet article.
Supposons que nous voulons une liste horizontale à 3 éléments, avec un fond différent pour chaque élément de la liste. Par exemple ceci: Exemple. Tout d'abord, il faut créer notre image de fond complète:

(je sais ce n'est pas du grand art, mais on va faire avec).
Nous avons besoin de savoir la taille de l'image (ici 322 x 123) ainsi que la taille d'un des blocs (~107 x ~62).
Passons au CSS et faisons notre bloc menu:
#menu {
height: 62px;
background: url(hover-list-final.png) left top no-repeat;
}
Sa hauteur est égale à la hauteur d'un des blocs.
En ce qui concerne la liste, elle se présente ainsi:
#menu ul, #menu li {
margin:0;
padding: 0;
list-style-type: none;
}
#menu ul {
position: absolute;
height: 62px;
width: 322px;
}
#menu li {
float: left;
}
Pas de marge ni de padding, pas de style de liste.
Elle a une hauteur égale à la hauteur d'un des blocs et une largeur égale à la largeur de l'image de fond.
Afin d'avoir une liste horizontale, les éléments li doivent être en float: left;
Au tour des différents liens:
#menu li a {
display: block;
height: 62px;
width: 107px;
color: #769712; //couleur du texte
text-decoration: none;
text-align: center;
}
#menu a:hover {
color: #fff;
background: transparent url(hover-list-final.png) top left no-repeat;
}
Dans cette partie, les éléments importants sont le display:block, height et width. Le lien aura donc la dimension d'un des blocs. Le reste n'est là que pour le style du texte (couleur, lien souligné ou pas, etc...).
Nous définissions ensuite l'image de fond pour le survol des liens. L'image entière est d'abord déclarée pour le a:hover, puis nous allons créer des blocs pour chaque zone, délimitée par les éléments de la liste et leur taille.
#menu a#menu1, #menu a#menu2, #menu a#menu3 {
display: block;
width: 107px;
}
Et pour finir, nous devons définir une classe pour chaque élément créé précédemment, en indiquant quelle partie de l'image de fond nous allons afficher lors du survol de la souris.
#menu a#menu1:hover {
background-position: 0px -62px;
}
#menu a#menu2:hover {
background-position: -107px -62px;
}
#menu a#menu3:hover {
background-position: -214px -62px;
}
Le code CSS en entier:
#menu {
height: 62px;
background: url(hover-list-final.png) left top no-repeat;
}
#menu ul, #menu li {
margin:0;
padding: 0;
list-style-type: none;
}
#menu ul {
position: absolute;
height: 62px;
width: 322px;
}
#menu li {
float: left;
}
#menu li a {
display: block;
height: 62px;
width: 107px;
color: #769712; //couleur du texte
text-decoration: none;
text-align: center;
}
#menu a:hover {
color: #fff;
background: transparent url(hover-list-final.png) top left no-repeat;
}
#menu a#menu1, #menu a#menu2, #menu a#menu3 {
display: block;
width: 107px;
}
#menu a#menu1:hover {
background-position: 0px -62px;
}
#menu a#menu2:hover {
background-position: -107px -62px;
}
#menu a#menu3:hover {
background-position: -214px -62px;
}
et dans notre page, nous aurons
<div id="menu">
<ul>
<li><a id="menu1" href="#">titi</a></li>
<li><a id="menu2" href="#">titi</a></li>
<li><a id="menu3" href="#">titi</a></li>
</ul>
</div>
Il est également possible d'avoir des blocs de largeurs différentes. Pour celà, il suffit d'indiquer la largeur de chaque bloc
#menu a#menu1 {
display: block;
width: AAApx;
}
#menu a#menu2 {
display: block;
width: BBBpx;
}
#menu a#menu3 {
display: block;
width: CCCpx;
}
#menu a#menu4 {
display: block;
width: DDDpx;
}
#menu a#menu5 {
display: block;
width: EEEpx;
}
et de modifier les coordonnées de l'image de fond à afficher en conséquence
#menu a#menu1:hover {
background-position: 0px -62px;
}
#menu a#menu2:hover {
background-position: AAA-BBBpx -62px;
}
#menu a#menu3:hover {
background-position: AAA-BBB-CCCpx -62px;
}
#menu a#menu4:hover {
background-position: AAA-BBB-CCC-DDDpx -62px;
}
#menu a#menu5:hover {
background-position: AAA-BBB-CCC-DDD-EEEpx -62px;
}
Il est évidemment possible d'avoir des blocs de hauteurs différentes (pour des menus verticaux). Même méthode que précédemment =)




