Un menu en onglets (« Tabs ») avec CSS

Il existe de nombreux menus différents : les menus classiques, soit une grosse barre horizontale, les menus dropdown, les menus verticaux alignés à gauche ou à droite, qui peuvent être plus ou moins complexes, etc. Certains de ces menus sont énormément lourds et quasiment inutilisables, d’autres très légers sobres. Nous voyons maintenant comment faire une barre de menu horizontale avec des onglets, comme c’est à la mode de nos jours, sans images ni javascript.

exemple1

Comme tu peux le voir, c’est sobre et simple. J’utilise ici simplement deux bordures gris clair et gris plus foncé, l’une étant sur le lien (a) et l’autre sur l’élément de liste (li)

Voici l’élément actif plus en détail pour bien voir les bordures :

exemple1_zoom

Commençons par un code html de base. Dans cet exemple, on utilisera la feuille de style menu.css.

<!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="en" lang="en">

<head>
 <title>Page de test</title>
 <meta http-equiv="content-type" content="text/html;charset=utf-8" />
 <link href="menu.css" media="all" rel="stylesheet" type="text/css"/>
</head>

<body>

</body>
</html>

Tous les morceaux code html qui suivent se situeront dans les balises <body></body> .Le code CSS se placera dans la feuille menu.css.

Mettons en place la structure du menu avec une liste :

<div id="menu">
<ul class="menu">
    <li>Menu 1</li>
    <li class="actif">actif</li>
    <li>Menu 3</li>
    <li>Menu 4</li>
</ul>
</div>

Ceci va donner une simple liste pas très belle et qui ne ressemble pas du tout à un menu. Il va falloir commencer à utiliser du CSS !

/* Base */
body { font-family: "Sans-Serif"; font-size: small } /* Histoire d'avoir une police d'écriture potable */
ul.menu { margin: 0; padding: 0}
ul.menu li { margin: 0; padding: 0; list-style-type:none;}

On vient d’enlever les marges et le padding par défaut des éléments de listes parce que c’est le bordel sinon. Le list-style-type correspond au petit point devant l’élément de liste. On continue :

div#menu { float:left;}
ul.menu { float:left;}
ul.menu li {
    display:block;
    float:left; /* ceci place l'élément du dessus à gauche */
}
ul.menu li a { display:block; }

/* Quelques couleurs... : */
.menu a {color: #3F5FA3; text-decoration:none; } /*Du bleu foncé pour les liens (une fois qu'on les aura mis) du menu sans soulignage*/
ul.menu {background: #eeeeec} /* Du gris pour le fond du menu */
/* ...et des espacements */
.menu li {
    margin-right: 20px;
    width: 120px; /* Une plus grand largeur... */
    text-align: center;  /*... et un alignement centré */
}

La chose commence à être utilisable. Mais bon, on a encore aucun design. Nous allons maintenant définir des hauteurs de ligne (et pas des hauteurs de blocs, parce que ces dernières ne centrent pas le texte verticalement). On veut que notre menu fasse 30px de haut. Nous allons mettre 31px sur l’extérieur à cause de la bordure et 30px sur l’élément de liste.

Voici un schéma qui explique ça bien :

embriquement_tailles

Regarde bien la partie gauche du dessin, on regardera l’histoire du li actif par la suite. ul.menu et li ont la même taille (une line-height de 30px. À l’ul.menu, on y rajoute une bordure de 1px. Le div#menu fait donc 31 px. A ce dernier, on y rajoute une autre bordure en gris plus foncé, pour faire un effet d’ombre.

div#menu { line-height: 31px; }
ul.menu, ul.menu li { line-height: 30px; }
/* et les couleurs */
ul.menu {border-bottom: 1px solid #DBDBD7; } /*Gris clair */
div#menu {border-bottom: 1px solid #BABDB6; } /* Gris plus foncé */

Ah, voilà qui nous donne quelque chose de sympa. La structure de base du menu est terminée. Ah non j’oubliais, notre menu n’a pas de liens ! (Parce qu’un menu, c’est cliquable).

<div id="menu">
<ul class="menu">
    <li><a href="#">Menu 1</a></li>
    <li class="actif"><a href="#">actif</a></li>
    <li><a href="#">Menu 3</a></li>
    <li><a href="#">Menu 4</a></li>
</ul>
</div>

Maintenant, il faut qu’on crée les onglets. Voici le schéma qui explique la méthode.

exemple1_zoom_doc

  • Sur tous les liens (a) des éléments de liste actifs (li.actif), une bordure de 1px partout sauf en bas, en gris foncé.
  • Sur tous les éléments de liste actifs (li.actif), une bordure de 1px partout sauf en bas, en gris clair.
  • On met une bordure de 1px blanche en bas sur les liens et les éléments de liste.

Compris ? A vos vim :)

li.actif a {
    border: 1px solid #B8BdB6; /* bordure grise partout */
    border-bottom: 1px solid #FFF; /* Ah en fait non, en bas on veut blanc */
}
li.actif  {
    border: 1px solid #DBDCD7;
    border-bottom: 1px solid #FFF;
    background:white; /* Le fond blanc sur le l'élément actif */
}

Reprenons notre schéma :
embriquement_tailles

A droite, on voit que les deux bordures (celle de l’élément de liste et celle du lien) « poussent » le l’élément de liste vers le bas. Comme c’est mis en place maintenant, il va simplement agrandir l’ul.menu et le div#menu. Pour éviter cela, on va définir une hauteur fixe pour ul.menu et div#menu d’un pixel de plus que les valeurs line-height.

ul.menu {height: 31px}
div#menu {height: 32px}

La question qui tue : pourquoi ?

Le menu fonctionne (chez moi) avec Firefox 3.5. N’hésite pas à poster des corrections ou des simplifications (et à me dire à quoi ça rime ce pixel supplémentaire sur les deux hauteurs) !

Vus : 918
Publié par Loutre.ch : 36