CSS : un menu horizontal centré sans utiliser les flottants

Partons du postulat suivant : dans l'en-tête de votre site web, vous souhaitez afficher le menu principal comme une barre horizontale contenant des onglets. De plus, vous souhaiteriez centrer ce menu par rapport à la page.

Les menus horizontaux utilisent traditionnellement des éléments flottants (propriété CSS float: left ou float: right). Ceux-ci ont plusieurs désavantages, qui doivent être contrés en utilisant des techniques alourdissant le code CSS.

Dans ce billet, je reviendrai sur les désavantages de l'utilisation d'éléments flottants, et je vous proposerai une méthode plus souple, nécessitant moins de code et fonctionnant avec tous les navigateurs récents ainsi qu'avec Internet Explorer 6.

 

Le code HTML

Voici notre code de base avec quelques règles CSS basiques : 

<!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" lang="fr" xml:lang="fr">

  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Test de menu</title>
    <style type="text/css">
      <!--
      #header {
        background-color: #CCC;
        padding: 1em 0 0;
      }

      #top-menu {
        margin: 0;
      }
        #top-menu li {
        }
          #top-menu li a {
            background-color: #EEE;
          }

      #content {
        background-color: #CCFFCC;
        padding: 1em 0;
      }
      -->
    </style>
  </head>

  <body>
    <div id="header">
      <p>div id="header"</p>
      <ul id="top-menu">
        <li><a href="#">Accueil</a></li>
        <li><a href="#">Blog</a></li>
        <li><a href="#">Portfolio</a></li>
        <li><a href="#">Me contacter</a></li>
      </ul>
    </div> <!-- /header -->
    <div id="content">
      <p>div id="content"</p>
    </div> <!-- /content -->
  </body>
</html>

Au départ, notre page ressemble à ceci : 

[img_assist|nid=69|title=|desc=|link=none|align=none|width=600|height=106]

Le problème des éléments flottants

Si l'utilisation de float en CSS est très pratique pour faire flotter un élément à gauche ou à droite d'un autre, il faut garder à l'esprit qu'avec cette propriété :

  • l'élément flottant sort du flux de son élément parent ; en pratique, cela signifie qu'ils peuvent casser les styles concernant la couleur ou l'image de fond, ainsi que les marges internes et externes.
  • l'élément parent ne peut pas connaître les dimensions des éléments enfants flottants; difficile donc de les centrer automatiquement.

[img_assist|nid=67|title=|desc=Problèmes de layout avec menu flottant|link=none|align=none|width=600|height=71]

Il existe des bidouilles pour pallier à ces limitations, mais ne serait-il pas préférable de trouver une manière plus simple ?

La propriété display à la rescousse

Cette propriété CSS contrôle la manière dont l'élément va s'afficher dans le navigateur. Pour afficher les éléments les uns à la suite des autres et non les uns sous les autres, on peut utiliser display: inline. On met aussi un peu de marge pour séparer les éléments:

        #top-menu li {
          display: inline;
          margin-right: 0.5em;
        }

Pour centrer les éléments dans la page on utilisera text-align, qui fonctionne avec les éléments inline. On en profite pour supprimer les puces des éléments de liste avec list-style: none

      #top-menu {
        list-style: none;
        margin: 0;
        text-align: center;
      }

L'ennui avec les éléments en display: inline, c'est qu'on ne peut pas leur assigner une largeur fixe. On va donc utiliser le méconnu display: inline-block pour assigner une largeur aux liens. On va aussi ajouter quelques informations de style basiques :

          #top-menu li a {
            background-color: #EEE;
            display: inline-block;
            padding: 0.5em 0;
            text-align: center;
            width: 10em;
          }

 

Et voilà ! C'est tout ce dont vous avez besoin pour afficher un menu horizontal avec les éléments centrés.

[img_assist|nid=68|title=|desc=Le résultat final de notre menu|link=none|align=none|width=600|height=88]

Voici notre CSS finale : 

      #header {
        background-color: #CCC;
        padding: 1em 0 0;
      }

      #top-menu {
        list-style: none;
        margin: 0;
        text-align: center;
      }
        #top-menu li {
          display: inline;
          margin-right: 0.5em
        }
          #top-menu li a {
            background-color: #EEE;
            display: inline-block;
            padding: 0.5em 0;
            text-align: center;
            width: 10em;
          }

      #content {
        background-color: #CCFFCC;
        padding: 1em 0;
      }

Quelques détails sur inline-block

La propriété inline-block, comme son nom l'indique, combine les avantages des éléments de type block et des éléments inline. Comme un block, on peut lui assigner des dimensions, et comme un élément inline, il s'affichera côte à côte avec les autres élements au lieu de s'afficher en dessous.

Si cette propriété est encore peu utilisée, c'est parce qu'elle est mal gérée par les navigateurs anciens comme Internet Explorer 6. En effet dans ce dernier, seuls les éléments inline par défaut (majoritairement <span> et <a>) fonctionnent correctement quand on leur assigne la propriété display: inline-block. C'est pourquoi pour le menu ci-dessus je n'ai utilisé inline-block que pour les liens (<a>) et pas pour les éléments de menu (<li>).

Limitations

À cause de la gestion incomplète d'inline-block dans IE6, il est difficile de réaliser des menus déroulants (drop down) avec cette méthode si vous devez garder la compatibilité avec ce navigateur.

Par contre, pour les menus à un seul niveau n'hésitez pas !

[MISE À JOUR 15/03/2010] Il y a tout de même moyen de faire fonctionner inline-block dans tous les navigateurs modernes.

Comments

Merci !

J'ai bataillé pendant des heures avec mon menu en float, du fait de problèmes de marge avec les éléments en dessous.

J'avais essayé vite fait avec display:inline et compagnie mais sans succès. Cette page m'a permis de m'en sortir en deux secondes.

Je me dépêche de t'adresser mes remerciements avant de découvrir un effet de bord inattendu...

(Le lien ajouté lors de la "MISE À JOUR 15/03/2010" est cassé.)

Presque...

En fait, j'avais des problèmes parce que selon les pages, le contenu en dessous du menu est parfois

, parfois

dans un tableau. Et à cause des chevauchements de marge, j'avais un espacement différent.

Pour que ça fonctionne, j'ai ajouté display:table dans #top_menu :

#top-menu {
list-style: none;
margin: 0;
text-align: center;
display:table;
}

...

...

Désolé, apparemment les balises sont interprétées...

Il fallait lire :

En fait, j'avais des problèmes parce que selon les pages, le contenu en dessous du menu est parfois "hache un", parfois "hache un" dans un tableau. Et à cause des chevauchements de marge, j'avais un espacement différent.

Pour que ça fonctionne, j'ai ajouté display:table dans #top_menu :

#top-menu {
list-style: none;
margin: 0;
text-align: center;
display:table;
}

...

Merci pour ton aide sa m'a

Merci pour ton aide sa m'a beaucoup aidé a obtenir se que je voulais et surtout de manière propre !

Excellent

Génial, merci

Écrire un nouveau commentaire

The content of this field is kept private and will not be shown publicly.
  • Lines and paragraphs break automatically.
  • Web page addresses and e-mail addresses turn into links automatically.

More information about formatting options

By submitting this form, you accept the Mollom privacy policy.

© 2009-2011 Linalis.com | Tous les articles sont sous licence CC by-sa | login

Formations Drupal | Formations Pentaho | Formations LPI | Contactez-nous