Présentation▲
Si vous êtes pressé, vous pouvez déjà voir un exemple en ligne.
Sinon voici un aperçu du menu déroulant animé que nous allons créer en CSS3 :

Vous vous souvenez de mon précédent menu déroulant CSS3 ? Ce menu vous a beaucoup plu et est à l'heure actuelle l'article le plus populaire de mon site.
Cet article aurait peut-être dû s'appeler « Un menu déroulant en CSS3 revisité ». Je dis cela car je vais vous apprendre à animer le menu déroulant de l'exemple de l'article précédent.
Le HTML▲
La structure HTML n'a pas du tout changé, simple et minimale. En voici un extrait :
<ul id="menu">
        <li><a href="#">Home</a></li>
        <li>
                <a href="#">Categories</a>
                <ul>
                        <li><a href="#">CSS</a></li>
                        <li><a href="#">Graphic design</a></li>
                        <li><a href="#">Development tools</a></li>
                        <li><a href="#">Web design</a></li>
                </ul>
        </li>
        <li><a href="#">Work</a></li>
        <li><a href="#">About</a></li>
        <li><a href="#">Contact</a></li>
</ul>Le CSS▲
J'ai en revanche un peu remanié les styles pour permettre d'animer ce magnifique menu déroulant CSS3. Voici donc les différentes portions de code commentées.
Mini reset▲
D'abord, nous réinitialisons certains styles par défaut des balises <ul>.
#menu, #menu ul {
        margin: 0;
        padding: 0;
        list-style: none;
}Niveau principal▲
L'élément #menu correspond à la balise <ul> contenant le menu. Nous lui appliquons un dégradé, des ombres et des coins arrondis pour lui donner l'aspect suivant :
#menu {
        width: 960px;
        margin: 60px auto;
        border: 1px solid #222;
        background-color: #111;
        background-image: -moz-linear-gradient(#444, #111);
        background-image: -webkit-gradient(linear, left top, left bottom, from(#444), to(#111));
        background-image: -webkit-linear-gradient(#444, #111);
        background-image: -o-linear-gradient(#444, #111);
        background-image: -ms-linear-gradient(#444, #111);
        background-image: linear-gradient(#444, #111);
        -moz-border-radius: 6px;
        -webkit-border-radius: 6px;
        border-radius: 6px;
        -moz-box-shadow: 0 1px 1px #777;
        -webkit-box-shadow: 0 1px 1px #777;
        box-shadow: 0 1px 1px #777;
}Annuler les flottements▲
J'ai repris ici la méthode de Nicolas Gallagher pour annuler le flottement :
Éléments de liste▲
Notez la présence du sélecteur #menu li:hover > a. C'est probablement l'astuce la plus importante pour réaliser ce menu déroulant CSS3 !
Son fonctionnement est de sélectionner une balise <a>, qui est enfant d'une balise <li>, qui elle-même est un descendant de #menu. Voir une description détaillée.
#menu li {
        float: left;
        border-right: 1px solid #222;
        -moz-box-shadow: 1px 0 0 #444;
        -webkit-box-shadow: 1px 0 0 #444;
        box-shadow: 1px 0 0 #444;
        position: relative;
}
#menu a {
        float: left;
        padding: 12px 30px;
        color: #999;
        text-transform: uppercase;
        font: bold 12px Arial, Helvetica;
        text-decoration: none;
        text-shadow: 0 1px 0 #000;
}
#menu li:hover > a {
        color: #fafafa;
}
*html #menu li a:hover { /* IE6 only */
        color: #fafafa;
}Sous-menus▲
Avec les transitions CSS3, nous pouvons animer les changements de valeurs des propriétés comme margin ou opacity. C'est plutôt sympa et j'ai utilisé cette méthode pour animer les sous-menus CSS3. Si vous me demandez mon avis, je dirais que le résultat est excellent :

#menu ul {
        margin: 20px 0 0 0;
        _margin: 0; /*IE6 only*/
        opacity: 0;
        visibility: hidden;
        position: absolute;
        top: 38px;
        left: 0;
        z-index: 9999;
        background: #444;
        background: -moz-linear-gradient(#444, #111);
        background: -webkit-gradient(linear,left bottom,left top,color-stop(0, #111),color-stop(1, #444));
        background: -webkit-linear-gradient(#444, #111);
        background: -o-linear-gradient(#444, #111);
        background: -ms-linear-gradient(#444, #111);
        background: linear-gradient(#444, #111);
        -moz-box-shadow: 0 -1px rgba(255,255,255,.3);
        -webkit-box-shadow: 0 -1px 0 rgba(255,255,255,.3);
        box-shadow: 0 -1px 0 rgba(255,255,255,.3);
        -moz-border-radius: 3px;
        -webkit-border-radius: 3px;
        border-radius: 3px;
        -webkit-transition: all .2s ease-in-out;
        -moz-transition: all .2s ease-in-out;
        -ms-transition: all .2s ease-in-out;
        -o-transition: all .2s ease-in-out;
        transition: all .2s ease-in-out;
}
#menu li:hover > ul {
        opacity: 1;
        visibility: visible;
        margin: 0;
}
#menu ul ul {
        top: 0;
        left: 150px;
        margin: 0 0 0 20px;
        _margin: 0; /*IE6 only*/
        -moz-box-shadow: -1px 0 0 rgba(255,255,255,.3);
        -webkit-box-shadow: -1px 0 0 rgba(255,255,255,.3);
        box-shadow: -1px 0 0 rgba(255,255,255,.3);
}
#menu ul li {
        float: none;
        display: block;
        border: 0;
        _line-height: 0; /*IE6 only*/
        -moz-box-shadow: 0 1px 0 #111, 0 2px 0 #666;
        -webkit-box-shadow: 0 1px 0 #111, 0 2px 0 #666;
        box-shadow: 0 1px 0 #111, 0 2px 0 #666;
}
#menu ul li:last-child {
        -moz-box-shadow: none;
        -webkit-box-shadow: none;
        box-shadow: none;
}
#menu ul a {
        padding: 10px;
        width: 130px;
        _height: 10px; /*IE6 only*/
        display: block;
        white-space: nowrap;
        float: none;
        text-transform: none;
}
#menu ul a:hover {
        background-color: #0186ba;
        background-image: -moz-linear-gradient(#04acec,  #0186ba);
        background-image: -webkit-gradient(linear, left top, left bottom, from(#04acec), to(#0186ba));
        background-image: -webkit-linear-gradient(#04acec, #0186ba);
        background-image: -o-linear-gradient(#04acec, #0186ba);
        background-image: -ms-linear-gradient(#04acec, #0186ba);
        background-image: linear-gradient(#04acec, #0186ba);Style des premiers et derniers éléments de liste▲
#menu ul li:first-child > a {
        -moz-border-radius: 3px 3px 0 0;
        -webkit-border-radius: 3px 3px 0 0;
        border-radius: 3px 3px 0 0;
}
#menu ul li:first-child > a:after {
        content: '';
        position: absolute;
        left: 40px;
        top: -6px;
        border-left: 6px solid transparent;
        border-right: 6px solid transparent;
        border-bottom: 6px solid #444;
}
#menu ul ul li:first-child a:after {
        left: -6px;
        top: 50%;
        margin-top: -6px;
        border-left: 0;
        border-bottom: 6px solid transparent;
        border-top: 6px solid transparent;
        border-right: 6px solid #3b3b3b;
}
#menu ul li:first-child a:hover:after {
        border-bottom-color: #04acec;
}
#menu ul ul li:first-child a:hover:after {
        border-right-color: #0299d3;
        border-bottom-color: transparent;
}
#menu ul li:last-child > a {
        -moz-border-radius: 0 0 3px 3px;
        -webkit-border-radius: 0 0 3px 3px;
        border-radius: 0 0 3px 3px;
}Le jQuery▲
Vous y êtes habitués : IE6 réclame quelques attentions supplémentaires :
$(function() {
  if ($.browser.msie && $.browser.version.substr(0,1)<7)
  {
        $('li').has('ul').mouseover(function(){
                $(this).children('ul').css('visibility','visible');
                }).mouseout(function(){
                $(this).children('ul').css('visibility','hidden');
                })
  }
});Puisque la pseudoclasse :hover ne fonctionne pas sur des éléments autres que des liens, nous devons ajouter ce petit code jQuery. Le code est suffisamment explicite selon moi.
Conclusion et remerciements▲
C'est terminé. Si cet article vous a plu, n'hésitez pas à le commenter et à proposer vos idées d'améliorations. (NDT Y compris sur le site de l'article original.)
Cet article a été publié avec l'aimable autorisation de Catalin Rosu. L'article original peut être lu sur le site de Red Team Design : CSS3 animated dropdown menu.
Nous tenons aussi à remercier bifconsult pour sa relecture attentive de cet article.


 
    








