Version en ligne

Tutoriel : Créer un menu horizontal déroulant en CSS

Table des matières

Créer un menu horizontal déroulant en CSS
Le xHTML
Le CSS
CSS + JavaScript
Adapter

Créer un menu horizontal déroulant en CSS

Le xHTML

Salut les zéros. ;)

Je vais aujourd'hui essayer de vous aider à créer un menu déroulant pour votre site ! :)

Ce menu déroulant est réalisé en xHTML/CSS, et utilise un brin de Javascript pour permettre une compatibilité avec les anciennes versions d'Internet Explorer.
Il a été testé sous Internet Explorer 6, Internet Explorer 7, Internet Explorer 8, Mozilla Firefox 2, Mozilla Firefox 3, Google Chrome ou encore Opéra et Safari !
De plus, il est valide xHTML strict !

Pour pouvoir réaliser ce menu déroulant, vous devez avoir lu le tutoriel de M@teo21 : Site Web !
Le niveau bac + 4 est aussi demandé !

Une fois ce tutoriel terminé, vous serez capables de réaliser un menu comme celui-ci, ou un beaucoup plus beau. :p

Bonne chance à vous... ^^

Le xHTML

Le CSS

Voilà, nous sommes partis ! :zorro:

Pour commencer ce tutoriel, nous allons étudier la structure xHTML à mettre en place.

Pour réaliser le menu déroulant, nous allons utiliser les balises de listes et non les tableaux.

Rappel

Voici comment se compose une liste en xHTML :

(Je ne parle pas des listes de définitions intentionnellement pour ne pas créer de confusion, mais vous pouvez retrouver la liste de ces balises avec des exemples dans la partie annexe du tuto Site Web sur les balises xHTML.)

Nous n'utiliserons pas les listes à puces numérotées pour une question d'esthétique. ;)
Nous nous retrouvons donc avec les balises <ul></ul> et <li></li>.
Utilisées de cette manière :

<ul>
        <li>Un premier élément de la liste</li>
        <li>Un deuxième élément de la liste</li>
</ul>

Imaginez que l'on désire un menu déroulant en plusieurs parties :

Voilà alors le code xHTML que l'on doit utiliser :

<ul>

        <li>
                <a href="#">accueil</a>
        </li>
        
        <li>
                <a href="#">membres</a>
        </li>
        
        <li>
                <a href="#">images</a>
        </li>
        
        <li>
                <a href="#">téléchargements</a>
        </li>
        
        <li>
                <a href="#">plus</a>
        </li>
        
</ul>

Imaginez maintenant transformer cette liste, en liste contenant des listes. :D

1, 2, 3, :magicien:

<ul id="menu">

        <li>
                <a href="#">accueil</a>
        </li>
        
        <li>
                <a href="#">membres</a>
                <ul>
                        <li><a href="#">connexion</a></li>
                        <li><a href="#">inscription</a></li>
                </ul>
        </li>
        
        <li>
                <a href="#">images</a>
                <ul>
                        <li>
                                <a href="#">photos</a>
                        </li>
                        <li>
                                <a href="#">vidéos</a>
                        </li>
                </ul>
        </li>
        
        <li>
                <a href="#">téléchargements</a>
                <ul>
                        <li><a href="#">vidéos</a></li>
                        <li><a href="#">musiques</a></li>
                </ul>
        </li>
        
        <li>
                <a href="#">plus</a>
                <ul>
                        <li><a href="#">forum</a></li>
                        <li><a href="#">liens</a></li>
                        <li><a href="#">nous contacter</a></li>
                        <li><a href="#">team</a></li>
                        <li><a href="#">recherche</a></li>
                </ul>
        </li>
        
</ul>

Mais si on veut encore plus développer le menu déroulant ^^ :

<ul id="menu">

        <li>
                <a href="#">accueil</a>
        </li>
        
        <li>
                <a href="#">membres</a>
                <ul>
                        <li><a href="#">connexion</a></li>
                        <li><a href="#">inscription</a></li>
                </ul>
        </li>
        
        <li>
                <a href="#">images</a>
                <ul>
                        <li>
                                <a href="#">photos</a>
                                <ul>
                                        <li><a href="#">catégorie 1</a></li>
                                        <li><a href="#">catégorie 2</a></li>
                                </ul>

                        </li>
                        <li>
                                <a href="#">vidéos</a>
                        </li>
                </ul>
        </li>
        
        <li>
                <a href="#">téléchargements</a>
                <ul>
                        <li><a href="#">vidéos</a></li>
                        <li><a href="#">musiques</a></li>
                </ul>
        </li>
        
        <li>
                <a href="#">plus</a>
                <ul>
                        <li><a href="#">forum</a></li>
                        <li><a href="#">liens</a></li>
                        <li><a href="#">nous contacter</a></li>
                        <li><a href="#">team</a></li>
                        <li><a href="#">recherche</a></li>
                </ul>
        </li>
        
</ul>

Nous allons donc créer un fichier CSS afin que la liste de base soit horizontale, et qu'au passage de la souris sur l'un des éléments de cette liste, la liste contenue dans cet élément soit à son tour affichée... Et ainsi de suite.

(J'ai mis id="menu" afin de travailler uniquement sur cette liste et donc ne pas déformer les autres listes de votre site. De plus ce sera utile pour le CSS.)

En avant, le plus dur facile est derrière nous. :pirate:


Le CSS

Le CSS

Le xHTML CSS + JavaScript

Bon : si vous avez essayé le code xHTML précédent, vous avez alors tout de suite vu que ce n'était qu'une liste qui contient des listes dans ses éléments. C'est pour cela que les CSS doivent intervenir afin de mettre en forme l'ensemble. ;)

(Je vous conseille de revoir vos connaissances en CSS si vous avez des doutes.)

Commençons doucement :-° ...

Adaptons la forme des listes (balises <ul></ul>) ...

#menu, #menu ul /* Liste */     
{
        padding : 0; /* pas de marge intérieure */
        margin : 0; /* ni extérieure */
        list-style : none; /* on supprime le style par défaut de la liste */
        line-height : 21px; /* on définit une hauteur pour chaque élément */
        text-align : center; /* on centre le texte qui se trouve dans la liste */
}

#menu /* Ensemble du menu */
{
        font-weight : bold; /* on met le texte en gras */
        font-family : Arial; /* on utilise Arial, c'est plus beau ^^ */
        font-size : 12px; /* hauteur du texte : 12 pixels */
}

... le contenu des listes (balises de liens) ...

#menu a /* Contenu des listes */
{
        display : block; /* on change le type d'élément, les liens deviennent des balises de type block */
        padding : 0; /* aucune marge intérieure */
        background : #000; /* couleur de fond */        
        color : #fff; /* couleur du texte */
        text-decoration : none; /* on supprime le style par défaut des liens (la plupart du temps = souligné) */
        width : 144px; /* largeur */
}

... et les éléments des listes (balises <li></li>) et les listes (balises <ul></ul>).

#menu li /* Éléments des listes */      
{ 
        float : left; 
        /* pour IE qui ne reconnaît pas "transparent" */
        border-right : 1px solid #fff; /* on met une bordure blanche à droite de chaque élément */
}

/* IE ne reconnaissant pas le sélecteur ">" */
html>body #menu li
{
        border-right: 1px solid transparent ; /* on met une bordure transparente à droite de chaque élément */
}

#menu li ul /* Sous-listes */
{ 
        position: absolute; /* Position absolue */
        width: 144px; /* Largeur des sous-listes */
        left: -999em; /* Hop, on envoie loin du champ de vision */
}


#menu li ul li /* Eléments de sous-listes */
{
        /* pour ie qui ne reconnaît pas "transparent" (comme précédemment) */
        border-top : 1px solid #fff; /* on met une bordure blanche en haut de chaque élément d'une sous-liste */
}

/* IE ne reconnaissant pas le sélecteur ">" */
html>body #menu li ul li                
{
        border-top : 1px solid transparent; /* on met une bordure transparente en haut de chaque élément */
}

#menu li ul ul 
{
        margin    : -22px 0 0 144px ; /* On décale les sous-sous-listes pour qu'elles ne soient pas au dessus des sous-listes */ 
        /* pour IE qui ne reconnaît pas "transparent" (comme précédemment) */
        border-left     : 1px solid #fff ; /* Petite bordure à gauche pour ne pas coller ... */      
}

/* IE ne reconnaissant pas le sélecteur ">" ... je me répète ;-) */
html>body #menu li ul ul                
{
        border-left     : 1px solid transparent ; /* on met une bordure transparente sur la gauche de chaque élément */
}

IE : Internet Explorer

Aidez-vous des commentaires pour comprendre ! ;)

Code CSS complet

#menu, #menu ul /* Liste */     
{
        padding : 0; /* pas de marge intérieure */
        margin : 0; /* ni extérieure */
        list-style : none; /* on supprime le style par défaut de la liste */
        line-height : 21px; /* on définit une hauteur pour chaque élément */
        text-align : center; /* on centre le texte qui se trouve dans la liste */
}

#menu /* Ensemble du menu */
{
        font-weight : bold; /* on met le texte en gras */
        font-family : Arial; /* on utilise Arial, c'est plus beau ^^ */
        font-size : 12px; /* hauteur du texte : 12 pixels */
}

#menu a /* Contenu des listes */
{
        display : block; /* on change le type d'élément, les liens deviennent des balises de type block */
        padding : 0; /* aucune marge intérieure */
        background : #000; /* couleur de fond */        
        color : #fff; /* couleur du texte */
        text-decoration : none; /* on supprime le style par défaut des liens (la plupart du temps = souligné) */
        width : 144px; /* largeur */
}

#menu li /* Elements des listes */      
{ 
        float : left; 
        /* pour IE qui ne reconnaît pas "transparent" */
        border-right : 1px solid #fff; /* on met une bordure blanche à droite de chaque élément */
}

/* IE ne reconnaissant pas le sélecteur ">" */
html>body #menu li
{
        border-right: 1px solid transparent ; /* on met une bordure transparente à droite de chaque élément */
}

#menu li ul /* Sous-listes */
{ 
        position: absolute; /* Position absolue */
        width: 144px; /* Largeur des sous-listes */
        left: -999em; /* Hop, on envoie loin du champ de vision */
}


#menu li ul li /* Éléments de sous-listes */
{
        /* pour IE qui ne reconnaît pas "transparent" (comme précédemment) */
        border-top : 1px solid #fff; /* on met une bordure blanche en haut de chaque élément d'une sous liste */
}

/* IE ne reconnaissant pas le sélecteur ">" */
html>body #menu li ul li                
{
        border-top : 1px solid transparent; /* on met une bordure transparente en haut de chaque élément */
}

#menu li ul ul 
{
        margin    : -22px 0 0 144px ; /* On décale les sous-sous-listes pour qu'elles ne soient pas au dessus des sous-listes */ 
        /* pour IE qui ne reconnaît pas "transparent" (comme précédemment) */
        border-left     : 1px solid #fff ; /* Petite bordure à gauche pour ne pas coller ... */      
}

/* IE ne reconnaissant pas le sélecteur ">" ... je me répète ;-) */
html>body #menu li ul ul                
{
        border-left     : 1px solid transparent ; /* on met une bordure transparente sur la gauche de chaque élément */
}

Fiou ... :-° !!!
(siffle)

Il ne reste donc plus qu'à faire réagir tout ça au passage de la souris ! :D


Le xHTML CSS + JavaScript

CSS + JavaScript

Le CSS Adapter

Bon : c'est bien beau, mais ce que nous avons fait avant n'a rien de déroulant.
Il faut faire réagir le menu au passage de la souris !

Hop ! Au passage de la souris sur l'un des contenus des listes (balises de liens), inversons les couleurs :

#menu a:hover /* Lorsque la souris passe sur un des liens */    
{
        color: #000; /* On passe le texte en noir... */
        background: #fff; /* ... et au contraire, le fond en blanc */
}

C'est facile : pour faire dérouler le menu au passage de la souris, il suffit d'utiliser à nouveau :hover, non ? :lol:

Oui et non, car les anciennes versions d'Internet Explorer n'acceptent la pseudo-classe :hover que sur les liens ...

Or, un menu déroulant interdit aux anciennes versions d'Internet Explorer... ce n'est pas le mieux que l'on puisse faire.

Nous allons donc devoir utiliser une pincée de Javascript (astuce trouvée dans ce tutoriel).

sfHover = function() {
        var sfEls = document.getElementById("menu").getElementsByTagName("LI");
        for (var i=0; i<sfEls.length; i++) {
                sfEls[i].onmouseover=function() {
                        this.className+=" sfhover";
                }
                sfEls[i].onmouseout=function() {
                        this.className=this.className.replace(new RegExp(" sfhover\\b"), "");
                }
        }
}
if (window.attachEvent) window.attachEvent("onload", sfHover);

Importez le code ci-dessus sur chaque page où sera installé le menu déroulant.
Pour cela, deux solutions :

<!-- Faire un fichier .js et mettre entre les balises head : -->
<script type="text/javascript" src="menu.js"></script>

<!-- Ou copier le code ci-dessus dans les balises : -->
<script type="text/javascript">
<!--
METTRE LE JAVASCRIPT EN COMMENTAIRES
POUR QUE LE SCRIPT SOIT VALIDE W3C
-->
</script>
<!--  Et mettre tout entre les balises head. -->

Ce code écrit en Javascript va mettre automatiquement une classe (sfHover) aux éléments de nos listes.
Au passage de la souris, cette classe est alors retirée. Cela nous permet donc de faire réagir facilement le menu. ;)

Voilà comment nous allons procéder :

#menu li:hover ul ul, #menu li.sfhover ul ul /* Sous-sous-listes lorsque la souris passe sur un élément de liste */
{
        left: -999em; /* On expédie les sous-sous-listes hors du champ de vision */
}

#menu li:hover ul, #menu li li:hover ul, #menu li.sfhover ul, #menu li li.sfhover ul  /* Sous-listes lorsque la souris passe sur un élément de liste ET sous-sous-lites lorsque la souris passe sur un élément de sous-liste */
{
        left: auto; /* Repositionnement normal */
        min-height: 0; /* Corrige un bug sous IE */
}

Lisez bien les commentaires. :)


Le CSS Adapter

Adapter

CSS + JavaScript

:colere2: Ce menu ne marche pas bien avec mon site !
Que puis-je faire pour l'adapter à mon cas ? :o

Nous allons voir ensemble comment adapter ce menu à vos différents designs... ;)

Largeur

Effectivement, ce menu mesure 725 pixels de large... ce n'est pas bien pratique pour les designs extensibles !

De simples modifications permettent de résoudre ce problème...

#menu a 
{
        display : block; 
        padding : 0; 
        background : #000; 
        color : #fff; 
        text-decoration : none; 
        width : 144px; /* <<<<<< ICI */
}

...

#menu li ul 
{ 
        position: absolute; 
        width: 144px; /* <<<<<< ET ICI */
        visibility: hidden; 
}

...


#menu li ul ul 
{
        margin    : -22px 0 0 144px ; 
        border-left     : 1px solid #fff ; /* <<<<<< sans oublier ICI */
}

Il suffit de remplacer cette largeur en pixels par un pourcentage. :)

Couleur

J'ai choisi de mettre le menu en noir et blanc, mais il ne tient qu'à vous de modifier les couleurs. :p

#menu a 
{
        display : block; 
        padding : 0; 
        background : #000; /* Couleur du fond, actuellement = noir */
        color : #fff; /* Couleur du texte, actuellement = blanc */
        text-decoration : none; 
        width : 144px; 
}

/* Inversement des couleurs lorsque la souris passe */

#menu a:hover 
{
        color : #000; /* Noir */
        background : #fff; /* Blanc*/
}

Images et transparence

Encore plus fort, il est très facile de mettre des images comme fond dans le menu.

De plus, pour donner un effet de transparence, vous pouvez mettre une image en partie transparente et rajouter :

#menu li ul li a 
{
         background     : transparent url("adresse de l'image transparente") repeat ;
}

Essayez, c'est facile à faire et cela peut avoir un bon rendu. ;)

Optimisation

Vos pages sont déjà très lourdes ? Vous avez peur de ralentir la navigation de vos visiteurs ?

Astuce : utilisez les commentaires conditionnels !

Utilisez-les de manière à ce que le Javascript ne soit là que pour les utilisateurs d'Internet Explorer.

Exemple :

<!--[if lte IE 6]>
Le javascript du menu déroulant ...
<![endif]-->

Ce commentaire conditionnel n'affiche le javascript que pour les versions d'Internet Explorer inférieures ou égales à 6.

Flash

Pour les dernières versions de Mozilla Firefox, d'Internet Explorer, de Google Chrome etc, il existe une solution qui consiste à rajouter un paramètre à l'application. Il faut utiliser le paramètre wmode avec l'attribut soit transparent : wmode="transparent", soit en opaque en appliquant un z-index à l'object.

Voici un exemple concret avec une vidéo YouTube :

Citation : Code

<object width="560" height="340">
<param name="movie" value="http://www.youtube.com/v/7H7OoKI5-yg&hl=fr&fs=1&"></param>
<param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param>
<embed wmode="transparent" src="http://www.youtube.com/v/7H7OoKI5-yg&hl=fr&fs=1&" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="560" height="340"></embed>
</object>

Si vous ne trouvez pas où mettre wmode="transparent", vous pouvez rajouter entre les balises <object></object> :

<param name="WMODE" value="transparent" ></param>

Ou :

<param name="WMODE" value="transparent" />

D'autres problèmes avec le menu déroulant ? Demandez des conseils sur le Forum, lisez les commentaires de ce tutoriel et documentez vous...

Voilà, c'est déjà la fin !

J'espère que ce tuto vous aura aidés à réaliser un menu déroulant pour votre site, cela fait toujours très pro. :D
Toujours dans les menus, si vous désirez réaliser un menu horizontal, ce tutoriel est là pour vous, ou si votre truc, c'est plutôt les onglets, pensez à visiter celui-là.

@+ les Zér0s. ;)

Ps : Vous avez apprécié ce tutoriel et vous avez trouvé des astuces d'adaptation, des soucis de compatibilité, des améliorations possibles ... ? N'hésitez pas à me prévenir pour les partager.
Je suis également en recherche de traducteurs pour faire profiter de ce tutoriel à un maximum de personnes.
Merci :)


CSS + JavaScript