Aller au menu - Aller au contenu

[Plan du site] Vous êtes ici --- > Le Site du Zéro > Les tutoriels > Non-Officiels > Site Web > XHTML / CSS > Menu à déroulement horizontal > Lecture du tutoriel

Menu à déroulement horizontal

Vous vous apprêtez à lire un tutoriel rédigé par un membre de ce site. Malgré tout le soin que ce membre a pu apporter au tutoriel, nous ne pouvons pas garantir que les informations contenues sur cette page sont exactes à 100%. Merci de garder cela en tête lorsque vous lirez cette page ;o)
Avatar
Auteur : Apocalypse_Lord
Note : 18 / 20 (26 votes)
Visualisations : 21 960

Plus d'informations Plus d'informations
Salut à tous. ;)
Je vous propose aujourd'hui de créer un menu à déroulement horizontal pour votre site web ^^ .

Et ça veut dire quoi, menu à déroulement horizontal d'après toi :o ?

Eh bien c'est ce que nous allons voir dans la première partie que je vous invite à lire dès maintenant :p .
Image utilisateur
Sommaire du tutoriel :
Icône du chapitre

Légère introduction

Les prérequis



Bien, sans plus tarder, voici la liste de ce qu'il faut connaître pour suivre ce tuto :
Je me permets de vous mettre en garde dès à présent sur le point suivant :
certaines notions pourront vous sembler assez abstraites, complexes voire même un peu folles.
Quoi qu'il en soit, je vais essayer de tout expliquer de la meilleure façon possible pour que tout le monde il comprenne du premier coup :p (oui, je sais, c'est bien français :D ).


Pour commencer



Bien, après ces quelques précisions, passons à présent au fruit de notre (futur) travail.
Voici donc ce que j'appelle un menu à déroulement horizontal :

menu

Bon, ok : ça rend pas grand chose vu comme ça, peut-être ce second aperçu vous convaincra-t-il un peu plus :p :

Secret (cliquez pour afficher)
menu déroulé

Est-ce que ça rend déjà un peu mieux, vu comme ça ^^ ?
Bon euh... pour en arriver là, il va falloir que vous suiviez rigoureusement ce tuto pour comprendre petit à petit la logique des choses que je vous expose :) .

Après cette courte partie sur l'aperçu du résultat, voici venue l'heure de mettre en place notre cahier des charges qui mettra en avant ce que l'on souhaite rendre possible et au contraire, ce que l'on veut empêcher.

Tu veux ou tu veux pas ?

C'est quoi, ce titre débile o_O ?
Pas d'inquiétude, vous allez très vite le comprendre ^^ .

Voici, d'après le second aperçu ci-dessus et ce que l'on ne voit pas directement, notre liste :

Je veux...



Je ne veux pas...



Bien, ça nous fait déjà pas mal de contraintes à respecter, je trouve :p .

On est parti !

Bien : à présent, nous allons nous poser la question qui permet de répondre à notre première contrainte, à savoir : faire notre menu sous forme de liste.

Des volontaires pour répondre :-° ?

Ok, c'est trop simple (vous verrez après :diable: ) : bien sûr, on utilise les balises <ul> et <li> pour créer notre liste.

Et pour créer les sous-menus et les éléments encore plus bas (comprenez par là sous-sous-menus etc), il suffit d'imbriquer une nouvelle liste <ul> dans la ligne <li> qui lui correspond.

Voici donc sans tarder TOUT le code HTML dont nous allons nous servir :

Code : HTML
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr">
  <head>
    <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1" />
    <title>Ma page</title>
    <link href="../css/menu_dynamique.css" rel="stylesheet" type="text/css" media="screen" />
  </head>
  <body>
    <div id="menu_dynamique">
      <ul>
        <li class="end first"><a href="#">Accueil</a></li>
        <li class="extend">
          <a href="#">Jeux vidéo</a>
          <ul>
            <li class="extend first">
              <a href="#">jeu 1</a>
              <ul>
                <li class="end first"><a href="#">Présentation</a></li>
                <li class="end"><a href="#">Personnages</a></li>
                <li class="end"><a href="#">Magies</a></li>
                <li class="extend last">
                  <a href="#">Solution</a>
                  <ul>
                    <li class="end first"><a href="#">partie 1</a></li>
                    <li class="end"><a href="#">partie 2</a></li>
                    <li class="end"><a href="#">partie 3</a></li>
                    <li class="end last"><a href="#">partie 4</a></li>
                  </ul>
                </li>
              </ul>
            </li>
            <li class="end last"><a href="#">jeu 2</a></li>
          </ul>
        </li>
        <li class="end"><a href="#">Informatique</a></li>
        <li class="end"><a href="#">Forum</a></li>
        <li class="end"><a href="#">Livre d'or</a></li>
        <li class="end"><a href="#">Partenariat</a></li>
        <li class="end last"><a href="#">Contact</a></li>
      </ul>
    </div>
  </body>
</html>


Comme vous pouvez le voir, notre menu sera donc contenu dans une div.
Vous avez à présent TOUS les éléments qui ont permis de créer le menu, il nous reste à présent le plus gros du travail : le CSS (on peut en faire des choses avec, vous allez voir ça ^^ ).

Attention les yeux !

Attaquons-nous dès maintenant à nos multiples contraintes énoncées il y a quelques temps.

Notez néanmoins qu'il vous faudra un fichier d'extension .htc afin de permettre à IE d'afficher pleinement (et correctement :-° ) notre menu.

Ok, mais il est où, ce fichier ? Faut l'inventer :o ?

Mais non malheureux :p , ce fichier, je vous le donne, bien évidemment.
Il se trouve ici, faites-en un copier-coller sous le Bloc-notes (ou toute autre application similaire) et enregistrez-le sous [nom].htc (où [nom] est le nom que vous décidez de lui donner ^^ ).
Pour ma part, celui que j'ai récupéré était nommé csshover.htc, j'ai donc gardé ce nom.

Je vous conseille de ne pas (trop) chercher à en comprendre le fonctionnement si vous voulez garder toute votre tête :p .
Retenez simplement que sans ce fichier, IE (version inférieure à 7) ne permettrait pas les actions liées au survol (plus d'infos ici).

Et ce fichier, il se met où ?

Eh bien si j'ai abordé ce sujet avant d'entrer dans le CSS, c'est parce qu'il s'agit là du premier élément dont nous allons nous servir :) ; regardez :

Code : CSS
1
2
3
body {
  behavior: url("csshover.htc");
}

Voilà : ça, c'est fait :D .
Bien évidemment, vous précisez l'emplacement exact de votre fichier .htc, il se peut qu'il ne se trouve pas au même endroit que le mien.

Précision importante : behavior n'est pas une propriété valide !

Légère invalidité ou totale incompatibilité : personnellement, j'ai choisi d'affronter la légère invalidité (pour ceux qui ne sont pas de cet avis, vous pouvez quitter ce tuto car votre menu ne marchera pas sous IE sans le fichier .htc :( .

Pour ma part, j'ai ajouté quelques mises en forme du texte dans cette même balise body, à savoir :
  • font-size:10pt;
  • font-family:"Trebuchet MS", serif;
de même, j'ai mis en forme mes liens de la manière suivante :Code : CSS
1
2
3
4
5
6
7
#menu_dynamique li a {
  display:block;
  height:23px;
  text-decoration:none;
  color:#696969;
  background-color:#FFFFFF;
}

Notez que j'applique à mes liens un affichage de type block, sinon, impossible de leur préciser une hauteur ensuite (et la hauteur, on en a besoin, vous verrez ;) ).


Cette fois, c'est la bonne



Bien : nous allons désormais nous attaquer réellement à notre menu pour le rendre plus beau (parce que plus moche, c'est pas possible :lol: ).


Quelques bases



Code : CSS
1
2
3
4
5
#menu_dynamique {
  width:auto;
  margin:10px 0px;
  padding:0px;
}

Ceci ne correspond qu'à une légère mise en page de la div (marges et taille automatique) que vous adapterez selon vos besoins, au niveau de la page qui contiendra votre menu.

Menu sous forme de liste



Code : CSS
1
2
3
4
5
6
7
#menu_dynamique ul {
  width:150px;
  list-style:none;
  padding:0px;
  margin:0px;
  border-right:1px solid silver;
}

Je donne à présent quelques précisions concernant chaque liste :
La largeur de la liste DOIT être précisée afin de positionner correctement les sous-menus par la suite.


Pourquoi tu ne fais qu'une bordure à droite :o ?

Eh bien ça fait partie de ces petits bidouillages qu'on fait de temps à autre ^^ ; ainsi ici, seule la bordure droite apparaîtra (patience vous verrez, les autres viendront ;) ).

La (grosse) bordure grise sur la gauche



Code : CSS
1
2
3
4
5
6
7
8
#menu_dynamique ul li {
  width:auto;
  margin-left:5px;
  padding-left:25px;
  text-indent:5px;
  height:23px;
  background:url("bordure.png") no-repeat;
}

À présent, je mets en forme les <li> avec une largeur automatique, j'applique une marge externe pour que mon menu ne soit pas collé au bord gauche de l'écran, je mets également une marge interne à gauche de 25px puis je décale à nouveau mon texte de 5px par rapport à cette marge.
Il ne me reste plus qu'à préciser une hauteur ainsi qu'une image de fond (notez qu'elle ne se répète pas).

Voici l'image en question : bordure (25 x 50 pixels)
Vous remarquerez que la largeur de l'image correspond à notre marge interne ^^ .


Eh, mais ça ressemble plus à rien ton truc, là o_O ! Tous les éléments se chevauchent les uns les autres, c'est moche ! :(

Pas de panique, une fois de plus, c'est tout à fait normal ^^ .

Activation / Désactivation de l'affichage des sous-menus



Il est vrai que ça ne ressemble qu'à un tas de textes mélangés pour le moment, c'est pourquoi je vous propose de cacher les zones "indésirables".

Code : CSS
1
2
3
#menu_dynamique ul li ul {
  display:none;
}

Et voilà ^^ , il ne nous reste plus qu'à afficher les zones au survol du lien et de les placer correctement :

Code : CSS
1
2
3
4
5
6
#menu_dynamique ul li:hover ul {
  display:block;
  position:relative;
  top:-24px;
  left:115px;
}

Grâce au positionnement relatif, on peut placer le sous-menu à droite de son lien d'appel.
Dans le cas de notre exemple, les valeurs en pixels de top et de left ont été testées jusqu'à ce que le positionnement me satisfasse, il se peut que ces valeurs changent selon vos envies, faites-en bon usage ;) .


Attends deux secondes ! Quand je survole le lien, TOUS les sous-menus s'affichent, c'est quoi ce délire ? :colere2:

À vrai dire, c'est tout à fait normal car j'ai demandé à afficher la liste contenue dans le <li> survolé, or cette liste contient TOUT le reste des sous-menus :) .

Pour y remédier, j'ajoute aux zones à cacher les sous-sous-menus et leurs descendants en ajoutant
#menu_dynamique ul li:hover ul li ul
et
#menu_dynamique ul li:hover ul li:hover ul li ul
qui correspondent aux descendants dans mes menus :

Code : CSS
1
2
3
#menu_dynamique ul li ul, #menu_dynamique ul li:hover ul li ul, #menu_dynamique ul li:hover ul li:hover ul li ul{
  display:none;
}

C'est bien beau mais du coup, après, les descendants ne s'affichent plus au survol du <li> :o !

Même opération avec les zones à afficher ce coup-ci, on ajoute
#menu_dynamique ul li:hover ul li:hover ul
et #menu_dynamique ul li:hover ul li:hover ul li:hover ul
à mon bloc de propriétés qui gèrent l'affichage :

Code : CSS
1
2
3
4
5
6
#menu_dynamique ul li:hover ul, #menu_dynamique ul li:hover ul li:hover ul, #menu_dynamique ul li:hover ul li:hover ul li:hover ul{
  display:block;
  position:relative;
  top:-24px;
  left:115px;
}

Je précise bien qu'il s'agit d'ajouter deux nouveaux groupes de balises à nos deux blocs de propriétés existants et non pas de les recréer ;) .


Ajout du petit triangle noir en bout de ligne



On veut donc, lorsque l'une des lignes dispose d'un sous-menu, qu'apparaisse à droite de cette ligne un petit triangle noir que voici : sous-menu.

Code : CSS
1
2
3
#menu_dynamique ul li.extend a {
  background:white url("suite.gif") right no-repeat;
}

Voilà :) , avec ceci je définis une couleur de fond blanche, couplée à une image placée à droite sans répétition.
Vous remarquerez que j'applique cette modification uniquement aux liens ayant extend pour classe !
C'est dans cette manipulation qui réside la nécessité d'avoir défini chaque <li> par une classe (end ou extend).


Peut-être mais en attendant, ça ne fonctionne toujours pas comme on veut :( ! Le petit triangle est présent à droite de chaque <li> des sous-menus.

Eh bien il nous suffit de spécifier que chaque <li> de classe end des sous-menus ne possède pas d'image de fond dans ce cas ;) :

Code : CSS
1
2
3
#menu_dynamique ul li.extend:hover ul li.end a {
  background-image:none;
}

Et voilà, le tour est joué, on passe à la suite :) .



La flèche de positionnement



On souhaite à présent ajouter une petite flèche dans la bordure gauche du menu pour préciser l'emplacement de notre pointeur.

Je dis ajouter mais en réalité, il s'agit de remplacer l'image bordure par notre flèche (que nous avons préalablement placée par dessus un cadre de même couleur).

Pour ceux qui n'auraient pas tout compris, voici l'image en question : flèche
Il s'agit donc de définir comme image de fond notre flèche lorsque l'on survole une ligne <li>.

Code : CSS
1
2
3
#menu_dynamique li:hover {
  background:url("fleche_survol.png") no-repeat;
}

Vous remarquerez qu'en descendant dans les sous-menus (et leurs descendants), les flèches restent affichées devant les menus que nous avons déroulés (normal, puisque chaque sous-menu est contenu dans un menu ; donc, lorsqu'on survole un sous-menu, on survole en même temps le menu qui le contient :) ).


Et concernant le changement de la couleur du texte et de la couleur du fond, pourquoi tu ne le fais pas là en même temps ?

Tout simplement parce que notre image de fond (la bordure ou la flèche) se rattache à une ligne <li> alors que notre texte est, lui, rattaché au lien qu'il représente ;) .

Changer la couleur du texte et du fond (du lien :p )



Bien, rien de très compliqué ici :

Code : CSS
1
2
3
4
#menu_dynamique li a:hover {
  color:black;
  background-color:#BBB7C7;
}

On applique donc, comme je l'ai dit, une couleur de texte ainsi qu'une couleur de fond à notre lien (qui, rappelons-le, est de type block, ce qui permet que la couleur de fond remplisse bien TOUTE la ligne, et non pas seulement la place occupée par le texte.



Essayez d'enlever la ligne qui définit l'affichage des liens de type block et vous verrez par vous-mêmes ;) .

Et une fois de plus ça foire, ton truc :colere2: !

Eh oui : il se trouve que les lignes de classe extend ne se voient pas attribuer de couleur de fond au survol du lien (ainsi que tous les éléments des sous-menus et de leur descendance).

Pour cela, on va ajouter une bloc de propriétés CSS supplémentaire qui s'occupera spécialement de ces lignes-là (ouah, la chance :p ) :

Code : CSS
1
2
3
#menu_dynamique ul li.extend:hover a, #menu_dynamique ul li.extend:hover ul li:hover a, #menu_dynamique ul li.extend:hover ul li.extend:hover ul li:hover a, #menu_dynamique ul li.extend:hover ul li.extend:hover ul li.extend:hover ul li:hover a{
  background-color:#BBB7C7;
}

Notez que je définis quatre fois les lignes extend car mon menu est constitué en tout et pour tout de quatre "niveaux" (des listes, pour être exact ^^ ).
Et donc à chaque nouvelle déclaration, je descends d'un niveau dans mes menus en ajoutant ul li.extend:hover à chaque fois (qui correspond donc au fait de descendre dans la liste suivante et d'y chercher la ligne de classe extend qu'on survole).



C'est alors que vous remarquez que TOUS les sous-menus et leurs descendants se trouvent affublés de cette couleur de fond sans avoir été survolés :-° .
Problème rapidement résolu ainsi :

Code : CSS
1
2
3
#menu_dynamique ul li.extend:hover ul li a, #menu_dynamique ul li.extend:hover ul li:hover ul li a, #menu_dynamique ul li.extend:hover ul li.extend:hover ul li:hover ul li a{
  background-color:#FFFFFF;
}

Cette fois, trois déclarations seulement sont nécessaires car il s'agit de les appliquer aux liens des sous-menus et... leurs descendants, oui (c'est bien, vous suivez :p ).


Les bordures manquantes



Oui, c'est vrai, une seule bordure à droite, c'est pas top.

Pourquoi ne pas avoir défini toutes les bordures au niveau de la liste principale en même temps que la bordure de droite ?

Eh bien pour la raison suivante : un léger décalage a lieu à gauche de notre bordure grise formée par les images ; du coup, les bordures haute et basse sont trop longues, et la bordure gauche fait moche :( .

Mais n'ayez crainte, voici la solution ^^ .
Si on ne peut appliquer la bordure à la liste, appliquons-la à la ligne directement :) .
Dans ce cas, la première ligne de chaque liste possèdera une bordure haute et la dernière ligne de chaque ligne possèdera une bordure basse.

C'est là qu'interviennent les classes first et last ^^ .

Pour ceux qui ne le sauraient pas, il est possible d'appliquer plusieurs classes à un même élément en séparant leurs noms d'un simple espace.
Exemple :
Code : HTML
1
2
3
[...]
<li class="end first">
[...]

Voici donc les deux blocs CSS qui vont avec ces deux nouvelles classes :

Code : CSS
1
2
3
#menu_dynamique li.first{
  border-top:1px solid silver;
}

Code : CSS
1
2
3
#menu_dynamique li.last{
  border-bottom:1px solid silver;
}

Et voilà le travail :) .



Il nous reste une ultime partie à traiter : la compatibilité avec IE :-° .

IE l'irréductible emmerdeur navigateur



Sur la version 6 de IE sous laquelle j'ai testé mon menu, le fait de survoler un lien qui laisse apparaître un sous-menu étire le menu de base, le rendant très moche :euh: .

Pour palier ce problème, j'ai décidé de masquer les extensions indésirables grâce à la propriété CSS overflow.

Code : CSS
1
2
3
4
5
#menu_dynamique ul li.extend:hover {
  width:120px;
  height:23px;
  overflow:hidden;
}

Ainsi, je définis une largeur et une hauteur au survol de mes lignes de classe extend et j'y applique un overflow:hidden; afin de masquer tout débordement intempestif ^^ .
De cette façon, plus d'extension de mon menu et ainsi, on obtient le même rendu que sous FF.

Ok : t'as réussi à rétablir le problème pour IE mais du coup, ce sont les sous-menus de FF qui ne s'affichent plus o_O !?!

Et c'est tout à fait normal : FF aussi exécute le overflow et donc masque nos sous-menus.
Nous allons donc utiliser une méthode que seul FF interprète (j'entends plutôt par là que IE ne la comprend pas :p ) : l'héritage (cliquez ici si vous ne connaissez pas, et descendez un peu sur la page pour arriver à la partie sélecteur d'enfant).

Code : CSS
1
2
3
html > body #menu_dynamique ul li.extend:hover {
  overflow:visible;
}


Ceux qui ont pour navigateur IE 6 verront que ces derniers changements sont indispensables ; pour les autres, inutile d'imaginer les problèmes que cela représente :lol: .
Voici donc le dernier aperçu pour lequel seuls les utilisateurs de IE 6 verront un changement :



ET VOILÀ : ON A FINI !!!!!!

Q.C.M.

Comment définit-on les différents "niveaux" du menu dans le code HTML ?
Comment fait-on pour que IE puisse gérer le survol d'un élément ?
Pourquoi, quand je me situe dans un sous-sous-menu, la flèche verte dans la bordure reste affichée dans les deux menus "parents" ?
Comment sont formées les bordures hautes et basses de chaque menu ?
Comment résout-on le problème posé (sous FF) par la propriété overflow:hidden définie pour IE ?

Statistiques de réponses au QCM


Bon, c'était vraiment long, mais je pense avoir fourni le maximum d'informations afin que vous ne restiez pas trop dans le vague :) .

Et voilà, j'espère que ce tuto vous aura servi et qu'il vous aura plu ;) .

Si vous avez des questions ou des remarques, n'hésitez pas à m'envoyer un MP et / ou un commentaire ;) , j'y répondrai dans la limite de mes connaissances :p .
@+ amis Zér0s :) .
Retour en haut Retour en haut


Créé : le 14/03/2007 à 13:09:41
Modifié : le 22/08/2008 à 16:09:30
Avancement : 100%
Licence : Copie non autorisée

Changer de design | En savoir plus | Plan du site | Politique d'accessibilité | Règles | RSS tutoriels | RSS news
Édité par Simple IT SARL : Nous contacter | Notre blog | Revue de presse | Publicité

Y'a plus rien à lire, faut remonter maintenant !

Hébergement web - Correction de tutoriels - Créer un site
Vous souhaitez apparaître ici ? Contactez-nous.

Nombre de connectés 92 Zéros connectés | Requêtes SQL 8 requêtes | Temps de génération de la page : Total (SQL) 0.1081s (0.0944s)