Créer un menu adaptable à toutes les résolutions

Pour de tutoriel, nous allons réaliser un menu composé de cinq liens, chacun divisé en 3 éléments. Un curseur indiquera la section dans laquelle se trouve le visiteur, l'intitulé du lien et un sous titre donnant plus de détails sur le contenu de la page.

Le menu s'adapte automatiquement à la résolution de l'écran utilisé et les éléments superflus (comme le curseur et les sous-titres) sont masqués pour les petits écrans. Celui-ci se transforme en menu rétractable pour les utilisateurs de smartphones.

Aperçu du résultat final

Préparation

pour commencer, créez un nouveau répertoire et, dans celui-ci, créez un dossier "images" et un dossier "css".
Avec votre éditeur de code, créez un nouveau fichier nommé, pour l'exemple, "index.html" que vous placerez le dans le répertoire hébergeant votre réalisation ainsi qu'une feuille de styles nommée "menu-responsive.css" enregistrée dans le dossier "css". Pour donner un peu de style à cette réalisation, nous utiliserons trois images : 2 flèches de dimension 16 x12 pixels et un background de dimension 130 x 130 pixels. Vous pouvez créer vous meme ces images ou tout simplement télécharger celle utilisées pour cette démonstration. Ces éléments graphiques seront placés dans le dossier images que nous avons préalablement créé.
telecharger les images

Structure générale

Nous utiliserons ici une structure basée sur HTML5. Le menu sera donc placé dans un élément <nav>, lui meme contenu dans un élément <header>, et sera plutot simple dans sa structure : une liste non ordonnée dans laquelle chaque élément contiendra également une liste non ordonnée de trois items (curseur, intitulé du lien et sous-titre du lien).
Coté code, nous obtiendrons donc ceci :

<header>
<nav>
<ul>

<!-- premier lien -->
<li><ul>
<li></li>
<li></li>
<li></li>
</ul></li>
<!-- fin du premier lien -->

<!-- second lien -->

<li><ul>
<li></li>
<li></li>
<li></li>
</ul></li>
<!-- fin du second lien -->
<!-- etc ...-->
</ul>
</nav>
</header>

Mise en place des liens

Nous allons maintenant nous occuper de la création de nos liens. Chaque balise <ul> contenue dans une balise <li> sera enveloppée dans un lien. Comme expliqué précédemment, chaque lien est constitué de trois éléments correspondants aux trois balises <li> qui les composent. Ce qui nous donnera, dans l'ordre, l'intégration du curseur (actif pour la page en cours), l'intitulé du lien et enfin son sous-titre :

<!-- premier lien -->
<li><a href="#"><ul>
<li><img src="images/curseur-on.png" alt="" /></li>
<li>Page 1</li>
<li>Sous-titre lien 1</li>
</ul></li>
<!-- fin du premier lien -->

<!-- second lien -->

<li><a href="#"><ul>
<li><img src="images/curseur-off.png" alt="" /></li>
<li>Page 2</li>
<li>Sous-titre lien 2</li>
</ul></li>
<!-- fin du second lien -->

Un peu de CSS

Avant d'aller plus loin, nous allons modifier des éléments, par exemple supprimer les puces affichées sur les listes, modifier la couleurs de liens, etc. Nous en profiterons également pour définir un style à notre balise <body> en lui donnant un motif de fond, une typographie et une taille de police adaptée. Dans notre feuille de style menu-responsive.css, nous allons donc écrire :

body{width: 100%;
/*Le body prendra toute la largeur de la fenêtre*/

background: url("../images/background.jpg") repeat;
/*On choisis un fond pour la page et on le répète à l'infini*/

font-size: 14px;
/*on choisi la taille des caractères*/

margin: 0;
/*On supprime les marges par défaut de certains navigateurs*/
font-family: arial, sans-serif;}
/* On choisi les polices par défaut*/

li{list-style-type: none;}

a{text-decoration: none;color: #000;}

a:hover{color: #0065cc;}

Mise en place du menu

Nous partirons du principe que le site dans lequel sera intégré le menu fera 960 pixels de largeur maximale. Celui-ci sera placé en haut de la fenetre du navigateur et devra toujours etre au centre de l'écran. Nous allons donc envelopper notre élément <na> dans un <div> ayant pour id="center". Coté HTML, nous ajouterons donc :

<header>
<div id=
"background-menu"></div>
<nav>
<ul>

<!-- Liens ->
</ul>
</nav>
</div>
</header>

Et coté CSS :

#center{max-width:960px;margin: auto;}

Nous allons maintenant intégrer tous les liens horizontalement, puis nous centrerons le texte dans chacun d'eux. nous créons ensuite des classes pour définir un style à chaque élément : Les intitulés de liens auront un visuel renforcé ainsi qu'une ombre interne blanche pour leur apporter un peu de relief. Les sous-titres auront une taille plus faible et seront affichés en italique. Définissons tout d'abord leurs styles dans notre feuille menu-responsive.css :

nav ul{margin-top: -40px;padding: 0;position: relative;
z-index: 99;} /*On spécifie le z-index*/

nav ul li{width: 12.71em;display:inline-block;text-align:center;}

.sous-titre{font-style: italic;font-size: 0.857em;}

.bold{font-weight: bold;text-shadow: 0 1px 1px rgba(255, 255, 255, 1);}

Intégrons maintenant nos balises HTML et attribuons leur leurs règles de styles spécifiques :

<nav>

<!-- premier lien -->
<ul>
<li><a href="#"><ul>
<li><img src="images/curseur-on.png" alt="" /></li>
<li class="bold">Page 1</li>
<li class="sous-titre">Sous-titre "Lien 1"</li>
</ul></a></li>
<!-- second lien -->
<li><a href="#"><ul>
<li><img src="images/curseur-off.png" alt="" /></li>
<li class="bold">Page 2</li>
<li class="sous-titre">Sous-titre "Lien 2"</li>
</ul>
</a></li>

... <!-- de meme pour les autres liens -->

</ul>
</nav>
</div>
</header>

Ajout du background

Nous allons maintenant créer un fond en dégradé, que nous réaliserons avec CSS3. La syntaxe des dégradés CSS3 et assurer une compatibilité avec les différents navigateurs étant toujours un peu laborieux, je vous propose d'utiliser un très bon outil en ligne qui se chargera de nous fournir le code CSS3 du dégradé voulu et un simple copiercoller suffira à son intégration dans notre feuille de styles.

Découvrir Ultimate CSS Gradient Generator

L'interface de module est relativement intuitive et les habitués de Photoshop y prendrons très rapidement leurs marques.

Plutot que d'appliquer notra dégradé directement à l'élément <nav>, je vous conseille de créer une <div> (ici ayant pour id "background-menu" et de la placer juste avant la balise <div="center">. Cette solution nous donnera plus de flexibilitté pour afficher le fond comme bon nous semble :

<body>
<header>
<div id="background-menu"></div>
<div id="center">
...

Le HTML étant maintenant en place, occupons nous de la partie CSS du background. Celui-ci cevra couvrir toute la largeur du site, avoir une fine bordure, une ombre portée et évidemment afficher un dégradé. Nous appliquerons une marge supérieure négative au menu afin de placer celui-ci au dessus du dégradé :

nav ul{
margin-top: -40px;
padding: 0;
position: relative; /*On spécifie un positionnement*/
z-index: 99; /*On spécifie le z-index*/
}

#background-menu{
width: 100%;
height: 6em;
border-bottom: 2px solid #ececec;
-ms-box-shadow: 1px 1px 3px #818181;
-o-box-shadow: 1px 1px 3px #818181;
-webkit-box-shadow: 1px 1px 3px #818181;
-moz-box-shadow: 1px 1px 3px #818181;
box-shadow: 1px 1px 3px #818181;
background:background: #b1b1b1; /* Old browsers */
background: -moz-linear-gradient(top, #b1b1b1 0%, #c3c3c3 50%, #bdbdbd 51%, #dbdbdb 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#b1b1b1), color-stop(50%,#c3c3c3), color-stop(51%,#bdbdbd), color-stop(100%,#dbdbdb)); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, #b1b1b1 0%,#c3c3c3 50%,#bdbdbd 51%,#dbdbdb 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, #b1b1b1 0%,#c3c3c3 50%,#bdbdbd 51%,#dbdbdb 100%); /* Opera 11.10+ */
background: -ms-linear-gradient(top, #b1b1b1 0%,#c3c3c3 50%,#bdbdbd 51%,#dbdbdb 100%); /* IE10+ */
background: linear-gradient(to bottom, #b1b1b1 0%,#c3c3c3 50%,#bdbdbd 51%,#dbdbdb 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#b1b1b1', endColorstr='#dbdbdb',GradientType=0 ); /* IE6-8 */
}

La base de notre menu est enfin en place. Si celui-ci réagit bien sur les grandes résolutions, on se rend vite compte que de nombreux soucis d'affichage apparaissent sur des fenetres de navigateurs plus petites.

Complétons notre gamme d'outils

Si ce n'est déjà fait, installez le plug-in Web Developer pour Firefox. Grace à lui, nous allons pouvoir visionner le comportement du menu en fonction des dimensions du navigateur. Un fois le plug-in installé, allez dans l'onglet "Redimensions" et cliquez sur "afficher la taille de la fenetre dans la barre de titre".

Déterminer les points de rupture

Grace à Web Developer, nous constatons qu'un premier problème survient lorsque l'affichage du navigateur est égal ou inférieur à 905 pixels. Grace au media queries, nous allons adapter la présentations des liens en masquant les sous-titres, en modifiant la largeur de l'élément <nav> et des liens eux-memes. Le but: garder un système de navigation d'origine jusqu'à une largeur minimale de 800 pixels. En dessous de cette résolution, nous basculerons vers un menu rétractable. Nous ajoutons donc dans notre fichier CSS :

/*AFFICHAGE 906 PIXELS*/
@media screen and (max-width: 905px){
nav{max-width: 44em;margin: auto;}
nav ul li{
max-width: 8.35em;}
.sous-titre{
display: none;}}
/*FIN AFFICHAGE 906 PIXELS*/

Optimiser pour les smartphones

Maintenant que le menu est adapté pour les écrans de bureau et la majorité des tablettes, il nous faut l'optimiser pour une utilisation sur smartphones et écrans de moins de 800 pixels. Les liens seront alignés à la vertical et cliquables sur toutes la largeur de l'écran. Afin d'améliorer l'affichage coté utilisateur, un bouton "menu" permettra aux usagers de rétracter les liens si besoin.

Nous allons donc créer et ajouter aux liens une classe nommée "smartphones-links" afin de pouvoir leur donner un design, les rendants ainsi plus visibles. La hauteur des ces liens sera de 40 pixels pour une navigation confortable et définirons une largeur maximale de 800 pixels pour ce mode de navigation. Coté HTML :

<nav>
<ul>

<!-- premier lien -->
<li><a href="#">
<ul class="smartphones-links">
<li><img src="images/curseur-on.png" alt="" /></li>
<li class="bold">Page 1</li>
<li class="sous-titre">Sous-titre "Lien 1"</li>
</ul></a></li>
<!-- second lien -->
<li><a href="#">
<ul class="smartphones-links">
<li><img src="images/curseur-off.png" alt="" /></li>
<li class="bold">Page 2</li>
<li class="sous-titre">Sous-titre "Lien 2"</li>
</ul>
</a></li>

... <!-- de meme pour les autres liens -->

</ul>
</nav>
</div>
</header>

Et pour notre code CSS :

/*AFFICHAGE <800 PIXELS*/
@media screen and (max-width: 800px){
nav {max-width: 800px;margin-top: 100px;}

nav ul li{display:inline;}

.smartphones-links{
height: 40px;
margin-top: 1px;
padding-top: 20px;
border-top: 1px solid #fff;
border-bottom: 1px solid #fff;
background-color: #d9d8d7;
position: relative;
-ms-box-shadow: 1px 1px 3px #818181;
-o-box-shadow: 1px 1px 3px #818181;
-webkit-box-shadow: 1px 1px 3px #818181;
-moz-box-shadow: 1px 1px 3px #818181;
box-shadow: 1px 1px 3px #818181;
}
}

Ajout du bouton Menu

Occupons-nous du bouton "menu". Nous allons dans un premier temps l'ajouter à notre code HTML, juste au-dessous de l'ouverture de la <div id="center">. Le bouton est simplement constitué d'un lien placé dans une<idv id="bouton-menu">. Je lui attribue égamenment la class "bold" afin de renforcer son visuel. Intégrons le à notre code HTML :

<header>
<div id=
"background-menu"></div>
<div id=
"center">
<div id=
"bouton-menu"><a href="#" class="bold">MENU</a></div>
<nav>

Occupons nous maintenant de son affichage. Celui-ci ne doit etre visible qu'en dessous de 800 pixels de largeur de résolution. Nous allons donc lui aplliquer un "display:none" par défault et un "display:block" pour notre media queries (max-width: 800px). Dans notre feuille css :

/*en dehors des règles media querie */
#bouton-menu{
display: none;
}

/*dans la définition de (media queries max-width: 800px)*/
#bouton-menu{display: block;}
#bouton-menu a{
width: 200px;
height: 60px;
margin: auto;
margin-top: -90px;
margin-bottom: -80px;
padding-top: 30px;
text-align: center;
font-size: 1.4em;
display: block;
position: relative;
z-index: 99;
-ms-box-shadow: 1px -1px 3px #818181;
-o-box-shadow: 1px -1px 3px #818181;
-webkit-box-shadow: 1px -1px 3px #818181;
-moz-box-shadow: 1px -1px 3px #818181;
box-shadow: 1px -1px 3px #818181;
}
#bouton-menu a:hover{
color: #0065cc;
border-left: 1px solid #cecece;
border-right: 1px solid #cecece;
background: #d6d6d6;
background: -moz-linear-gradient(top, #d6d6d6 0%, #bdbdbd 79%, #c3c3c3 85%, #b1b1b1 100%);
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#d6d6d6), color-stop(79%,#bdbdbd), color-stop(85%,#c3c3c3), color-stop(100%,#b1b1b1));
background: -webkit-linear-gradient(top, #d6d6d6 0%,#bdbdbd 79%,#c3c3c3 85%,#b1b1b1 100%);
background: -o-linear-gradient(top, #d6d6d6 0%,#bdbdbd 79%,#c3c3c3 85%,#b1b1b1 100%);
background: -ms-linear-gradient(top, #d6d6d6 0%,#bdbdbd 79%,#c3c3c3 85%,#b1b1b1 100%);
background: linear-gradient(to bottom, #d6d6d6 0%,#bdbdbd 79%,#c3c3c3 85%,#b1b1b1 100%);
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#d6d6d6', endColorstr='#b1b1b1',GradientType=0 );
-ms-box-shadow: inset 1px 1px 3px #818181;
-o-box-shadow: inset 1px 1px 3px #818181;
-webkit-box-shadow: inset 1px 1px 3px #818181;
-moz-box-shadow: inset 1px 1px 3px #818181;
box-shadow: inset 1px 1px 3px #818181;
}

Rendre le menu rétractable

Donnons maintenant aux visiteurs mobiles la possibilité de rétracter le menu. Pour ce faire, nous allons utiliser la bibliothèque JQuery et la fonction "slideToggle". Pour pouvoir utiliser la bibliothèque JQuery, il nous faut tout d'abord l'appeller dans notre feuille HTML en insérant le codes uivant dans le <head></head> de notre page :

<script type="text/javascript"
src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>

Pour pouvoir faire fonctionner notre slide, nous allons ajouter un id, nommé "menu-scroll", au lien contenu dans notre <div> "bouton-menu". Celui-ci va nous permettre d'écouter et de détecter un évènement qui déclenchera le slide. Le slide sera alors appliqué à l'élément <nav> grace à la fonction "slideToggle". Nous lui attribuerons également une vitesse de rétractation plutot lente. Intégrons donc ce code dans notre page HTML, juste avant </body> :

<div id="center">
<div id="bouton-menu"><a href="#" id="menu-scroll" class="bold">MENU</a></div>
<nav>
<ul>

...
</header>
<script>$("#menu-scroll").click(function (){$("nav").slideToggle("slow")});</script>
</body>
</html>

Ca y est, notre menu coulisse bien lorsque nous cliquons sur le bouton "menu". Seule ombre au tableau, les éléments se chevauchent de façon anarchique ... Nous aloons y rmédier grace à quelques lignes de code CSS en utilisant la propriété Z-index :

/*dans nos règles générales*/
#background-menu{
position: relative; /*On spécifie un positionnement*/
z-index: 10;/*on spécifie un z-index de 10 pour masquer les éléments ayant un z-index inférieur*/
... }

/*dans les règles @media screen and (max-width: 800px)*/
nav ul{ z-index: 9;}

Supprimer les curseurs

Pour supprimer les curseurs, nous allons d'abord leur ajouter une classe "curseur" dans le code HTML. Puis, dans la media queries dédiée aux écrans de 800 pixels et moins, nous lui appliquerons un "display:none;". Coté HTML :

<div id="center">
<div id="bouton-menu"><a href="#" id="menu-scroll" class="bold">MENU</a></div>
<nav>
<ul>

<li><a href="#"><ul class="smartphones-links">
<li class="curseurs"><img src="images/curseur-on.png" alt="" /></li>
<li class="bold">Page 1</li>
<li class="sous-titre">Sous-titre "Lien 1"</li>
</ul>

</a></li>
...
<!-- ainsi de suite -->

Coté CSS :

/*dans les règles @media screen and (max-width: 800px)*/
.curseurs{display: none;}

Notre création d'un menu Responsive est maintenant terminée. Il ne vous reste plus qu'à retravailler un peu le code CSS afin de personnaliser cet exemple et le mettre en accord avec le design de votre (futur) site.