Menu d�roulant dans un site web by LauraLimem

VIEWS: 29 PAGES: 7

									                                 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.


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&eacute;e</li>
       <li>Plat</li>
       <li>Dessert</li>
       <li>Caf&eacute;</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;}

Survolez     le     menu    ci-dessous   pour      voir     le    résultat    de     ce     code.
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 :

         Menu

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}

Résultat :

       Menu

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 :

CSS
<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&eacute;e</li>
      <li>Plat</li>
      <li>Dessert</li>
      <li>Caf&eacute;</li>
    </ul>
  </li>
</ul>

Résultat :
    Menu



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>
<![endif]-->

Pour exploiter cette fonction, les styles CSS devront être modifiées comme suit :

CSS
<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, 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 grey;}
</style>
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 fins
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"
 border="none">
                         Extras
                      </a>
                      <ul class="niveau3">
                        <li>
                          <a href= "http://www.rankspirit.com">
                               <img alt=" " src="illustrations/ menu-deroulant/
note.gif"
 border="none">
                              Demander la note
                            </a>
                          </li>
                          <li>
                               <a href= "http://www.rankspirit.com">
                                   <img alt=" "
 src="illustrations/ menu-deroulant/ serveuse.gif"
 border="none">                    Draguer la serveuse
                               </a>
                          </li>
                      </ul>
                   </li>
                   <li>
                      <a href= "http://www.rankspirit.com">
                          <img alt=" "
 src="illustrations/ menu-deroulant/ entree.gif"
 border="none">
                          Entrée
                      </a>
                   </li>
                   <li>
                      <a href= "http://www.rankspirit.com">
                          <img alt=" "
 src="illustrations/ menu-deroulant/ plat.gif"
 border="none">
                          Plat
                      </a>
                   </li>
                   <li>
                       <a href= "http://www.rankspirit.com">
                          <img alt=" "
 src="illustrations/ menu-deroulant/ dessert.gif"
 border="none">
                          Dessert
                       </a>
                    </li>
                    <li>
                        <a href= "http://www.rankspirit.com">
                          <img alt=" "
 src="illustrations/ menu-deroulant/ cafe.gif"
 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;}

et hop !

								
To top