Menu
déroulant
en CSS
Menu hiérarchique vertical ou horizontal
sans javascript
Le confort de navigation est l'un des éléments majeurs du succès d'un site. Vos visiteurs doivent toujours savoir où ils sont et quel contenu vous leur proposez. Les menus hiérarchiques sont un excellent moyen d'atteindre ce but et les CSS permettent de les réaliser avec un petit code élégant et efficace.
Si vous voulez avoir tout de suite un aperçu du type de menu décrit dans cette page, vous pouvez visiter notre page de démonstration.
Et pour garder le script proposé au chaud sur votre PC, vous pouvez aussi le télécharger.
Dans cette page
Éviter les décalages verticaux
Rendre le code compatible avec
Internet Explorer 6
Sélection de liens concernant
les menus déroulants en CSS
Ces liens pointent vers des pages dont les contenus complètent notre article.
Des menus déroulants
en CSS compatibles avec tous les navigateurs
Cet auteur utilise le script
csshover.htc
pour ajouter à IE6 la possibilité de gérer la
propriété "hover" sur les balises <li>. Nous lui
avons préféré le petit script proposé au
bas de notre page.
Un menu déroulant
en CSS et XHTML
Alsacréations propose une version de code utilisant le
javascript pour tous les navigateurs. Nous préférons
limiter l'usage de ce langage au strict nécessaire.
Un menu déroulant
sans javascript
Marcerea fait l'impasse sur le navigateur IE6 et propose en
conséquence un menu déroulant sans une ligne de
javascript.
Un menu déroulant
sans javascript
compatible avec IE6
Stu Nicholls a démontré que la chose était
possible en exploitant une particularité un peu bizarre d'IE6 :
avec ce navigateur, les balises <A> peuvent englober des balises
<UL> et <LI> (ce qui n'est pas conforme aux normes HTML).
Grâce à des commentaires conditionnels, Stu parvient
même à faire un code qui passe le contrôle du
testeur W3C.
Bel exercice de style, mais le code produit est hélas très volumineux.
Menus déroulants contre liens hypertextes : la victoire de la simplicité
Vincent Benard dit tout le mal qu'il pense des menus déroulants.
La plupart des reproches qu'il leur adresse peut être
corrigée par une bonne conception de ces menus. Voilà
pourquoi il est important de lire cet article et d'en tenir compte pour
votre site.
Un menu déroulant
accessible
Trés bel exemple de menu réalisé par FairyTells.
Ce code - hélas un peu complexe - gère la navigation au
clavier et propose même un petit délai de "latence" pour
faciliter l'utilisation du menu par les personnes victimes de
tremblements. Du grand art.
La vengeance des menus déroulants
Dans
sa dernière version, le code proposé par les américains Patrick
Griffiths et Dan Webb présente de très fortes similarités avec le notre
(preuve que les grands esprits se rencontrent ?). Simple, efficace,
compatible avec tous les navigateurs et n'utilisant le javascript que
pour IE6 à travers un code économique en taille et en ressources.
Un menu semi-transparent
Pour donner un look un peu plus "fun" à votre menu, voici comment procéder.
Le script qui a servi de base à cette adaptation semble être celui de Patrick
Griffiths et Dan Webb (voir paragraphe précédent sur "la vengeance des menus déroulants")
Avec ou sans javascript ?
Lorsqu'on peut se passer de javascript, il est prudent de le faire. Certains internautes désactivent en effet l'exécution du javascript et pourraient se retrouver dans l'impossibilité de naviguer sur un site utilisant ce langage dans sa gestion de menu.
Les principes utilisés pour créer les menus hiérarchiques sont malheureusement incompatibles avec Internet Explorer versions 6 et antérieures. Seul le langage javascript permet de dépasser cette limitation.
Notre choix a consisté à mettre au point un menu à 2 vitesses qui fonctionne :
- Sans javascript pour Firefox, Opera, Mozilla et IE7
- Avec javascript pour IE 5.5 et 6
Ce choix permet à notre menu de rester pleinement opérationnel pour la quasi-totalité des visiteurs.
Une partie de cache-cache
En réfléchissant au principe de base d'un menu déroulant, vous constaterez qu'il s'agit essentiellement d'une partie de cache-cache : certaines parties en sont masquées et n'apparaissent que lorsque l'utilisateur survole le menu principal.
Dans le cas d'un menu hiérarchique à 3 niveaux, le troisième niveau n'apparaît que lorsque l'utilisateur survole certaines lignes de deuxième niveau.
Pour obtenir ce résultat, il faut donc maîtriser deux techniques :
Comment faire apparaître et disparaître des éléments- On utilisera pour cela la propriété display qui peut recevoir (entre autre) les valeurs none (bloc masqué) et block (bloc affiché).
Comment déclencher un événement lorsque le curseur de la souris
survole une élément.- On utilisera pour cela la propriété hover qui permet d'associer un style CSS à un bloc survolé.
Ajoutons à cet inventaire le fait qu'un menu est un ensemble de lignes qu'il va falloir structurer dans le code HTML. Puisqu'il s'agit d'une liste de liens, il semble logique d'utiliser la structure "<LIST>" et c'est ce qui est fait dans la quasi-totalité des exemples que vous pourrez trouver sur le Web.
Voici donc ce que donnerait notre exemple si on le structure avec cette balise :
<ul
class="niveau1">
<li>
Menu
<ul class="niveau2">
<li>
Extras
<ul
class="niveau3">
<li>Demander la note</li>
<li>Draguer la
serveuse</li>
</ul>
</li>
<li>Entrée</li>
<li>Plat</li>
<li>Dessert</li>
<li>Café</li>
</ul>
</li>
</ul> Le niveau 2 et le niveau 3 doit être invisibles en temps normal et ne devenir visibles que lors du survol des niveaux précédents. Voici comment obtenir ce résultat avec des CSS :
ul ul {display:
none;}
li:hover ul.niveau2,
li li:hover ul.niveau3
{display:block;}Pour que cet exemple fonctionne, vous devez visualiser cette page avec FireFox, Mozilla, Opera ou Internet Explorer 7, mais nous verrons plus bas comment rendre cet exemple compatible avec Internet Explorer 6 :
Voici les explications concernant ce code :
ul ul {display:none;} : lorsqu'une balise <ul> se trouve enchâssée dans une autre balise <ul>, elle ne sera pas affichée.
Ce code rend invisible le bloc <ul class="niveau2"> (qui est enchâssé dans <ul class="niveau1">) ainsi que le bloc <ul class="niveau3"> (qui est enchâssé dans <ul class="niveau1"> et <ul class="niveau2">)
li:hover ul.niveau2, li li:hover ul.niveau3 {display:block;} : l'expression <li:hover> signifie "quand <li> est survolé par la souris".
- Lorsqu'une balise <ul> ayant la classe "niveau2" se trouve enchâssée dans une balise <li> survolée par la souris, elle sera affichée.
- Lorsqu'une balise <ul> ayant la classe "niveau3" se trouve enchâssée dans une balise <li> survolée par la souris, elle-même enchâssée dans une autre balise <li>, elle sera affichée.
Éviter les décalages verticaux
En survolant le menu proposé au paragraphe précédent, on constate que son affichage n'est pas des plus agréable : lorsque la souris survole "Extras", les lignes "Entrée", "Plat", "Dessert" et "Café" se décale vers le bas pour laisser la place au bloc "niveau3".Nous allons donc modifier les styles comme suit :
ul ul {display:
none; position: absolute; left: 140px; top: 0px; margin: 0px; padding:
0px;}
li
{list-style-type: none; position: relative; width: 140px;
background-color: #E0E0E0}
li:hover ul.niveau2, li
li:hover ul.niveau3 {display: block}Les blocs <UL> de niveaux 2 et 3 sont désormais positionnés en absolu et ne modifie plus le flux de la page, c'est à dire qu'ils ne décalent plus le reste du menu vers le bas.
Les blocs <LI> sont positionnés en relatif afin de servir de repère aux blocs <UL> qu'ils contiennent. On a également attribué un fond gris à ces blocs afin de commencer à travailler sur l'esthétique de notre menu.
Améliorer la présentation
Les modifications qui suivent concernent uniquement l'esthétique :
<style
type="text/css">
ul
ul {display: none; position: absolute; left: 144px; top:
-1px; margin:0px; padding: 0px; border: 1px solid grey;}
li
{list-style-type: none; position: relative; width: 140px;
background-color: #E0E0E0; padding: 2px; margin: 0px}
li:hover
{background-color:
#FFFF70;}
li:hover
ul.niveau2, li li:hover
ul.niveau3 {display: block}
li.plus
{background-position:right; background-image:
url(illustrations/fdroite.gif); background-repeat: no-repeat;
border-bottom: 1px solid grey;}
</style>
HTML<ul
class="niveau1">
<li>
Menu
<ul class="niveau2">
<li class="plus">
Extras
<ul
class="niveau3">
<li>Demander la note</li>
<li>Draguer la
serveuse</li>
</ul>
</li>
<li>Entrée</li>
<li>Plat</li>
<li>Dessert</li>
<li>Café</li>
</ul>
</li>
</ul>
Rendre le code compatible avec Internet Explorer 6
Le problème d'IE 6 et de ses versions précédentes est la non-reconnaissance de la propriété hover sur les blocs de type <LI>.
Nous allons donc créer une petite fonction javascript qui ajoute cette fonctionnalité à IE 6 et qui ne sera utilisée que par lui .
Cette fonction attribue la classe sfhover aux blocs <LI> lorsqu'ils sont survolés par la souris :
<!--[if lt IE
7]>
<script type="text/javascript">
// Fonction destinée à remplacer le "LI:hover"
pour IE 6
sfHover =
function() {
var sfEls =
document.getElementsByTagName("li");
for (var i=0;
i<sfEls.length; i++) {
sfEls[i].onmouseover = function() {
this.className = this.className.replace(new RegExp(" sfhover"), "");
this.className += " sfhover";
}
sfEls[i].onmouseout = function() {
this.className = this.className.replace(new RegExp(" sfhover"), "");
}
}
}
if (window.attachEvent) window.attachEvent("onload", sfHover);
</script>
<style type="text/css">
li {width: 144px;}
</style>
<![endif]--> Pour exploiter cette fonction, les styles CSS devront être modifiées comme suit :
<style
type="text/css">
ul
ul {display: none; position: absolute; left: 144px; top:
-1px; margin:0px; padding: 0px; border: 1px solid #B0B0B0;}
li
{list-style-type: none; position: relative; width: 140px;
background-color: #E0E0E0; padding: 2px; margin: 0px}
li:hover,
li.sfhover {background-color:
#FFFF70;}
li:hover
ul.niveau2, li li:hover
ul.niveau3, li.sfhover
ul.niveau2, li li.sfhover
ul.niveau3 {display: block}
li.plus
{background-position:right; background-image:
url(illustrations/fdroite.gif); background-repeat: no-repeat;
border-bottom: 1px solid #B0B0B0;}
</style>
Cliquer ici pour voir le résultat
Derniers petits ajustements
Tels que nous les avons rédigés dans les exemples précédents, les styles CSS s'appliquent à toutes les listes (balises <ul> et <li>) de la page. Cela peut être ennuyeux si on utilise d'autres listes à d'autres fin que la gestion du menu dans la même page.
Nous allons donc inclure l'ensemble du menu dans un bloc <div> auquel nous allons attribuer un "ID". Cela permettra de restreindre l'influence de nos styles CSS à ce bloc.
Le code complet proposé ci-dessous intègre ces modifications ainsi que quelques derniers ajustements esthétiques :
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<style type="text/css">
#monmenu {font-family: trebuchet
ms, arial, tahoma, verdana, sans-serif; font-size: 90%; font-weight:bold;}
#monmenu ul ul {display: none; left: 144px; top: -1px; position: absolute; margin:0px; padding: 0px; border: 1px solid #B0B0B0;}
#monmenu li {list-style-type: none; position:
relative; width: 140px; background-color: #E0E0E0; padding: 2px;
margin: 0px}
#monmenu li:hover, #monmenu li.sfhover {background-color: #FFFF70;}
#monmenu li a {text-decoration:none;}
#monmenu li:hover ul.niveau2, #monmenu li li:hover
ul.niveau3, #monmenu li.sfhover ul.niveau2, #monmenu li li.sfhover
ul.niveau3 {display: block}
#monmenu li.plus {background-position:right; background-image:
url(illustrations/ fdroite.gif); background-repeat: no-repeat;
border-bottom: 1px solid #B0B0B0;}
</style>
<!--[if lt IE 7]>
<script type="text/javascript">
// Fonction destinée à remplacer le "LI:hover" pour IE 6
sfHover = function() {
var sfEls =
document.getElementById("monmenu").getElementsByTagName("li");
for (var i=0; i<sfEls.length; i++) {
sfEls[i].onmouseover = function() {
this.className =
this.className.replace(new RegExp(" sfhover"), "");
this.className += " sfhover";
}
sfEls[i].onmouseout = function() {
this.className =
this.className.replace(new RegExp(" sfhover"), "");
}
}
}
if (window.attachEvent) window.attachEvent("onload", sfHover);
</script>
<style type="text/css">
#monmenu li {width: 144px;}
</style>
<![endif]-->
<meta name="keywords"
content="CSS, cascading style sheets, mise en page, design, site, web, techniques, sites, webmaster, page">
<meta name="description"
content="Voici un exemple de code de menu hiérarchique
déroulant réalisé à l'aide de CSS.">
<title>Exemple de menu hiérarchique en CSS</title>
</head>
<body>
<div id="monmenu">
<ul class="niveau1">
<li> Menu
<ul class="niveau2">
<li class="plus">
<a href= "http://www.rankspirit.com">
<img alt="
" src="illustrations/ menu-deroulant/ bebe.gif" align="top"
border="none">
Extras
</a>
<ul class="niveau3">
<li>
<a
href= "http://www.rankspirit.com">
<img alt="
" src="illustrations/ menu-deroulant/ note.gif" align="top"
border="none">
Demander la note
</a>
</li>
<li>
<a
href= "http://www.rankspirit.com">
<img alt=" "
src="illustrations/ menu-deroulant/ serveuse.gif" align="top"
border="none"> Draguer la serveuse
</a>
</li>
</ul>
</li>
<li>
<a
href= "http://www.rankspirit.com">
<img alt=" "
src="illustrations/ menu-deroulant/ entree.gif" align="top"
border="none">
Entrée
</a>
</li>
<li>
<a
href= "http://www.rankspirit.com">
<img alt=" "
src="illustrations/ menu-deroulant/ plat.gif" align="top"
border="none">
Plat
</a>
</li>
<li>
<a
href= "http://www.rankspirit.com">
<img alt=" "
src="illustrations/ menu-deroulant/ dessert.gif" align="top"
border="none">
Dessert
</a>
</li>
<li>
<a
href= "http://www.rankspirit.com">
<img alt=" "
src="illustrations/ menu-deroulant/ cafe.gif" align="top"
border="none"> Café
</a>
</li>
</ul>
</li>
</ul>
</div>
</body>
</html>
Version modifiée pour un menu vertical
Notre code ne nécessite qu'un infime ajustement pour afficher un menu vertical.
La ligne :
#monmenu ul ul {display: none; left: 144px; top: -1px; position: absolute; margin:0px; padding: 0px; border: 1px solid #B0B0B0;} devient :
#monmenu ul ul {display: none; position: absolute;
margin:0px; padding: 0px; border: 1px solid #B0B0B0;}
#monmenu ul.niveau2 {left: 0px; top: 22px;}
#monmenu ul.niveau3 {left: 144px; top: -1px;}
Accueil
Recherche
Page précédente
Haut






Premiers pas
Héritages
Eléments "blocs"
Mise en page
Faire des tableaux
Pseudo-frames
Menu déroulant
Styles alternatifs
10 trucs à savoir
Toutes les propriétés CSS
Couleurs CSS
Classement par familles
Réflexions et prises de tête
Les fausses promesses
Tableaux contre CSS : le combat
Les ayatollahs