Présentation▲
Developpez.com tient à vous informer que le support du CSS par les navigateurs a évolué. Par conséquent, certaines propriétés proposées dans les codes ont aujourd'hui été adoptées ou rejetées. Nous vous invitons à vous renseigner à ce sujet, par exemple sur ce site : CSS3 Browser Support
Voyons d'abord comment se présente ce menu.
Si vous êtes pressé, vous pouvez déjà voir un exemple en ligne.
La structure HTML▲
Comme vous pouvez le constater ci-dessous, la structure HTML ne contient rien de plus que ce qui est nécessaire, elle est minimale et facile à comprendre.
<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>
Une dernière chose, mais néanmoins importante, le code HTML est sémantiquement correct. La structure est logique et a une signification propre, même si aucun style n'est appliqué :
Dans mon exemple, seule la section « Categories » possède un sous-menu, mais bien entendu, vous pouvez en ajouter sur chacun des éléments.
Le CSS▲
/* Principal */
#menu
{
width:
100
%;
margin:
0
;
padding:
10
px 0
0
0
;
list-style:
none
;
background:
#111
;
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-border-radius:
50
px;
border-radius:
50
px;
-moz-box-shadow:
0
2
px 1
px #9c9c9c
;
-webkit-box-shadow:
0
2
px 1
px #9c9c9c
;
box-shadow:
0
2
px 1
px #9c9c9c
;
}
#menu
li{
float:
left
;
padding:
0
0
10
px 0
;
position:
relative
;
}
#menu
a{
float:
left
;
height:
25
px;
padding:
0
25
px;
color:
#999
;
text-transform:
uppercase
;
font:
bold
12
px/25
px Arial,
Helvetica;
text-decoration:
none
;
text-shadow:
0
1
px 0
#000
;
}
#menu
li:
hover
>
a{
color:
#fafafa
;
}
*
html #menu
li a:
hover
{
/* IE6 */
color:
#fafafa
;
}
#menu
li:
hover
>
ul{
display:
block
;
}
/* Sous-menu */
#menu
ul{
list-style:
none
;
margin:
0
;
padding:
0
;
display:
none
;
position:
absolute
;
top
:
35
px;
left
:
0
;
z-index:
99999
;
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-border-radius:
5
px;
border-radius:
5
px;
}
#menu
ul li{
float:
none
;
margin:
0
;
padding:
0
;
display:
block
;
-moz-box-shadow:
0
1
px 0
#111111
,
0
2
px 0
#777777
;
-webkit-box-shadow:
0
1
px 0
#111111
,
0
2
px 0
#777777
;
box-shadow:
0
1
px 0
#111111
,
0
2
px 0
#777777
;
}
#menu
ul li:
last-child
{
-moz-box-shadow:
none
;
-webkit-box-shadow:
none
;
box-shadow:
none
;
}
#menu
ul a{
padding:
10
px;
height:
auto
;
line-height:
1
;
display:
block
;
white-space:
nowrap
;
float:
none
;
text-transform:
none
;
}
*
html #menu
ul a{
/* IE6 */
height:
10
px;
width:
150
px;
}
*:
first-child
+
html #menu
ul a{
/* IE7 */
height:
10
px;
width:
150
px;
}
#menu
ul a:
hover
{
background:
#0186ba
;
background:
-moz-linear-gradient(
#04acec
,
#0186ba
);
background:
-webkit-gradient(
linear
,
left
top
,
left
bottom
,
from(
#04acec
),
to(
#0186ba
));
background:
-webkit-linear-gradient(
#04acec
,
#0186ba
);
background:
-o-linear-gradient(
#04acec
,
#0186ba
);
background:
-ms-linear-gradient(
#04acec
,
#0186ba
);
background:
linear-gradient
(
#04acec
,
#0186ba
);
}
#menu
ul li:
first-child
a{
-moz-border-radius:
5
px 5
px 0
0
;
-webkit-border-radius:
5
px 5
px 0
0
;
border-radius:
5
px 5
px 0
0
;
}
#menu
ul li:
first-child
a:
after
{
content:
''
;
position:
absolute
;
left
:
30
px;
top
:
-8px;
width:
0
;
height:
0
;
border-left:
5
px solid
transparent
;
border-right:
5
px solid
transparent
;
border-bottom:
8
px solid
#444
;
}
#menu
ul li:
first-child
a:
hover
:
after
{
border-bottom-color:
#04acec
;
}
#menu
ul li:
last-child
a{
-moz-border-radius:
0
0
5
px 5
px;
-webkit-border-radius:
0
0
5
px 5
px;
border-radius:
0
0
5
px 5
px;
}
/* Rétablissement du flottement */
#menu
:
after
{
visibility:
hidden
;
display:
block
;
font-size:
0
;
content:
" "
;
clear:
both
;
height:
0
;
}
*
html #menu
{
zoom:
1
;
}
/* IE6 */
*:
first-child
+
html #menu
{
zoom:
1
;
}
/* IE7 */
Le code est assez long, mais c'est tout ce dont on a besoin.
Forme CSS▲
Peut-être avez-vous remarqué le triangle qui apparaît au-dessus du sous-menu. Il s'agit d'une forme CSS dont le but est d'améliorer l'utilisation de ce menu CSS3.
Il est écrit en utilisant le pseudoélément :after :
#menu
ul li:
first-child
a:
after
{
content:
''
;
position:
absolute
;
left
:
30
px;
top
:
-8px;
width:
0
;
height:
0
;
border-left:
5
px solid
transparent
;
border-right:
5
px solid
transparent
;
border-bottom:
8
px solid
#444
;
}
#menu
ul li:
first-child
a:
hover
:
after
{
border-bottom-color:
#04acec
;
}
Apprivoiser la « bête » IE6▲
Le sous-menu est affiché au survol de la balise <li>. Comme vous le savez déjà, IE6 ne supporte pas le survol sur des éléments qui ne sont pas des liens.
Même si au début de cet article j'ai annoncé « sans code JavaScript additionnel », je vais malgré tout en ajouter, uniquement pour le support d'IE6.
<script
type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js">
</script>
<script
type="text/javascript">
$(
function(
) {
if (
$.
browser.
msie &&
$.
browser.
version.substr
(
0
,
1
)<
7
)
{
$(
'li'
).has
(
'ul'
).mouseover
(
function(
){
$(
this).children
(
'ul'
).show
(
);
}
).mouseout
(
function(
){
$(
this).children
(
'ul'
).hide
(
);
}
)
}
}
);
</script>
Ceci n'est toutefois plus réellement utile. Le décompte final ayant commencé !
La solution proposée utilise jQuery, mais cela ne devrait pas être un problème puisqu'aujourd'hui, il est présent dans la plupart des sites.
Cibler IE6 et IE7▲
À côté de ce fallback avec jQuery, le code CSS inclut quelques lignes spécifiques pour IE6 et IE7 :
*
html #menu
{
zoom:
1
;
}
/* IE6 */
*:
first-child
+
html #menu
{
zoom:
1
;
}
/* IE7 */
D'autres astuces relatives à la compatibilité pour IE sont présentes dans le code CSS et empêchent la validation. Si cela vous perturbe, vous pouvez utiliser les commentaires conditionnels !
Voir un exemple en ligne.
Mises à jour▲
Depuis l'écriture de l'article, le menu déroulant gère maintenant plusieurs niveaux de sous-menus.
J'ai encore pris sur mon temps libre pour améliorer encore ce menu CSS3 :
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 dropdown menu.
Nous tenons aussi à remercier bifconsult et jacques_jean pour leur relecture attentive de cet article.