Comment appliquer des styles spécifiques à la page en cours dans un menu ?

Astuce par (Lyon, France)
Créé le , mis à jour le (131181 lectures)
Tags : css, ergonomie, php, html, actif, active, navigation, en cours

C'est un besoin courant en ergonomie web: marquer visuellement un lien dans un menu de navigation comme «actif» ou «en cours». Pour une page donnée du site, on voudra par exemple mettre en évidence le lien vers la page en question (si le menu propose un accès direct à chaque page) ou bien le lien vers la rubrique ou partie du site dans laquelle le visiteur se trouve.

La pseudo-classe :active? Rien à voir.

Les débutants en HTML et CSS cherchent souvent à utiliser la pseudo-classe CSS :active pour arriver à ce résultat. C'est une erreur, qui relève d'une confusion entre «page active» ou «lien actif» et «état actif» d'un élément HTML.

La pseudo-classe :active permet de donner des styles à un élément qui ne seront appliqués que lorsque l'élément sera dans sont état «actif», c'est à dire pour un lien ou un bouton lorsqu'il sera cliqué. Cela correspond au troisième état de ce que l'on appelle un «bouton trois états» dans les interfaces informatiques. Notez que sur le Web, on utilise assez peu ce troisième état (élément cliqué ou activé), car cliquer sur un lien ou un bouton d'envoi de formulaire a généralement comme conséquence de changer de page… ce qui suffit déjà largement à indiquer à l'utilisateur que son action (cliquer) a eu un effet. De plus, designer un troisième état peut être une perte de temps lorsque cet état ne sera visible qu'une fraction de seconde (la page en cours étant remplacée par une autre lors du clic).

Marquer la page en cours dans un menu de navigation

Pour éviter ce genre de confusion, parlons plutôt de page ou rubrique «en cours», et pas de page ou rubrique «active».

Pour marquer la page en cours dans un menu, on ne pourra pas se reposer sur CSS uniquement. Il n'existe pas de pseudo-classe :current ou chose de ce genre, et pour une bonne raison: le navigateur n'aurait aucun moyen fiable de reconnaitre quel lien pointe vers la page ou rubrique en cours. La page, passe encore, mais pour la rubrique c'est une autre paire de manche. En effet, le concept de rubrique ou «partie» ou «zone» n'a aucune équivalence technique en HTML.

C'est donc à vous de déterminer quels liens il faut différencier visuellement des autres, et de créer les styles CSS correspondants.

Concrètement, si on a une série de liens dans un menu, on pourra appliquer une classe spécifique au lien souhaité. Par exemple si j'ai trois liens vers les pages «À propos», «Contact» et «Mentions légales», et que je me trouve sur la page «Contact», je peux avoir le code HTML suivant:

<a href="/apropos.html">À propos</a> ⋅
<a href="/contact.html" class="en-cours">Contact</a> ⋅
<a href="/mentions.html">Mentions légales</a>

Et pour la page «Mentions légales», le code HTML devra être modifié ainsi:

<a href="/apropos.html">À propos</a> ⋅
<a href="/contact.html">Contact</a> ⋅
<a href="/mentions.html" class="en-cours">Mentions légales</a>

Exemple plus poussé

Pour un menu de navigation plus classique codé avec une liste non ordonnée, on aura le choix de placer la classe (ou éventuellement l'identifiant) distinctif sur les liens (éléments a) ou bien sur les items de liste (éléments li). Voici un exemple pour un site fictif de recettes de cuisine:

<ul id="navigation">
	<li><a href="/">Accueil</a></li>
	<li><a href="/entree/">Entrées</a></li>
	<li id="en-cours"><a href="/poisson/">Poissons</a></li>
	<li><a href="/viande/">Viandes</a></li>
	...
	<li><a href="/dessert/">Desserts</a></li>
</ul>

Cet exemple correspond au code HTML que l'on trouvera sur les différentes pages de la section «Poissons» de ce site. Pour toute page de la section «Entrées», on aura un code HTML légèrement différent pour ce menu, avec un attribut id (ou une classe si on a choisi d'utiliser une classe) que se «déplace» sur le li correspondant.

Côté CSS, maintenant, vous avez carte blanche. Pour garder le même exemple, on pourrait avoir les styles suivants:

/* Styles pour tous les liens du menu */
#navigation a {
	padding: 4px 10px; 
	font-weight: bold;
	text-decoration: none;
	color: #666;
}

/* Styles pour les liens survolés ou sélectionnés au clavier*/
#navigation a:hover, #navigation a:focus {
	text-decoration: underline;
	color: #444;
}

/* Styles pour la rubrique en cours */
#navigation #en-cours a {
	background-color: #91BD09;
	color: #fff;

 

Avec ce code CSS, les liens du menu sont affichés sans soulignement et en gris. Au survol ou au focus, ils sont affichés avec un soulignement et un gris plus sombre. Quant au lien correspondant à la rubrique active, pour peu que le li correspondant dans le code HTML porte bien l'identifiant (attribut id) en-cours, il sera affiché en blanc sur fond vert.

Gérer une classe ou identifiant «en cours» pour un site dynamique

Si votre site est «statique», c'est-à-dire si vos pages sont des pages HTML séparées, vous devrez avoir un code HTML légèrement différent sur chaque page, pour placer votre «marqueur» (classe ou identifiant de votre choix) sur le bon élément. Il faudra faire ces modifications à la main, pour chaque page.

Mais si votre site est généré dynamiquement, à l'aide de scripts PHP ou d'un autre langage serveur, il est probable que votre menu de navigation n'est pas dupliqué sur chaque page, mais plutôt généré par des gabarits (templates), ou appelé via une fonction PHP include().

Cela signifie que votre menu n'existe qu'à un seul endroit. Dans ce cas, comment générer un code HTML différent pour chaque page ou rubrique à partir de cette source unique?

Cela dépendra de la technologie utilisée. Si vous travaillez avec un CMS, lisez la documentation ou posez la question à la communauté pour savoir de quelle manière vous pouvez placer votre identifiant ou classe au bon endroit pour chaque page. Si vous utilisez uniquement la fonction include() en PHP comme décrit dans ce tutoriel, vous pouvez fonctionner ainsi:

1. Sur chaque page PHP, déclarer une variable comme ceci:

<?php $nav_en_cours = 'rubrique1'; ?>

2. Dans le fichier PHP qui contient votre menu, le code du menu devra ressembler à ceci:

<ul id="navigation">
	<li<?php if ($nav_en_cours == 'rubrique1') {echo ' id="en-cours"';} ?>><a href="/rub1/">Rubrique 1</a></li>
	<li<?php if ($nav_en_cours == 'rubrique2') {echo ' id="en-cours"';} ?>><a href="/rub2/">Rubrique 2</a></li>
</ul>

Rentrer dans les détails demanderait un tutoriel complet. Retenez juste que réussir ce genre de chose vous demandera une connaissance correcte des bases les plus élémentaires de PHP, et que copier-coller ce dernier exemple ne vous servira à rien si vous n'en avez pas compris le principe à la première ou deuxième lecture.

De même, si vous travaillez avec le langage de template d'un CMS, il vous faudra bien connaitre ce langage de template et les possibilités du CMS… ou bien vous renseigner correctement.

Une solution côté client, en JavaScript?

Jusqu'ici nous avons écrit qu'il fallait écrire ou générer un code HTML avec un «marqueur» (classe ou identifiant) pour le ou les items de menu à mettre en valeur. C'est globalement vrai mais on pourrait aussi envisager une solution utilisant JavaScript.

Pour cette dernière, il s'agit de comparer l'URL de la page chargée et la valeur de l'attribut href pour les différents liens du menu de navigation. Simple sur le papier, mais un peu plus compliqué en pratique; il y aura quelques subtilités à prendre en compte.

On pourra par exemple lire l’article Vous êtes ici ! de Clément Hardouin, qui propose un script JS pour identifier le lien correspondant à la page en cours dans un menu.