28111 sujets

CSS et mise en forme, CSS3

Avec ces histoires de menus, je suis en train de devenir chèvre.

J'essaie depuis près d'une semaine de "fignoler" un menu vertical (qui fonctionnera avec SPIP) utilisant CSS/JS pour fonctionner. Après avoir rencontré plusieurs problèmes de compatibilité entre IE et Firefox -- et les avoir résolus petit à petit --, je suis confronté cette fois-ci à une difficulté apparaissant dans les deux navigateurs : le sous-menu est recouvert par les menus inférieurs. Voici ce que cela donne :
http://ipr.univ-paris1.fr/spip/recouvrement_menu.png

Le code CSS est celui-ci :
/* Style du menu */

	.menu {
		border:1px solid gray;
		display:block;
		float:left;
		padding:10px 5px 10px 5px;
		width:160px;
		}

	.menu FORM {
		background-color: #f2f2f2;
		border: 1px solid #909090;
		color: #505030;
		display:block;
		font-family: Verdana;
		font-weight: normal;
		margin-top:5px;
		width:160px;
		}

	ul#menu li ul {
		display:none;
		}

	ul#menu li:hover>ul {
		display:block;
		}

	ul#menu {
		font-family:Verdana;
		height:133px;
		list-style:none;
		margin:0px;
		margin-bottom:3px;
		padding:0px;
		width:148px;
		_width:150px;
		}

	ul#menu ul {
	border:1px solid black;
	border-bottom:0px;
	left:120px;
	list-style:none;	
	position:absolute;
	margin:0px;
	padding:0px;
	top:-1px;
	width:148px;
	_width:150px;
	}

	ul#menu ul li{
	margin-bottom:0px;
	border-top:0px;
	border-left:0px;
	border-right:0px;
	}
	
	ul#menu li
	{
	background:#C4C4C4;
	border:1px solid black;
	margin-bottom:3px;
	position:relative;
	}

	ul#menu a {
	color:#000000;
	display:block;
	font-style:normal;	
	text-decoration:none
	}

	ul#menu a:hover{
	background:#000000;
	color:#FFFFFF;
	font-style:normal;
	}


L'animation se fait via un JS (pour IE) ou via un hover>UL pour un autre navigateur.

Si vous connaissez une solution à ce problème, votre avis m'intéresse... au plus haut point.

GS.
Modifié le 06 Dec 2004 - 08:08
le z-index n'est pas interprété par msie, l'odre des balises dans le code prime. Il faudra trouver autre chose.
J'ai déjà essayé de régler le problème avec le "z-index." Mais cela ne semble pas fonctionner (ni sous IE, ni sous Firefox).

D'autres idées ?

...
Administrateur
brice a écrit :
le z-index n'est pas interprété par msie, l'odre des balises dans le code prime. Il faudra trouver autre chose.

Non non, l'ordre imposé par z-index prime sur l'ordre dans le code (c'est justement l'utilité) : sur IE comme sur les autres.
Je ne connais pas de bug IE à ce sujet.

Par contre, il faut bien comprendre que le z-index ne peut s'appliquer que sur des éléments frères : s'il y'a imbrications des éléments (parenté), cela change tout.

http://www.aidejavascript.com/article93.html
Aidejavascript a écrit :
Ordre de superposition

Les éléments en positionnement absolu peuvent se superposer à des éléments non positionnés ou à d'autres éléments en positionnement absolu. Trois facteurs interviennent dans l'ordre d'empilement : le contexte de superposition, la propriété z-index et l'ordre d'apparition dans le source.

Chaque élément en positionnement absolu appartient à un contexte de superposition. Le contexte de superposition initial est créé par la fenêtre du navigateur. Chaque élément dans le même contexte de superposition définit son ordre de superposition grâce à la propriété z-index. Deux éléments du même contexte de superposition, ayant le même z-index, seront départagés par leur ordre d'apparition dans le source.

Un conteneur définit un contexte de superposition pour ses descendants. L'ordre de superposition parmi ces descendants est défini par leur z-index et éventuellement par leur ordre d'apparition dans le source.

Dans l'exemple ci-dessous, tous les éléments sont positionnés de façon absolue. L'élément A1 est contenu dans l'élément A, mais B est indépendant. A1 se superpose à A, puisque son z-index est supérieur. Mais B se superpose à A1, parce que son contexte de superposition est supérieur à celui de A (et de ses descendants).


Dans le cas de gsaunier, les sous-menus sont enfants des blocs menus donc même avec un très gros z-index, ils s'afficheront quand-même en dessous de ces blocs.
Administrateur
gsaunier a écrit :
Si je te comprends bien, il n'y aurait pas de solution...
GS.

Il y'a très certainement une (ou plusieurs) solution(s), mais dans tous les cas, cela aurait de grosses implications sur la structure de ton menu.

Je ne connais pas le squelette de ton menu déroulant (il n'est pas parmi ceux d'Alsa), par contre je peux supposer que :
1- tes balises de menu ("l'institut", "les centres", etc.) sont positionnées en absolu
2- tes balises de sous-menu ("CHNA", etc.) sont aussi positionnées en absolu.

Si c'est le cas et que ta structure est de ce genre :

<menu1> (position absolute + z-index 1)
   <sous-menu> (position absolute + z-index 100000)
</menu1>
<menu2> (position absolute + z-index 2)
</menu2>


Dans ce cas, même avec un z-index de 100000, le <sous-menu> s'affichera sous les deux <menu> car il est enfant (il ne se trouve pas à la même hauteur dans la hierarchie)

L'une des solutions est... que les <menu> ne soient pas positionnés en absolu. Dans ce cas, les <sous-menu> positionnés s'afficheraient automatiquement au-dessus, mais cela posera d'autres problèmes.
Hello,

C'est bizarre, j'avais essayé ta CSS avec un menu HTML rapide pour essayer de trouver d'autres solutions, mais j'était également arrivé à la conclusion que seuls les z-index pouvaient fonctionner vu que tu as compliqué le problème en faisant un recouvrement des sous-menu sur les menus...Et ce fut le cas, du moins sous FireFox Smiley biggrin . Vu la réponse de Raphaël, du coup je me demande si je ne me suis pas mis dans un cas un peu idéal Smiley rolleyes . Peux-tu donner ton code HTML/JS s'il te plait histoire que je comprenne ?
Ok. À la demande générale, tout le code.

1- HTML

Le code HTML est généré par SPIP. modele3.php3 appelle un squellette qui contient un INCLURE du menu. Voici le code de cet INCLURE de menu.

<div class="menu">
<ul id="menu">
<BOUCLE_menu_rubrique(RUBRIQUES){meme_parent}{par num titre}>

	<li><a href="[(#URL_RUBRIQUE)]">[(#TITRE|supprimer_numero)]</a>
		<ul>
		<BOUCLE_menu_ssrubrique(RUBRIQUES){id_parent}>				
			<li><a href="[(#URL_RUBRIQUE)]">[(#TITRE|supprimer_numero)]</a></li>
		</BOUCLE_menu_ssrubrique>
		</ul>
	</li>
	</BOUCLE_menu_rubrique>
</ul>
<form action="recherche.php3" method="get">
	<input type="text" name="recherche" size="15" maxlength="50">
	<input type="submit" value="ok">
</form>
</div>


Le code JS (avec quelques commentaires) :
function setHover()
{
	LI = document.getElementById('menu').getElementsByTagName('li'); /* Récupère et inscrit dans le tableau LI les éléments li du document contenu dans le style "menu" */
	nLI = LI.length; /* Compte le nombre de lignes du tableau LI */
	for(i=0; i < nLI; i++) /* Exécute une boucle sur chaque élément du tableau */
	{
		LI[i].onmouseover = function() /* Si l'un des éléments du LI est survolé, lance la fonction hover sur cet élement */
		{
			hover(this);
		}
		LI[i].onmouseout = function() /* Si l'un des éléments du LI n'est pas survolé, lance la fonction hover sur cet élement */
		{
			hover(this);
		}
	}
}

function hover(obj_jojo)
{
	if(document.all) /* Vérifie que le navigateur est IE ou Opera. Si ce n'est pas le cas, le script n'est pas exécuté */
	{
		UL = obj_jojo.getElementsByTagName('ul'); /* Crée un tableau contenant l'ensemble des éléments UL de l'élément survolé dans la fonction setHover */
		if(UL.length > 0) /* Vérifie que le tableau n'est pas vide, c'est à dire qu'il y a bien des tag UL dans cet élément */ 
		{
			sousMenu = UL[0].style; /* Récupère le style de la première balise UL de l'élément survolé dans la fonction setHover  */
			if(sousMenu.display == 'none' || sousMenu.display == '') 
			{
				sousMenu.display = 'block'; /* Si la propriété CSS display de cette balise UL est nulle ou "none", elle est passée en "block" */
			}
			else
			{
				sousMenu.display = 'none'; /* Dans le cas contraire, place cette même valeur sur "none" */
			}
		}
	}
}


Le CSS :

/* Style du menu */

	.menu {
		border:1px solid gray;
		display:block;
		float:left;
		padding:10px 5px 10px 5px;
		width:160px;
		}

	.menu FORM {
		background-color: #f2f2f2;
		border: 1px solid #909090;
		color: #505030;
		display:block;
		font-family: Verdana;
		font-weight: normal;
		margin-top:5px;
		width:160px;
		}

	ul#menu li ul {
		display:none;
		}

	ul#menu li:hover>ul {
		display:block;
		}

	ul#menu {
		font-family:Verdana;
		height:133px;
		list-style:none;
		margin:0px;
		margin-bottom:3px;
		padding:0px;
		width:148px;
		_width:150px;
		}

	ul#menu ul {
	border:1px solid black;
	border-bottom:0px;
	left:120px;
	list-style:none;	
	position:absolute;
	margin:0px;
	padding:0px;
	top:-1px;
	width:148px;
	_width:150px;
	}

	ul#menu ul li{
	margin-bottom:0px;
	border-top:0px;
	border-left:0px;
	border-right:0px;
	}
	
	ul#menu li
	{
	background:#C4C4C4;
	border:1px solid black;
	margin-bottom:3px;
	position:relative;
	}

	ul#menu a {
	color:#000000;
	display:block;
	font-style:normal;	
	text-decoration:none
	}

	ul#menu a:hover{
	background:#000000;
	color:#FFFFFF;
	font-style:normal;
	}


Voilà...

Le tout est visible ici.

GS.[/i][/i]
Raphaël,

Sauf erreur de ma part, mes <menus> sont positionnés en relative et les <sous-menus> en absolute. Mais, comme tu le soulignes, ces derniers dépendent effectivement de chaque menu. Ce qui impliquerait (si je t'ai bien compris) qu'ils seront toujours en dessous d'éléments frère de leurs parents dans le flux... Ouf.

GS.
Bon, c'est bien ce que j'avais vu :

Sous Firefox pas de problème avec les z-index. En revanche sous IE, impossible à cause en effet du "position:relative" qui si j'ai bien compris ce qui est expliqué ICI fait qu'on a aucune chance et qu'en plus ça colle à la norme. Smiley decu

Pour une fois.... Smiley fache
J'étais persuadé que IE ne le reconnaissait pas, après vérification il semblerait que oui, au temps pour moi. Merci
Si j'avais su... j'aurai pas "menu"...

Je me demande s'il est possible de s'extraire du contexte "relative" dans mon cas. Je vais faire quelques tests.

GS.
En plaçant le <ul> principal (ul#menu) en absolute, cela ne marche pas mieux. La seule solution semble de placer chaque (ul#menu li) en absolute, une par une, et de les positionner correctement. Malheureusement, une telle solution empêche, dans mon cas (SPIP), d'avoir un menu évoluant (dynamique) avec le contenu du site.

En fait, moins que la question du absolute/relative, le problème semble plutôt résider dans celui des relations parents/enfants.

Je viens de regarder l'un des menus sur Alsa. Il ressemble exactement à ce que je veux faire. Mais, miracle, il ne semble pas confronté au même problème. Je me demande si ce n'est pas parce qu'il utilise les <dl>, <dd>, etc.

Quel est votre avis ?

p.s. Si je n'utilise pas ce menu vu sur Alsa, c'est qu'il produit un effet de "clignotement" sous Firefox que j'essaie d'éviter en utilisant le code JS de JEP (cf. ce post).

GS.
Administrateur
a écrit :
Je me demande si ce n'est pas parce qu'il utilise les <dl>, <dd>, etc.

Non, la structure n'influe pas sur la mise en page.
Si ça fonctionne, c'est que les menus ne sont pas positionnés en absolu, comme je te l'ai expliqué : l'ensemble du menu global est positionné, et les sous-menus sont positionnés (par rapport à cet ensemble), mais les différents menus ne le sont pas.
J'avoue que là, tu me cloues sur place : je ne comprends donc pas très bien cette affaire de position...

Pour le moment, je vais essayer de biaiser le problème en plaçant le sous-menu en bordure droite du menu de façon à ne pas avoir le problème du recouvrement. Solution qui n'est tout de même pas très satisfaisante. Bref, je "bricole" encore.

(le DT et DD étant frères, tu es sur que cela n'arrange pas les choses ?)

GS.
Administrateur
gsaunier a écrit :
J'avoue que là, tu me cloues sur place : je ne comprends donc pas très bien cette affaire de position...

En résumé :

- Voici ma structure qui fonctionne :
<menu global> <-- positionné en absolu
<menus> <-- pas positionnés
<sous-menus> <-- positionnés en absolu (référénce = <menu global>)

- Voici la tienne qui pose problème :
<menu global> <-- position ?
<menus> <-- positionné en absolu
<sous-menus> <-- positionnés en absolu (référénce = <menu>)
Je comprends mieux. Ou, plus exactement, je crois comprendre mieux.

Si je reprends ton dernier message, Raphaël, puis essayer de le compléter

Est-ce que ta structure n'est pas celle-ci :

<menu global> positionné en absolu 

   <menu_1> pas positionnés </menu_1>

   <sous-menus_1> positionnés en absolu </sous-menus_1>

   [...]

   <menu_n> pas positionnés </menu_n>

   <sous-menus_n> positionnés en absolu </sous-menus_n>


</menu global> 


Alors que ma structure est celle-ci :

<menu global> pas positionné (donc dans le flux normal ?)

   <menu_1> pas positionnés 

     <sous-menus_1> positionnés en absolu </sous-menus_1>

   </menu_1>

   [...]

   <menu_n> pas positionnés

      <sous-menus_n> positionnés en absolu </sous-menus_n>

   </menu_n>

</menu global> 


Suis-je encore en train de me tromper (si le diagnostique de départ n'est pas bon, je vais avoir beaucoup de mal à guérir mon #!§$ de menu) ?

GS.
Je prends la liberté de remonter mon post. J'ai esayé de modifier les paramètres de mon menu en tenant compte des remarques de Raphaël, mais le recouvrement ne disparait pas.

GS.
Dernier post : avant le [résolu].

J'ai finalement abandonné la structure de menu utilisant des :
 <ul>
   <li>
     <ul><li></li></ul>
   </li>
 </ul>

au profit des <dl> :
<dl>
  <dt></dt>
  <dd></dd>
</dl>

<dt> et <dd> étant frères, cela permet d'utiliser le z-index et évite ainsi le recouvrement.

GS.