Comment réduire le poids d'un menu en rollover avec beaucoup d'entrées ?

Il est indéniable que des boutons en «rollover» dans un menu apportent beaucoup à l'attrait d'une page web, mais ils ont aussi le défaut que chaque bouton demande deux images, et, même si aucune de ces images n'est bien lourde, leur multiplication finit par compter. Avec de «beaux» boutons à 2 ko, dix entrées se paient par 40 ko, ce qui est loin d'être négligeable pour un budget total dans la gamme 60-100 ko. Et on voudrait parfois monter à 15 ou 20 entrées...

Le HTML4 et les feuilles de style («CSS») permettent de réduire fortement le recours aux images, et donc d'alléger en proportion le poids du menu. Nous allons détailler deux solutions, autant à titre d'exercice sur les CSS que pour leur intérêt pratique.

Un menu en rollover et en «pur texte» !

Nous allons commencer par le menu ci-contre, qui fonctionne absolument sans aucune image. Difficile, donc, de faire plus léger !

Première étape : le menu au repos

L'ensemble sera enserré dans un bloc DIV général qui fixera la largeur totale et les paramètres importants pour les caractères (police, taille, couleur), le tout dans un cadre fin noir, soit avec la classe de style suivante :
    .menugeneral { 
          width:140px; 
          font-size:0.80em; font-family:verdana,sans-serif;
      	   color:#ffc; border:1px solid black;} 
Le fond de chaque bouton est un simple bloc DIV  avec une couleur de fond et une bordure simulant un bouton en relief (c.à.d. les côtés haut et gauche clairs, bas et droite sombres), ce qui s'obtient avec la classe suivante :
    .menuitem { 
          padding-left:12px;  /* marge à gauche */
          background:#578;    /* couleur de fond */
          border-bottom:1px solid black;  /*bord bas*/
          border-right:1px solid black;   /*bord droit*/          
          border-top:1px solid #cca;     /*bord haut*/
          border-left:1px solid #cca;     /*bord gauche*/
          } 
et on obtient un bouton  simplement en écrivant dedans ; aucun besoin de fixer de hauteur, le bloc s'adapte tout seul à ce qu'on met dedans.

On va maintenant former une maquette "statique" du menu, c.à.d. à réaliser l'empilement des boutons et à voir ce que cela donne. Vous voyez ci-dessous le codage et le résultat correspondant :

<div class="menugeneral">
  <div class="menuitem" id="m1">
   Entrée 1</div>
  <div class="menuitem" id="m2">
   Entrée 2</div>
  <div class="menuitem" id="m3">
  . . . . .
</div>

(Les différents ID seront nécessaires dans la suite pour la contrôle des rollovers.)
C'est le moment d'ajuster la largeur du menu en fonction de vos entrées, et ses diverses couleurs.

Deuxième étape : le style du bouton survolé

L'étape suivante consiste à déterminer le style du bouton enfoncé : il faudra prévoir un changement de couleur de fond, et aussi un changement dans la couleur des caractères, qu'on confiera plus tard à un effet hover. Pour cela, il suffit de donner une classe menuitema à l'un des boutons et d'ajuster ses propriétés jusqu'à obtenir l'effet voulu.

.menuitema {  
  padding-left:12px; 
  background:#d96; color:#600;
  border-top:1px solid black; 
  border-right:1px solid black; 
  border-bottom:1px solid #cca; 
  border-left:1px solid black;
		}
Par exemple, ici, pour donner l'effet d'un bouton enfoncé, on a interverti les côtés haut et bas de la bordure, et mis en noir le côté gauche. Logiquement, on aurait pu mettre le côté droit en clair, mais le résultat n'est pas heureux à l'œil.

Troisième étape : un style pour les liens

Comme toutes les écritures sont des liens, les couleurs seront commandées par des styles comme a:link, a:visited, etc... On définira donc une classe de style spéciale pour ces boutons :
.menulien {text-decoration:none;} 
        /*pour eviter tout soulignement*/
.menulien:link {color:#ffc;}
.menulien:visited {color:#ffc;}
.menulien:hover{color:#600;} /*couleur au survol*/
et on mettra class="menulien"...> dans tous les liens.

Quatrième étape : les scripts javascript

Le script pour changer le style du bouton devrait couler de source :
function hovermenu(idf) {
var stylem=trouvestyle(idf); /*objet "style" du bouton"*/
  if(stylem) {
    stylem.backgroundColor='#d96'
    stylem.borderBottomColor='#cca';
    stylem.borderLeftColor='black';
    stylem.borderTopColor='black';
   }
L'argument idf est l'identificateur du bouton. La première ligne sert à retrouve l'objet javascript "style" de ce bouton, grâce à la fonction trouvestyle() que nous avons décrite ailleurs (ou qu'on peut retrouver dans le code de cette page). Les lignes suivantes réalisent les changements entre les classes de style menuitem et menuitema (en fait, on n'aura plus besoin de cette dernière classe).

Le script pour restaurer le style du bouton devrait paraître tout aussi évident :
function restauremenu(idf) {
var stylem=trouvestyle(idf); /*objet "style" du bouton"*/
  if(stylem) {
    stylem.backgroundColor='#578'
    stylem.borderBottomColor='black';
    stylem.borderLeftColor='#cca';
    stylem.borderTopColor='#cca';
   }

Dernière étape : les écritures complètes

Il ne reste plus qu'à mettre en place tous les liens avec les onMouseOver et onMouseOut pour commander les rollovers.

Dans ce processus, chacune des entrées de notre maquette de menu, comme
<div class="menuitem" id="m1">Entrée 1</div> 
va être remplacée par une entrée complètement fonctionnelle :
<div class="menuitem" id="m1">
   <a class="menulien" href="...." 
	  onMouseOver="menuhover('m1')"
	  onMouseOut="menurestaure('m1')">Entrée 1</a>
</div>
Et voilà, il reste plus plus qu'à traiter tous les boutons de cette manière. Ouf !

A peine plus lourd : tout un menu juste avec deux images

Le menu précédent est certainement le plus léger qui soit parmi les menus avec des boutons, mais on peut lui faire deux reproches
— il n'est pas très folichon, et ses possibilités de personnalisation sont très limitées (essentiellement le choix des couleurs)
- sous Opera, le changement de couleur de fond ne marche pas (c.à.d. l'effet «bouton on/off» ). C'est dommage, même si, fort heureusement, il reste le changement de couleur sur les textes.

On peut pallier ces deux problèmes en dessinant deux images de boutons, sans texte, l'une pour la position au repos, l'autre pour la position survolée, qu'on utilisera en image de fond dans les blocs DIV des différents boutons. Bien sûr il n'y aura ni bordures ni couleur de fond. Vous voyez ci-contre un exemple d'un tel menu.

On va suivre les mêmes étapes que précédemment pour construire ce menu.

Voilà ! Le reste est une affaire d'inspiration dans le dessin des boutons. Ça fonctionne de la même façon dans IE5/6 (Mac/Windows) et dans les navigateurs conformes que nous avons essayés (Opera, NN6, Mozilla)... avec un petit bémol tout de même : Opera s'obstine à placer les écritures un pixel plus haut que tous les autres. Grrr...

Et pour finir...

Bien sûr, certains vont ensuite remarquer qu'on est limité aux polices passe-partout Times, Verdana, Arial, Helvetica, et donc regretter qu'on doive renoncer aux beaux effets typographiques qu'on pouvait avoir avec les rollovers classiques entièrement dessinés. Allons, ce n'est pas entièrement perdu : on peut garder les images de boutons sans texte et y superposer une deuxième image en *.gif à fond transparent ne contenant que ces écritures amoureusement dessinées. A vous de faire le code. Le tout restera sensiblement plus léger que les rollovers classiques.

Charles