Menus déroulant - vertical ou horizontal - en feuilles de style CSS fondé sur XHTML

Cette contrib vise à proposer un script de menu XHTML déroulant complètement intégré aux boucles de SPIP en utilisant un simple script JS et surtout des feuilles de styles.
Mise à jour le 24 octobre 2005 / modif champs extra / version 1.82d de SPIP.

Cette contrib a été écrite en deux temps et fournit ainsi deux méthodes pour construire un menu déroulant en XHTML-CSS. La seconde méthode est le résultat d’une recherche pour ajuster les dysfonctionnements de la première sous quelques navigateurs.

Première méthode inspirée de Alsacreations

Ce script peut sous certaines conditions remplacer le script DHTML de menus déroulant présenté dans la contrib fondée sur « coolmenu » . Son intérêt est un réglage plus simple de la feuille de style mais aussi du positionnement du menu dans le squelette, mais aussi sa propreté par l’utilisation du XHTML et des feuilles de styles. Ce menu peut bien sûr être géré comme un include.

<INCLURE (menu_css.php3)>

Il s’agit là d’une adaptation pour SPIP de certains des scripts présentés par Alsacréations dans sa présentation de l’intérêt et du bon usage des feuilles de style. On ne peut qu’inciter à faire un tour pour en savoir plus en ce domaine sur leur site très riche en exemple.
Le site d’Alsacréations : http://www.alsacreations.com/ et ses tuturiels sur le XHTML et CSS.

Je reprends donc ici des morceaux de leurs explications pour introduire cette adaptation de leur travail à SPIP.
Ce script utilise un java script simple pour la gestion de l’affichage des sous menus.

Citation :

« Un menu déroulant peut très bien se réaliser intégralement en CSS, sans utilisation de langages de scripts, alors pourquoi allons-nous utiliser javascript dans ce didactitiel ?

Il y a deux raisons à cela. La première est que la fonction première des feuilles de styles CSS est de s’occuper de la mise en page et non des aspects dynamiques de celle-ci. Ces derniers sont du domaine de Javascript (ou ECMAScript). Il s’avère que la pseudo-classe (:hover) est un peu située entre les deux : elle indique le comportement au survol mais pourrait très bien servir à des applications plus dynamiques.
La seconde raison est plus pragmatique : la pseudo-classe (:hover) qui, appliquée à bon escient, permettrait de réaliser ce genre de menus déroulants facilement et sans l’usage de javascript n’est malheureusement pas bien comprise par Internet Explorer (sur IE, cette pseudo classe n’est prise en compte que lorsqu’elle s’applique à la balise <a>).

Nous allons donc devoir utiliser une fonction javascript pour afficher / masquer nos sous-menus et nous appellerons cette fonction à l’aide des détecteurs "onmouseover" ou "onclick" selon les envies.

Nous utiliserons également les Listes de Définition (balises <dl>, <dt> et <dd>) pour structurer notre menu déroulant. La balise “dl” englobera le menu. Le “dt” sera le “titre”, c’est à dire “menu1”, “menu2”, ... et les “dd” désigneront chaque sous-menu. »

Le script Javascript va s’occuper du comportement lors du clic sur les menus parents.
Lorsque la fonction est appelée à l’aide du “onclick”, voici le déroulement : pour commencer, tous les sous-menus se ferment (display: none), puis, le sous-menu indiqué dans le “onclick” s’affiche (display: block).
Si aucun sous-menu n’est spécifié (cas du menu 1), seule la première phase a lieu : tous les sous-menus affichés se ferment.

Comme vous le remarquez dans le code Javascript ci-dessous, le script appelle la fonction “montre()” au chargement de la page. Cet appel (“montre” vide) a pour effet de cacher tous les sous-menus dès le chargement du document.

Il aurait été plus simple de masquer ces sous-menus en définissant simplement leur CSS à “display:none” (c’était d’ailleurs le cas dans la première version du tutoriel), alors pourquoi avoir préféré utiliser un appel javascript pour obtenir le même effet ?

L’intérêt est une question d’Accessibilité, ou plutôt d’interopérabilité : il existe une part non négligeable d’internautes pour qui Javascript est désactivé.
Pour ces utilisateurs, le menu doit rester utillisable, ce qui n’aurait pas été le cas si les sous-menus avaient été cachés par CSS, car ils le resteraient.
Dans notre cas, les menus sont effacés au chargement, mais uniquement si javascript est actif. Dans les autres cas, le menu reste navigable même si aucun comportement au survol ne sera déclenché.

Code Javascript (à placer dans les balises HEAD) :

<script type="text/javascript">
<!--
window.onload=montre;
function montre(id) {
var d = document.getElementById(id);
	for (var i = 1; i<=10; i++) {
		if (document.getElementById('smenu'+i)) {document.getElementById('smenu'+i).style.display='none';}
	}
if (d) {d.style.display='block';}
}
//-->
</script>

Fin de citation

1ère note d’adaptation SPIP

A partir de là nous entrons dans les subtilités (et limites actuelles - on peut peut-être aller plus loin , mais pour le moment j’en suis resté à une adaptation simple a minima...) de l’application de ce JS à SPIP.
Il faut noter tout de suite que la gestion de l’affichage des sous menus passe par l’incrémentation d’une expression qui est « smenu » (smenu1, smenu2...smenu[i]...smenu10). Notons au passage que le script donné ici ne peut gérer que 10 item de menus. Pour augmenter il faudrait modifier la valeur maximum de i.
Ce point est important car il faudra par convention utiliser le champ de description des rubriques de premier niveau du menu pour inscrire cette valeur de « smenu ». (en y mettant « smenu1 » pour l’item 1 du menu, « smenu2 » pour l’item 2 du menu etc..jusqu’à 10 maximum).

Remarque :
Ceci a pour effet bien sûr de geler l’utilisation du champ descriptif de la rubrique...Mais ceci pourrait être contourné par l’utilisation du champ « texte explicatif », voire mieux par la création d’un « champ extra » (cf contribution sur Champs Extras)

Conseil (et contrainte ?) :
Ce script est plus particulièrement adapté et facile à mettre en œuvre au moment de la conception/création d’un site. Il est conseillé de créer ainsi en série à la racine du site 10 rubriques qui serviront de conteneur aux sous-rubriques (sous-menus) dans l’arborescence des contenus. Ceci dit peut importe le numéro d’ « id » des rubriques parentes SPIP qui constituent le menu. Le point important est l’incrémentation de 1 à 10 de « smenu » dans le champ descriptif de la rubrique.

La feuille de style CSS du menu déroulant horizontal :

<style type="text/css" media="screen">
<!-- 
body {
margin: 0;
padding: 0;
background: white;
font: 80% verdana, arial, sans-serif;
}
dl, dt, dd, ul, li {
margin: 0;
padding: 0;
list-style-type: none;
}
#menu {
position: absolute; /* placement du menu, à modifier selon vos besoins */
top: 0;
left: 0;
z-index:100;
width: 100%; /* correction pour Opera */
}
#menu dl {
float: left;
width: 12em;
}
#menu dt {
cursor: pointer;
text-align: center;
font-weight: bold;
background: #ccc;
border: 1px solid gray;
margin: 1px;
}
#menu dd {
display: none;
border: 1px solid gray;
}
#menu li {
text-align: center;
background: #fff;
}
#menu li a, #menu dt a {
color: #000;
text-decoration: none;
display: block;
height: 100%;
border: 0 none;
}
#menu li a:hover, #menu li a:focus, #menu dt a:hover, #menu dt a:focus {
background: #eee;
}
#site {
position: absolute;
z-index: 1;
top : 70px;
left : 10px;
color: #000;
background-color: #ddd;
padding: 5px;
border: 1px solid gray; 
}
-->
</style>

Remarque elle peut être introduite directement dans le

, mais il est mieux de faire une feuille de style séparée (dans le zip je l’ai appelée de manière tout à fait original « menu.css » et d’y faire appel par :

<head> 
<style type="text/css">
<!--
@import url(menu.css);
//-->
</style>
</head>

Bien sûr c’est au niveau de la feuille de style que vous allez régler l’apparence de votre menu déroulant (couleurs, bordures, taille, espacements...) A vous de jouer pour ajuster à votre charte graphique.

Et maintenant le code XHTML d’affichage :

<div id="menu">
<dl>
<dt onmouseover="javascript:montre();">
<a href="sommaire.php3"  title="Retour à l'accueil">Accueil</a></dt>
</dl>
<BOUCLE_menu(RUBRIQUES) {racine} {par titre}>	
<dl>					
<dt onmouseover="javascript:montre('#DESCRIPTIF');">#TITRE</dt>
<dd id="#DESCRIPTIF">
<ul>				
<BOUCLE_sous_menu(RUBRIQUES) {id_parent} {par titre}>
<li><a href="#URL_RUBRIQUE">#TITRE</a></li>
</BOUCLE_sous_menu>					
</ul>		
</dd>
</dl>
</BOUCLE_menu>		
</div>

Ceci fait apparaître un menu déroulant à 2 niveaux (menu et sous menus de rubriques).
Rien de compliqué donc : 2 boucles imbriquées une sur la racine dans l’exemple pris et l’autre sur les rubriques filles (ayant le même parent).
Le lien avec le JS de gestion est fait par la balise #DESCRIPTIF des rubriques menus de la racine (mais cela pourrait être #TEXTE pour le texte explicatif ou #CHAMP_EXTRA...). Il faut donc remplir et nommer avec soin ce champ avec les « smenu[i] »

Dans cet exemple les sous menus ne disparaissent que lorsqu’on change d’item de menu. Mais d’autres comportements sont possibles.
Le code en grisé peut être éliminé il sert ici à afficher une première boite du menu pour la gestion du retour à la page d’accueil (sommaire.php3).
Si vous ne voulez par faire apparaître l’une des rubriques du menu, vous pouvez toujours la supprimer par l’instruction id_rubrique !=XX dans

<BOUCLE_sous_menu(RUBRIQUES) {id_parent} {par titre} {id_rubrique !=XX} >

Maintenant des pistes pour des variantes

Pour un menu déroulant vertical :

<style type="text/css" media="screen">
<!-- 
body {
margin: 0;
padding: 0;
background: white;
font: 80% verdana, arial, sans-serif;
}
dl, dt, dd, ul, li {
margin: 0;
padding: 0;
list-style-type: none;
}
#menu {
position: absolute; /* placement du menu, à modifier selon vos besoins */
top: 0;
left: 0;
}
#menu {
width: 15em;
}
#menu dt {
cursor: pointer;
margin: 2px 0;;
height: 20px;
line-height: 20px;
text-align: center;
font-weight: bold;
border: 1px solid gray;
background: #ccc;
}
#menu dd {
border: 1px solid gray;
}
#menu li {
text-align: center;
background: #fff;
}
#menu li a, #menu dt a {
color: #000;
text-decoration: none;
display: block;
border: 0 none;
height: 100%;
}
#menu li a:hover, #menu dt a:hover {
background: #eee;
}
-->
</style>

Notre menu déroulant vertical est fonctionnel !

Variante : les sous-menus disparaissent

La version proposée ci-dessus laisse apparaître les sous-menus même lorsqu’ils ne sont plus survolés.
Si vous préférez qu’ils se masquent lorsque la souris les quitte, il suffit d’ajouter le comportement onmouseout= “javascript:montre();” sur les sous-menus (dd) comme le montre le code suivant :

<div id="menu">
<BOUCLE_menu(RUBRIQUES) {racine} {par titre}>	
<dl>					
<dt onmouseover="javascript:montre('#DESCRIPTIF');">#TITRE</dt>
<dd id="#DESCRIPTIF" onmouseover="javascript:montre('#DESCRIPTIF');" onmouseout="javascript:montre('');">
<ul>				
<BOUCLE_sous_menu(RUBRIQUES) {id_parent} {par titre}>
<li><a href="#URL_RUBRIQUE">#TITRE</a></li>
</BOUCLE_sous_menu>					
</ul>		
</dd>
</dl>
</BOUCLE_menu>			
</div>

Bien sûr il y a sans doute encore du travail pour améliorer cette adaptation.
On peut imaginer de faire apparaître un troisième niveau dans un menu horizontal en le gérant en affichage horizontal comme dans le menu DHTML.

Fichiers fournis dans le zip pour cette première méthode.

-  menu_css.php3
-  menu_css.html contenant le java script d’affichage des sous menus
-  menu.css (la feuille de style - ici menu horizontal)

« Une deuxième méthode » qui gère mieux les différents navigateurs et respectant les normes d’accessibilité inspirée de OpenWeb. »

Voici une autre méthode totalement appuyée sur le tutoriel rédigé par Fabrice Bonny dans OpenWeb pour réaliser un menu dynamique ouvert et accessible à partir de feuilles de style et de XHTML.

Pour la totalité des explications il est conseillé de lire ce tutoriel de Fabrice Bonny sur http://openweb.eu.org/articles/menu_universel/

Le principe est identique à celui expliqué dans la première partie de ma contrib. Il s’agit d’associer des styles à chacune des rubriques et sous-rubriques composant le menu déroulant.

Pour commencer voici le code HTML de génération du menu qui fait référence à une feuille de style externe (menuuniversel.css) et au javascript de gestion des feuilles de style.
Ce script ne peut donc fonctionner que sur un navigateur sur lequel le javascript n’a pas été désactivé.
En revanche il fournit un meilleur contrôle de l’affichage des feuilles de style selon les différents navigateurs.
Pour information, il a été testé par Fabrice Bonny 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..

Exemple de travail de ce menu pour le site infogm.org

Voici le code pour l’affichage de l’ensemble du menu des rubriques de premier niveau + les sous-rubriques de ces rubriques. ( syntaxe d’affichages des champs extra pour la V1.82d de SPIP )

<html>
<head>
<title>Menu dynamique - Etape 3</title>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
    <link rel="stylesheet" type="text/css" href="menuuniversel.css" title="défaut">
    <script type="text/javascript" src="menu.js"></script>

</head>

<body lang="fr" onload="Chargement();">
   
<p id="access" onmouseover="CacherMenus();">
    
</p>

<div id="texte" onmouseover="CacherMenus();">
 
</div>
    
<hr>

<BOUCLE_menu(RUBRIQUES){racine}{par titre}{id_rubrique}>
<p id="[(#EXTRA|extra{menu})]" class="menu">
<a href="#URL_RUBRIQUE" title="[(#TITRE|supprimer_numero)]"
onmouseover="MontrerMenu('[(#EXTRA|extra{ssmenu})]');" 
onfocus="MontrerMenu('[(#EXTRA|extra{ssmenu})]');"> 
[(#TITRE|supprimer_numero)] </a><span>&nbsp;;</span>
     
    </p>
<ol id="[(#EXTRA|extra{ssmenu})]" class="ssmenu">		
<BOUCLE_sous_menu(RUBRIQUES) {id_parent} {par titre} {inverse} {0,10}>
<li><a href="#URL_RUBRIQUE" title="[(#TITRE|supprimer_numero)]">
[(#TITRE|supprimer_numero)]</a><span>&nbsp;;</span>
      </li>
</BOUCLE_sous_menu>					
</ol>		
</BOUCLE_menu>		

</body>
</html>

Commentaires

Pour intégrer les « mots-clefs » qui activent la gestion des feuilles de style via le JS (Cf plus bas), j’ai été conduit ici à introduire deux champs extras au niveau des rubriques :
-  un champ extra nommé « menu » pour la gestion du 1er niveau du menu déroulant : il faut alors y incrémenter dans les rubriques que l’on voudra incorporer dans le menu déroulant les « variables » suivantes : « menu1 » , « menu2 »... « menuX » pour X rubriques de premier niveau. Le numéro incrémenté défini alors l’ordre de rangement (dans l’exemple donné horizontal) des rubriques de premier niveau.
-  un champ extra nommé « ssmenu » pour la gestion des sous-menus (niveau 2) : il faut alors y incrémenter dans les rubriques du premier niveau que l’on voudra incorporer dans le menu déroulant les « variables » suivantes : «ss menu1 » , «ssmenu2 »... « ssmenuX » .

Pour activer les champs extras voir la contrib Les champs extra .
L’archive fournie contient dans le répertoire “ecrire” un fichier mes_options.txt qui contient le code pour la génération des champs extras “menu” et “ssmenu”. Si vous n’avez pas de fichier mes_options vous pouvez renommer ce fichier en mes_options.php3, sinon recopier le code fourni (syntaxe adaptée à la version 1.82d de SPIP) dans votre fichier mes_options.php3.

À noter au passage la balise « title » du lien est renseignée aussi avec le titre de la rubrique ciblée (norme d’accessibilité).

On trouve dans le code l’appel du script dans le head et la mise en place des événements onload, onmouseover et onfocus. Ce dernier sert à intercepter les déplacements sur un lien effectués à l’aide du clavier et non de la souris.

La feuille de style

C’est à partir de cette feuille de style que vous pouvez habiller ce menu dynamique à votre charte de style.
A vous de jouer.

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;
}

Le code JavaScript

A prendre tel quel mais en ajustant précisément la valeur de la variable i maximale au nombre exact que vous avez d’entrées de menus (5 dans l’exemple que je donne). A changer dans :

- for(i=1;i<={{5}};i++) {
      with(document.getElementById("menu"+i).style)
- for(i=1;i<={{5}};i++) {
      with(document.getElementById("ssmenu"+i).style) {
- function CacherMenus()

C’est aussi dans ce js que vous allez régler le positionnement absolu, la dimension et l’écartement des boites d’affichage des menus et sous menus.

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<=5;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<=5;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<=5;i++) {
      with(document.getElementById("ssmenu"+i).style) {
        visibility="hidden";
      }
    }
  }
}

Explications

Citation de Fabrice Bonny :
Nous avons 3 fonctions :
-  Chargement qui est appelée au chargement de la page grâce au onload sur le body ;
-  MontrerMenu qui affiche le menu dont le nom lui est passé en argument ;
-  CacherMenus qui cache les menus.

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. »

Variante :

Après avoir adapter 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();
  }

updated on 7 December 2006

Discussion

17 discussions

  • Bonjour,
    Découvrant par hasard cette excellente contribution et ayant moi aussi utilisé et tuner pour spip le code d’alsacréation, je me permet d’ ajouter ma modeste contribution qui automatise le compteur de la boucle du code javascript; en effet il faut tout simplement utiliser les balises #TOTAL_BOUCLE, #COMPTEUR_BOUCLE des dernières versions de Spip .

    C’est assez lourd à mettre en place car il faut aussi déclarer des variables avec les balises #SET/#GET, mais le résultat nous fait éviter l’incrustation de code php.
    l’idée est la suivante : récupérer le nombre totale de la boucle (soit le total des rubriques à afficher) en utilisant #TOTAL_BOUCLEd’une part et se servir du compteur d’incrémentation de la boucle pour créer les noms des “id” (dtxx ou menuxy ou sousmenuyz) avec #COMPTEUR_BOUCLE d'autre part
    Ces compteurs sont à rajouter en argument aux fonctions javascript d’affichage.

    Voici un exemple complet de 2 niveaux de déroulement (je ne met pas le style css car il ne diffère en rien du source cité):
    javascript :
    _

    window.onload=afficheMenu;
    window.onload=afficheSousMenu;
    
    function afficheMenu(id,id2,total) {
       var d = document.getElementById(id);
       var dt = document.getElementById(id2);
       for (var i = 1; i<=total; i++) {
           if (document.getElementById('smenu'+i)) {
              document.getElementById('smenu'+i).style.display='none';
             
            }
       }
       if (d) {
              d.style.display='block';
       }
    }
    
    function afficheSousMenu(id,id2,soustotal) {
       var d = document.getElementById(id);
       for (var i = 1; i<=soustotal; i++) {
        if (document.getElementById('smenu'+id2+i)) {
            document.getElementById('smenu'+id2+i).style.display='none';
        
        }
       }
       if (d) {
        d.style.display='block';
        
    }
    }

    _ squelette :

    <BOUCLE_menu(RUBRIQUES) {id_parent} {lang} {par titre}>
    [(#REM on recupere le nombre total de rubrique de tete ainsi que l'incrementation de la boucle principale "_menu"
    ]
    [(#SET{total_menu,#TOTAL_BOUCLE})]
    [(#SET{cpt_menu,#COMPTEUR_BOUCLE})]
    <dl>
    <dt id="[dt(#COMPTEUR_BOUCLE)]" onmouseover="javascript:afficheMenu('[smenu(#COMPTEUR_BOUCLE)]','[dt(#COMPTEUR_BOUCLE)]','[(#TOTAL_BOUCLE)]');" onmouseout="javascript:afficheMenu();" >
    <a href="#URL_RUBRIQUE" border="0">[(#TITRE|supprimer_numero|coupeTitre{20})]</a></dt>
    <B_sous_menu>
    <dd id="[smenu(#GET{cpt_menu})]" onmouseover="javascript:afficheMenu('[smenu(#GET{cpt_menu})]','[dt(#COMPTEUR_BOUCLE)]','[(#GET{total_menu})]')" onmouseout="javascript:afficheMenu();">
    <ul>
            
                    
    <BOUCLE_sous_menu(RUBRIQUES) {id_parent} {par titre}>
    [(#SET{total_sous_menu,#TOTAL_BOUCLE})]
    [(#SET{cpt_sous_menu,#COMPTEUR_BOUCLE})]
    
    <li onmouseover="javascript:afficheSousMenu('[smenu[(#GET{cpt_menu})](#GET{cpt_sous_menu})]','[(#GET{cpt_menu})]','[(#GET{total_sous_menu})]');" onmouseout="javascript:afficheSousMenu('','[(#GET{cpt_menu})]','[(#GET{total_sous_menu})]');">
    
    <a href="#URL_RUBRIQUE">[(#TITRE|supprimer_numero)]</a>
    
    <B_soussous_menu>
    [(#SET{total_soussous_menu,#TOTAL_BOUCLE})]
    
    
    <ol id="[smenu[(#GET{cpt_menu})](#GET{cpt_sous_menu})]" onmouseover="javascript:afficheSousMenu('[smenu[(#GET{cpt_menu})](#GET{cpt_sous_menu})]','[(#GET{cpt_menu})]','[(#GET{total_soussous_menu})]');"
     onmouseout="javascript:afficheSousMenu('','[(#GET{cpt_menu})]','[(#GET{total_soussous_menu})]');">
    
    
    
    <BOUCLE_soussous_menu(RUBRIQUES) {id_parent} {par titre}>
                <li><a href="#URL_RUBRIQUE">[(#TITRE|supprimer_numero|coupeTitre{20})]</a></li>
    </BOUCLE_soussous_menu>
    </ol>
    </B_soussous_menu>
    [(#REM) -mEGa FIN 2eme deroulant]
    
    </li>
    </BOUCLE_sous_menu>                                        
    </ul>
                    
    </dd></B_sous_menu><//B_sous_menu>
    </dl>
    
    </BOUCLE_menu> 

    Spipement vôtre ;-)

    Reply to this message

  • Bonjour à tous,

    J’ai pris exactement le menu deroulant horizontal mais rie ne ce se déroule regarder sur mon site http://www.rezolinux.com

    Qui peux m’aider merci

    Reply to this message

  • 2

    Hello,
    Moi aussi dévoreur des bons conseils d’alsacrations, j’en ai appliqué un très facilement à Spip (horizontal se déroulant verticalement).

    Voici son application: http://www.observatoirecitoyen.be/

    Il y reste cependant un petit bug, que non codeur, je n’arrive pas du tout à comprendre. Si l’auteur de l’article ou d’autres experts ont la possibilité d’un jeter un oeil, il serait temps que j’arrive à shooter ce petit bug d’affichage. Merci!

    L

    • Salut,

      j’avais le même problème que toi, c’est à dire que, quand on a plusieurs sous-rubriques dans une rubrique, le menu se ferme dès qu’on veut passer à la ligne suivante, comme s’il n’existait qu’une seule ligne.

      J’ai résolu ce problème en observant ce que Bienf (ci-dessus) a fait sur son site : il a mis en commentaire (donc annulé) une partie du code.

      <dd id="#DESCRIPTIF"> <!-- onmouseover="javascript:montre('#DESCRIPTIF');" onmouseout="javascript:montre('');" -->

      Voilà, j’espère que ce sera utile à d’autres !

    • Merci beaucoup :)

    Reply to this message

  • 2

    Bonjour,
    ca y est j’ai presque terminé mon menu,
    mais les fenetres ouvertes ne se ferment pas . Comment faire ?

    J’ai vu qu’il fallait faire : onmouseout= "javascript :montre()
    Mais ca ne marche pas ...

    comme le montre cet extrait du forum :

    "La version proposée ci-dessus laisse apparaître les sous-menus même lorsqu’ils ne sont plus survolés. Si vous préférez qu’ils se masquent lorsque la souris les quitte, il suffit d’ajouter le comportement onmouseout= “javascript :montre() ;” sur les sous-menus (dd) comme le montre le code suivant :

    • Bonjour,

      J’ai le même problème, as-tu trouvé une solution au fait que les sous menus restent affichés ???
      Grand merci pour cette contribution et vos réponses

    • salut,

      j’ai exactement le meme probleme avec montre(’’).

      quelqu’un a trouvé une astuce?!?

      merci

    Reply to this message

  • Si sa interesse quelqu’un j’ai modifié la boucle pour affiché directement le titre des articles quand il n’y a pas de sous-rubrique, si il y a des sous-rubriques leur titre s’affiche dans le menu déroulant.

    <div id='nav-container'>
    
    <B_rubriques>
    <div id="nav">
            <ul>
            <BOUCLE_rubriques(RUBRIQUES) {racine} {par num titre, titre}>
                    <BOUCLE_articles(ARTICLES){id_rubrique}{par titre}>
                    <li>
                            <a href="#URL_ARTICLE">[(#TITRE|supprimer_numero|couper{80})]</a>
                    </BOUCLE_articles>
            [(#REM) Si aucun article, affiche un plan de la rubrique ]
                            <B_sous_rubriques>
                            <ul>
                                    <BOUCLE_sous_rubriques(RUBRIQUES) {id_parent} {par num titre, titre}>
                                            <li>
                                            <h6><a href="#URL_RUBRIQUE" <BOUCLE_test_sousrub(RUBRIQUES){id_parent}{0,1}>class='daddy'</BOUCLE_test_sousrub>>[(#TITRE|supprimer_numero|couper{80})]</a><BOUCLE_re(BOUCLE_sous_rubriques)></BOUCLE_re>        </li></h6>
                                    </BOUCLE_sous_rubriques>
                            </ul>
                            </B_sous_rubriques>
    
                    </li>
            </BOUCLE_rubriques>
    
            </ul>
    </div>
    </B_rubriques>
    </div>

    Reply to this message

  • Bonjour tous le monde!

    Je suis débutant sous SPIP et j’ai un petit problème! Je suis sous SPIP 1.9.1

    J’utilise un menu semblable mais avec la fonction “onclick”, le javascript utiliser est

    <script type="text/javascript">
    <!--
    window.onload=montre;
    function montre(id) {
    var d = document.getElementById(id);
            for (var i = 1; i<=10; i++) {
                    if (document.getElementById('smenu'+i)) {document.getElementById('smenu'+i).style.display='none';}
            }
    if (d) {d.style.display='block';}
    }
    //-->
    </script>

    Mon code HTML est celui-ci :

    <!-- DEBUT MENU GAUCHE -->
    <div id="menugauche">
    
    <dl id="menu">
    <BOUCLE_rub(RUBRIQUES){racine}{tout}{par num titre}>                        
            <dt onclick="javascript:montre('');"><a href="#URL_RUBRIQUE" title="[(#TITRE|supprimer_numero)]">[(#TITRE|supprimer_numero)]</a></dt>
                    <dd id="">
                    <B_srub>
                            <ul>
                                    <BOUCLE_srub(RUBRIQUES){id_parent}>
                                            <li><a href="#URL_RUBRIQUE" title="[(#TITRE|supprimer_numero)]">[(#TITRE|supprimer_numero)]</a></li>
                                    </BOUCLE_srub>
                            </ul>
                    </dd>        
                    </B_srub>
    </BOUCLE_rub>
    </dl>
    
    </div>
    <!-- FIN MENU GAUCHE -->

    Mon menu est en verticale, et mon problème est le suivant :

    Il n’affiche que mes sous-rubriques de ma 1ère rubrique ! Au clique des rubriques suivante il ne rabaisse pas la 1ère rubrique et n’affiche pas les sous rubrique de la rubrique cliquée ! ( Ouf je m’excuse d’avance pour cette phrase un peu mal tournée ! )

    Si quelqu’un à une astuce pour palier à ce problème je suis preneur !!

    Merci d’avance !

    Reply to this message

  • 1

    Bonjour à tous !

    J’ai la dernière version de SPIP qui tourne, a base d’un squelette EPONA.
    Je modifie ce squelette et je voulais surtout obtenir un menu horizontal (pas besoin qu’il soit deroulant)
    j’essaye depuis quelques heures de faire tourner ce script Alsacréations et je n’arrive qu’à obtenir un menu horizontal, avec trois boutons (Accueil, et les deux rubriques à la racine du site). Le lien vers l’acceuil rend effectif ce bouton, mais pour les deux suivants, rien...

    J’ai intégré le CSS dans habillage .css, et dans sommaire.html, j’ai enlevé l’ancien code pour mettre un vers le inc_menu que j’ai changé avec le code fourni.

    Où est l’erreur ?
    merci de votre aide, il n’y a plus que cela qui me bloque vraiment, le reste n’étant que de la biduouille simple de css...

    merci d’avance de votre aide

    • j’ai écris trop vite, il faut lire :
      “J’ai intégré le CSS dans habillage .css, et dans sommaire.html, j’ai enlevé l’ancien code pour mettre un INCLUDE vers le inc_menu (...”

    Reply to this message

  • 5

    Bonjour,

    Je réalise un site sous Spip.
    j’ai des problèmes avec les sous menus alors qu’avec la version html cela fonctionne correctement.

    Mes sous menus poussent tous les blocs du dessous malgré des positions différentes dans les z-index du CSS.

    http://www.bibliotheques93.fr/article.php3?id_article=3 par exemple

    Que dois-je faire ?

    Ce menu fonctionne très bien avec le html http://www.bibliotheques93.fr/index07.htm

    merci.

    Bienf

    • Je corrige, si vous allez sur http://www.bibliotheques93.fr/index07.htm les menus fonctionnent mais si vous choisissez un article dans le menu horizontal, le décalage vers le bas s’observe en pointant sur ce menu .

      je ne sais à quoi c’est dû.

      Bienf

    • Ton contenu qui s’affiche juste en dessous, ne serait-il pas placé en float ou relative ?

    • Le #menu dl est en float, mais je n’ai pas ce pb sur netscape, donc il faut pê trouver du javascript qui corrige le problème sur ie.

      je vais voir la contrib sur alsacreations et celle d’infogm

      Bienf

    • ...pardon j’ai mal lu, j’ai lu menu au lieu de “contenu du dessous”.

      Le contenu du dessous :

      #page
      {
      	background: #ffe382;
      	text-align: left;
      	/*margin: 0;*/
      	padding: 0 5 0 0px;
      	
      	width: 950px;
      	z-index: 1;
      	/*position: absolute;*/
      	
      }

      Le menu de gauche est en float :

      #barre_laterale
      {
      	float: left;
      	left: 10px;
      	margin: 16px 10px 20px 0;
      	border: 2px solid #64643c;
      	top:200px;
      	padding: 0px 10px 10px 0;
      	color: #64643c;
      	background: #fffde9;
      	width: 157px;
      	z-index:35;
      }
    • Pour que cela fonctionne sous ie, il fallait en plus une position absolute aux sous menus #menu dd

      Bienf

    Reply to this message

  • bonjour !
    J’ai créé un menu déroulant à partir de ce code seulement je rencontre un problème de mise en page. Lorsque le sous-menu se déroule, il décale les rubriques. Vous pouvez visionner à l’adresse que je joind.
    Si quelqu’un a une idée d’où ça pourrait venir, merci de son aide !
    didi

    PS : je tiens à préciser que le site devant s’ajuster à la résolution qu’aura l’utilisateur, le menu ne peut être entièrement en absolut...

    Reply to this message

  • 1

    Je débute sur SPIP et j’essaie de faire mon premier squelette.
    Où dois-je insérer ces fichiers pour pouvoir utiliser le menu.
    -  menu_css.php3
    -  menu_css.html
    -  menu.css
    Merci pour votre aide.

    • bonjour,
      j’utilise spip et je viens de telecharger le menu deroulant menu css open web
      mais j’arrive pas à l’integrer dans le squelette que j’utilise.

      Si vous avez une solution merci de m’aider.

    Reply to this message

Comment on this article

Who are you?
  • [Log in]

To show your avatar with your message, register it first on gravatar.com (free et painless) and don’t forget to indicate your Email addresse here.

Enter your comment here

This form accepts SPIP shortcuts {{bold}} {italic} -*list [text->url] <quote> <code> and HTML code <q> <del> <ins>. To create paragraphs, just leave empty lines.

Add a document

Follow the comments: RSS 2.0 | Atom