Réalisons un menu déroulant qui soit à la fois portable, utilisable sans JavaScript et accessible aux personnes handicapées.
Parfois, pour des raisons de place sur la page, on ajoute un menu dynamique. Seulement qui dit dynamique dit obligation d'avoir un navigateur supportant le langage de script utilisé. Comment faire un menu qui fonctionne sans ce langage ? Comment le rendre utilisable par tous, quelles que soient les capacités du matériel ou de l'internaute ? Nous allons tenter de relever ce défi pas à pas.
Il est important que vous gardiez à l'esprit que le principal interêt d'un menu dynamique est de donner un double niveau d'entrée. Un clic sur un menu ouvre une page détaillant les éléments du sous-menu et permettant au visiteur indécis de faire un choix. Un survol de ce même lien fait apparaître un sous-menu permettant à l'internaute d'accéder en un clic à l'information, s'il a déjà fait son choix.
Si vous êtes aveugle, vous ne devriez percevoir aucune différence entre les 3 étapes du menu puisque c'est le but de l'article. De plus, les liens ne sont pas renseignés et renvoient sur la même page.
Nous allons tout d'abord réaliser la page à proprement parler sans nous soucier ni du rendu, ni de l'interactivité mais en prenant en compte l'accessibilité.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>
Test de menu
</title>
<meta http-equiv="Content-Type" content=
"text/html; charset=iso-8859-1">
</head>
<body lang="fr">
<p id="access">
[<a href="#" accesskey="0">Politique
d'accessibilité</a>]
[<a href="#texte" accesskey="1">Aller
au contenu</a>]
[<a href="#menu1" accesskey="2">Aller
au menu</a>]
</p>
<div id="texte">
<p>
Scrahascrit mohotis, rusn scratedeus en
pronohus cremaquoranis. Phel vup, etrop
usnuquori mu nutram demol. Stobaquadore
ilirher, hisch themipam ol asnuplue thoticrat.
Spem ahospum quiduhiquiduer, la scat satidam
aspadront. Rhasadit in amuv omebras. Ecepore
alaps sni taspes itocont. Ubriplue pribinatis,
iquiduh orem ipu rimalius quidematanis. Arinam
in cespus cinilas. Crequad ofopriem, quadop
molines dad rasalon ilaspant. Igopr brugipam
va gidosmam vobarotis. Smoquad thegecr al
aniquidem cunitrant. Lofoti mapopr, cratr
phiropeus cer togibit crahego.
</p>
<p>
Apher est. Cedinam cop uco sischa quoru
psilascham est. Dipsam in rhigustam
quorabanatis. Phenebron in spomamus
stemeprotis. Anusch initiem pu tescha
thehescranis. Ohiph plisch bolotam lu ecananis
hut thehaquoratis. Quorav scem mesciem me
cepemer pi aspitront. Ephaquad quorol ev
psivaspem vehant. Usmispeus, ocimus men
rilecit naphanis. Rutrue som bal mepres tof
iproplem est. Smin scridupeus lovorher, na
esiquad rulam itrisner. Quadisch udepli
upraplant, rac muph truvibeus baranis.
</p>
</div>
<hr>
<p id="menu1">
<a href="#" title="Menu 1">Animaux :</a>
</p>
<ul id="ssmenu1">
<li>
<a href="#" title="Sous-menu 1">Girafe</a> ;
</li>
<li>
<a href="#" title="Sous-menu 2">Pingouin</a>.
</li>
</ul>
<p id="menu2">
<a href="#" title="Menu 2">Villes :</a>
</p>
<ul id="ssmenu2">
<li>
<a href="#" title="Sous-menu 1">Lisbonne</a> ;
</li>
<li>
<a href="#" title="Sous-menu 2">Varsovie</a> ;
</li>
<li>
<a href="#" title="Sous-menu 3">Lima</a> ;
</li>
<li>
<a href="#" title="Sous-menu 4">Nairobi</a>.
</li>
</ul>
<p id="menu3">
<a href="#" title="Menu 3">Personnages :</a>
</p>
<ul id="ssmenu3">
<li>
<a href="#" title="Sous-menu 1">Gandhi</a> ;
</li>
<li>
<a href="#" title="Sous-menu 2">César</a> ;
</li>
<li>
<a href="#" title="Sous-menu 3">Gengis
Khan</a>.
</li>
</ul>
<p id="copy">
©Blablablabla
</p>
</body>
</html>
Les différents éléments de la page sont identifiés grâce à l'attribut id afin de pouvoir les enjoliver et les manipuler par la suite.
Vous pouvez tester cette étape dans votre navigateur.
Le menu se présente sous la forme d'une liste à puce numérotée en bas de page, ce qui permet de lire directement le contenu de la page. La typographie a été respectée en ce qui concerne les listes avec utilisation d'un point-virgule précédé d'une espace insécable afin d'éviter les retours à la ligne disgracieux, même s'ils sont improbables dans notre cas. Ceci permet aussi une meilleure accessibilité puisqu'une synthèse vocale marque des pauses lorsqu'elle en rencontre. Nous pourrions aussi utiliser des virgules.
Puisque nous parlons d'accessibilité, nous avons des liens permettant de naviguer dans la page. En effet, si un aveugle se rend compte à la lecture du contenu que la page ne correspond pas à son attente, il doit pouvoir aller directement au menu. Il retournera en haut de la page et trouvera les liens adéquats. De plus, ces liens sont pourvus d'un accélérateur, via accesskey, qui permet de les lancer grâce à une combinaison de touches. Il existe plusieurs écoles quant à l'ordre de ces liens. Pour ma part, je recommande de commencer par la politique d'accessibilité car un aveugle peut tomber sur n'importe quelle page, depuis un moteur de recherche par exemple, et ces informations lui sont utiles. Vous pouvez consulter notre politique d'accessibilité pour en savoir plus.
C'est bien beau, me direz-vous, mais nous sommes loin d'avoir une page habillée et dynamique. Certes mais notez toutefois que ce rendu sera celui d'un navigateur texte, par exemple. Vous voyez aussi que même ainsi, il est possible de cliquer sur « Animaux » pour avoir les détails des pages « Girafe » et « Pingouin » ou directement sur ces liens.
Nous allons maintenant passer au rendu de notre page HTML grâce aux CSS. Pour cet exemple, j'ai choisi un rendu sobre, tout comme le contenu de la page n'est formé que de simples paragraphes. Il est bien sûr possible de remplacer les couleurs de fond par des images et d'enrichir le contenu de photos ou de tableaux.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>
Test de menu
</title>
<meta http-equiv="Content-Type" content=
"text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href=
"menu.css" title="défaut">
</head>
<body lang="fr">
<p id="access">
[<a href="#" accesskey="0">Politique
d'accessibilité</a>]
[<a href="#texte" accesskey="1">Aller
au contenu</a>]
[<a href="#menu1" accesskey="2">Aller
au menu</a>]
</p>
<div id="texte">
<p>
Scrahascrit mohotis, rusn scratedeus en
pronohus cremaquoranis. Phel vup, etrop
usnuquori mu nutram demol. Stobaquadore
ilirher, hisch themipam ol asnuplue thoticrat.
Spem ahospum quiduhiquiduer, la scat satidam
aspadront. Rhasadit in amuv omebras. Ecepore
alaps sni taspes itocont. Ubriplue pribinatis,
iquiduh orem ipu rimalius quidematanis. Arinam
in cespus cinilas. Crequad ofopriem, quadop
molines dad rasalon ilaspant. Igopr brugipam
va gidosmam vobarotis. Smoquad thegecr al
aniquidem cunitrant. Lofoti mapopr, cratr
phiropeus cer togibit crahego.
</p>
<p>
Apher est. Cedinam cop uco sischa quoru
psilascham est. Dipsam in rhigustam
quorabanatis. Phenebron in spomamus
stemeprotis. Anusch initiem pu tescha
thehescranis. Ohiph plisch bolotam lu ecananis
hut thehaquoratis. Quorav scem mesciem me
cepemer pi aspitront. Ephaquad quorol ev
psivaspem vehant. Usmispeus, ocimus men
rilecit naphanis. Rutrue som bal mepres tof
iproplem est. Smin scridupeus lovorher, na
esiquad rulam itrisner. Quadisch udepli
upraplant, rac muph truvibeus baranis.
</p>
</div>
<hr>
<p id="menu1" class="menu">
<a href="#" title=
"Menu 1">Animaux<span> :</span></a>
</p>
<ul id="ssmenu1" class="ssmenu">
<li>
<a href="#" title=
"Sous-menu 1">Girafe</a><span> ;</span>
</li>
<li>
<a href="#" title=
"Sous-menu 2">Pingouin</a><span>.</span>
</li>
</ul>
<p id="menu2" class="menu">
<a href="#" title=
"Menu 2">Villes<span> :</span></a>
</p>
<ul id="ssmenu2" class="ssmenu">
<li>
<a href="#" title=
"Sous-menu 1">Lisbonne</a><span> ;</span>
</li>
<li>
<a href="#" title=
"Sous-menu 2">Varsovie</a><span> ;</span>
</li>
<li>
<a href="#" title=
"Sous-menu 3">Lima</a><span> ;</span>
</li>
<li>
<a href="#" title=
"Sous-menu 4">Nairobi</a><span>.</span>
</li>
</ul>
<p id="menu3" class="menu">
<a href="#" title=
"Menu 3">Personnages<span> :</span></a>
</p>
<ul id="ssmenu3" class="ssmenu">
<li>
<a href="#" title=
"Sous-menu 1">Gandhi</a><span> ;</span>
</li>
<li>
<a href="#" title=
"Sous-menu 2">César</a><span> ;</span>
</li>
<li>
<a href="#" title="Sous-menu 3">Gengis
Khan</a><span>.</span>
</li>
</ul>
<p id="copy">
©Blablablabla
</p>
</body>
</html>
Peu de changement, si ce n'est l'ajout du lien vers la feuille de style dans le head et des spans dans les menus pour pouvoir cacher la ponctuation.
body {
background-color:#FFF;
color:#333;
font-family:Verdana, Geneva, Arial,
Helvetica, sans-serif;
margin:0;
padding:0;
}
hr {
display:none;
}
.menu, .ssmenu {
background-color:#FFF;
color:#333;
border:0.1em solid #333;
margin:1em;
}
.menu span, .ssmenu span {
display:none;
}
.menu a, .ssmenu a {
text-decoration:none;
color:#333;
}
.menu {
padding:0 1em;
}
.ssmenu {
padding:0;
}
.ssmenu li {
list-style-type:disc;
list-style-position:inside;
padding-left:0.2em;
color:#F93;
}
.ssmenu li:hover, .ssmenu a:hover,
.ssmenu a:focus {
background-color:#F93;
color:#FFF;
}
.ssmenu li:hover {
list-style-type:circle;
}
#access a, #texte a {
color:#F93;
}
#access a:hover, #texte a:hover {
text-decoration:none;
}
#access a:focus, #texte a:focus {
text-decoration:none;
background-color:#F93;
color:#FFF;
}
#access {
margin:1em;
padding:0;
}
#texte {
text-align:justify;
margin:1em;
padding:0;
}
#texte p {
text-indent:1em;
}
#copy {
padding:1em;
margin:0;
text-align:center;
}
Nous réglons tout d'abord les paramètres globaux de la page. Ensuite, nous traitons la partie accessibilité et nous cachons la barre de séparation et la ponctuation dans le menu. Nous mettons en forme les menus et sous-menus ainsi que les liens qu'ils contiennent. Enfin nous traitons le texte et le bas de page.
Le point sensible concerne les :hover. En effet, le survol des éléments d'une liste n'étant pas toujours bien compris par les navigateurs, on ajoute un survol des liens. De même la partie :focus concerne les personnes qui ne peuvent utiliser une souris et naviguent au clavier. Généralement, la touche Tab permet de sauter de lien en lien, ce que vous pouvez essayer sur votre navigateur.
Vous pouvez tester cette étape.
Bon c'est bien beau mais où il est le menu dynamique, hum ? Et bien on y arrive.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>
Test de menu
</title>
<meta http-equiv="Content-Type" content=
"text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href=
"menu.css" title="défaut">
<script type="text/javascript" src="menu.js">
</script>
</head>
<body lang="fr" onload="Chargement();">
<p id="access" onmouseover="CacherMenus();">
[<a href="#" accesskey="0"
onfocus="CacherMenus();">Politique
d'accessibilité</a>]
[<a href="#texte" accesskey="1"
onfocus="CacherMenus();" >Aller
au contenu</a>]
[<a href="#menu1" accesskey="2"
onfocus="CacherMenus();">Aller
au menu</a>]
</p>
<div id="texte" onmouseover="CacherMenus();">
<p>
Scrahascrit mohotis, rusn scratedeus en
pronohus cremaquoranis. Phel vup, etrop
usnuquori mu nutram demol. Stobaquadore
ilirher, hisch themipam ol asnuplue thoticrat.
Spem ahospum quiduhiquiduer, la scat satidam
aspadront. Rhasadit in amuv omebras. Ecepore
alaps sni taspes itocont. Ubriplue pribinatis,
iquiduh orem ipu rimalius quidematanis. Arinam
in cespus cinilas. Crequad ofopriem, quadop
molines dad rasalon ilaspant. Igopr brugipam
va gidosmam vobarotis. Smoquad thegecr al
aniquidem cunitrant. Lofoti mapopr, cratr
phiropeus cer togibit crahego.
</p>
<p>
Apher est. Cedinam cop uco sischa quoru
psilascham est. Dipsam in rhigustam
quorabanatis. Phenebron in spomamus
stemeprotis. Anusch initiem pu tescha
thehescranis. Ohiph plisch bolotam lu ecananis
hut thehaquoratis. Quorav scem mesciem me
cepemer pi aspitront. Ephaquad quorol ev
psivaspem vehant. Usmispeus, ocimus men
rilecit naphanis. Rutrue som bal mepres tof
iproplem est. Smin scridupeus lovorher, na
esiquad rulam itrisner. Quadisch udepli
upraplant, rac muph truvibeus baranis.
</p>
</div>
<hr>
<p id="menu1" class="menu">
<a href="#" title="Menu 1" onmouseover=
"MontrerMenu('ssmenu1');" onfocus=
"MontrerMenu('ssmenu1');">Animaux<span> :</span></a>
</p>
<ul id="ssmenu1" class="ssmenu">
<li>
<a href="#" title=
"Sous-menu 1">Girafe</a><span> ;</span>
</li>
<li>
<a href="#" title=
"Sous-menu 2">Pingouin</a><span>.</span>
</li>
</ul>
<p id="menu2" class="menu">
<a href="#" title="Menu 2" onmouseover=
"MontrerMenu('ssmenu2');" onfocus=
"MontrerMenu('ssmenu2');">Villes<span> :</span></a>
</p>
<ul id="ssmenu2" class="ssmenu">
<li>
<a href="#" title=
"Sous-menu 1">Lisbonne</a><span> ;</span>
</li>
<li>
<a href="#" title=
"Sous-menu 2">Varsovie</a><span> ;</span>
</li>
<li>
<a href="#" title=
"Sous-menu 3">Lima</a><span> ;</span>
</li>
<li>
<a href="#" title=
"Sous-menu 4">Nairobi</a><span>.</span>
</li>
</ul>
<p id="menu3" class="menu">
<a href="#" title="Menu 3" onmouseover=
"MontrerMenu('ssmenu3');" onfocus=
"MontrerMenu('ssmenu3');">Personnages<span> :</span></a>
</p>
<ul id="ssmenu3" class="ssmenu">
<li>
<a href="#" title=
"Sous-menu 1">Gandhi</a><span> ;</span>
</li>
<li>
<a href="#" title="Sous-menu 2">César</a>
<span> ;</span>
</li>
<li>
<a href="#" title="Sous-menu 3">Gengis
Khan</a><span>.</span>
</li>
</ul>
<p id="copy">
©Blablablabla
</p>
</body>
</html>
Les seuls changements sont l'ajout de l'appel du script dans le head et le mise en place des événements onload, onmouseover et onfocus. Ce dernier sert là encore à intercepter les déplacements sur un lien effectués à l'aide du clavier et non de la souris.
var blnOk=true;
function Chargement() {
if(document.body.style.backgroundColor!="") { blnOk=false; }
if(document.body.style.color!="") { blnOk=false; }
if(document.body.style.marginTop!="") { blnOk=false; }
if(document.getElementById) {
with(document.getElementById("texte").style) {
if(position!="") { blnOk=false; }
if(top!="") { blnOk=false; }
if(left!="") { blnOk=false; }
if(width!="") { blnOk=false; }
if(height!="") { blnOk=false; }
if(zIndex!="") { blnOk=false; }
if(margin!="") { blnOk=false; }
if(padding!="") { blnOk=false; }
if(visibility!="") { blnOk=false; }
}
}
else{
blnOk=false;
}
if(blnOk) {
with(document.body.style) {
backgroundColor="#333";
color="#FFF";
marginTop="5.2em";
}
with(document.getElementById("access").style) {
position="absolute";
top="1em";
left="1em";
margin="0";
}
with(document.getElementById("texte").style) {
margin="0";
padding="1em";
backgroundColor="#FFF";
color="#333";
}
for(i=1;i<=3;i++) {
with(document.getElementById("menu"+i).style) {
position="absolute";
top="3em";
left=(((i-1)*11)+1)+"em";
width="10em";
height="1.2em";
textAlign="center";
margin="0";
padding="0";
zIndex="2";
}
}
for(i=1;i<=3;i++) {
with(document.getElementById("ssmenu"+i).style) {
position="absolute";
top="4.4em";
left=(((i-1)*11)+1)+"em";
width="12em";
margin="0";
padding="0";
zIndex="3";
}
}
with(document.getElementById("copy").style) {
backgroundColor="#333";
color="#FFF";
}
CacherMenus();
}
}
function MontrerMenu(strMenu) {
if(blnOk) {
CacherMenus();
document.getElementById(strMenu).style.visibility="visible";
}
}
function CacherMenus() {
if(blnOk) {
for(i=1;i<=3;i++) {
with(document.getElementById("ssmenu"+i).style) {
visibility="hidden";
}
}
}
}
Voilà enfin la partie tant attendue. Nous avons 3 fonctions :
onload sur le body ;La première fonction met en place les éléments. On vérifie d'abord que le navigateur supporte les fonctions qui vont être utilisées. L'instruction with évite d'avoir à répéter le début des instructions. Si le navigateur passe les tests, on éloigne le texte du haut de l'écran afin de laisser la place pour le menu et de faire apparaître la couleur de fond de la page avec marginTop. Ensuite, on place la partie accessibilité et on met en forme le texte.
A ce stade, vous vous demandez peut-être pourquoi on utilise em comme unité. C'est simple : en faisant ainsi, on tient compte de la taille de la police choisie par l'internaute et notre page supportera un agrandissement harmonieux, la rendant ainsi accessible aux mal-voyants. Vous pouvez essayer de modifier la taille de votre police sur l'exemple. Elle se trouve généralement dans le menu affichage de votre navigateur.
La commande suivante mérite quelques explications. On utilise une boucle for afin de traiter les différents menus. C'est à cet endroit qu'il faudra changer le 3 suivant le nombre de menus que vous mettrez en place. Le petit calcul effectué nécessite aussi des éclaircissements. Le but est de positionner les menus tous les 11em, soit en laissant 1em entre chaque, puisqu'il en mesure 10. Le dernier 1 correspond au décalage par rapport au bord gauche. Nous procédons de la même manière pour les sous-menus. Notez au passage qu'ils mesurent 12em… de façon arbitraire.
Nous finissons en changeant les couleurs du bas de page et en cachant les sous-menus. Les deux autres fonctions vont respectivement montrer un sous-menu après avoir cacher les autres et tous les cacher.
Vous pouvez tester cette étape.
Après avoir adapté ce menu à votre cas, vous vous rendez compte que si vous ajoutez une cinquième rubrique, par exemple, la page déborde en 640 par 480. Ah, si le menu était à la verticale… Très simple : il suffit de décaler le texte vers la droite et non plus vers le haut et de repositionner les éléments. Quelques lignes à changer dans le fichier menu.js et tout votre site change d'aspect.
if(blnOk) {
with(document.body.style) {
backgroundColor="#333";
color="#FFF";
marginLeft="12.2em";
}
with(document.getElementById("access").style) {
position="absolute";
top="8em";
left="1em";
width="10em";
margin="0";
}
with(document.getElementById("texte").style) {
margin="0";
padding="1em";
backgroundColor="#FFF";
color="#333";
}
for(i=1;i<=3;i++) {
with(document.getElementById("menu"+i).style) {
position="absolute";
top=(((i-1)*2)+1)+"em";
left="1em";
width="10em";
height="1.2em";
textAlign="center";
margin="0";
padding="0";
zIndex="2";
}
}
for(i=1;i<=3;i++) {
with(document.getElementById("ssmenu"+i).style) {
position="absolute";
top=(((i-1)*2)+1)+"em";
left="11.2em";
width="12em";
margin="0";
padding="0";
zIndex="3";
}
}
with(document.getElementById("copy").style) {
backgroundColor="#333";
color="#FFF";
}
CacherMenus();
}
Vous pouvez tester cette variante.
Nous venons de poser les bases d'un menu qui marche dans pratiquement tous les cas de figure. Pour information, il a été testé sur MSIE, les navigateurs basés sur Gecko (Mozilla, Netscape, Camino), Opera, les navigateurs basés sur KHTML (Konqueror, Safari) ainsi que sur des navigateurs texte ou adaptés aux handicapés. Et ceci sur Windows, Macintosh et Linux lorsqu'ils étaient disponibles.
Nous avons vu aussi qu'il était très simple d'adapter ce menu ou de le faire évoluer. Tout ceci est dû à une forte séparation entre les différentes composantes : le contenu, son rendu et son interactivité. L'emploi d'une CSS et d'un JS externes prouve ici toute leur souplesse et leur réutilisabilité.
Voici les divers éléments de cet article :
Pour utiliser la variante, il faut soit changer l'appel du script dans le head en menu2.js, soit renommer ce fichier en menu.js.
Cet article a servi de base à de nombreux travaux dérivés. Deux d'entre eux ont particulièrement retenu mon attention et vous permettront d'aller plus loin dans la conception de menus dynamiques :
Une question, une remarque ? Écrivez à l'auteur.
Page valide XHTML 1 Strict,
CSS2 et
accessible AA.
Ce site s'affiche mieux dans un navigateur conforme aux standards,
voici pourquoi.
Site hébergé par l'APINC
et propulsé par SPIP.