28172 sujets

CSS et mise en forme, CSS3

Bonjour.

Je cherche à mettre en place un menu qui réponde au critères suivants :
- css only, pas de JavaScript
- horizontal
- avec 1 menu déroulant en-dessous de certains items qui se déploie au hover, ou alors au clic, ça m'est égal (mais au clic, ça suppose que si on clic sur un autre item, ça ferme en même temps celui qui est éventuellement déjà ouvert...)
- largeur 100% de la fenêtre
- qui reste forcément sur une seule ligne même si on réduit beaucoup la largeur de la fenêtre, quitte à sortir de la fenêtre
- dont les items s'agrandissent (en rétrécissant les autres) au passage de la souris

La meilleure solution que j'ai trouvé pour l'instant, c'est de le faire sous la forme d'un tableau, avec les display table, table-row et table-cell, ce qui permet de garantir :
- qu'il ne va pas passer sur une deuxième ligne si la fenêtre est rétrécie
- que je peux contrôler la largeur des items au hover

Mon problème, c'est que je ne vois pas comment mettre en place les sous-menus.
- comme les items sont des cellules, leurs sous-menus respectifs ne peuvent pas en faire partie ou être un élément enfant, sinon lorsqu'un apparait, il agrandit toute la ligne de cellules en hauteur. A moins, bien sûr de forcer le débordement, mais ça ne me parait pas possible dans une cellule de tableau.
- si je met les sous-menus dans des div à part pour les faire apparaitre au hover sur un item, comment je fais pour les cibler avec un :hover depuis l'item correspondant ?
- si je met les sous-menus dans des div à part pour les faire apparaitre au clic sur un item, ça fonctionne grâce à :target mais comment je fais pour les faire disparaitre au clic sur un autre item ?

Merci d'avance pour vos idées
Modifié par louisss (19 Apr 2013 - 12:31)
Merci petitours220, mais malheureusement non, ça ne correspond pas exactement à ce que je veux, car si je met à l'horizontal ce menu vertical, une fenêtre trop étroite provoquera le débordement sur une deuxième ligne d'une partie du menu, ce que je ne veux pas. Smiley decu
J'ai envisagé la solution suivante : je garde la mise en page en tableau avec une première ligne pour les items de mon menu, et une seconde ligne pour les sous-menus. Et j'essaie de contrôler une cellule de la deuxième ligne par le hover de la première, mais après bien des essais, ça ne marche pas. Est-ce tout simplement impossible ? Faut-il s'y prendre autrement ?

Voici quelques tests que j'ai fais à partir des classes suivantes :
.tableaumenu : classe du div qui sert de tableau
.lignemenu : classe des div qui servent de ligne
.celluletableau : classe des div qui servent de cellule

Ce test change la couleur de la dernière cellule d'une ligne quand on passe sur la première de la même ligne (pourtant je prend les cellules enfants du tableau, pas d'une ligne particulière !)

.tableaumenu .cellulemenu:first-child:hover ~ .cellulemenu:last-child
{
	color: #FF0000;
}


Ce test ne fonctionne pas : il n'y a que 5 cellules par ligne, et la première cellule de la seconde ligne n'est pas considérée comme la sixième du tableau.

.tableaumenu .cellulemenu:first-child:hover ~ .cellulemenu:nth-child(6)
{
	color: #FF0000;
}


Une idée ? Qu'est-ce qui m'échappe ?
Ok, cette fois-ci j'ai essayé de faire ce qui me paraissait le plus logique : contrôler par le hover de la première cellule de la première ligne du tableau la mise en forme de la première cellule de la seconde ligne du tableau.
Aucune de ces 2 tentatives ne fonctionne. Est-ce que quelqu'un saurait quelle correction les ferait fonctionner ?

.tableaumenu .lignemenu:first-child .cellulemenu:nth-child(1):hover ~ .lignemenu:nth-child(2) .cellulemenu:nth-child(1)
{
	color: #FF0000;
}



.tableaumenu .lignemenu:first-child .cellulemenu:nth-child(1):hover ~ .tableaumenu .lignemenu:nth-child(2) .cellulemenu:nth-child(1)
{
	color: #FF0000;
}


Merci d'avance
Bon, j'ai trouvé une solution. Pas idéale, mais c'est déjà pas mal.
Comme je n'arrive pas à contrôler une cellule de la deuxième ligne de mon tableau à partir du hover d'une cellule de la première ligne, il y a au moins une chose que je peux faire : contrôler une cellule de la deuxième ligne à partir du hover de la première ligne entière.
Du coup, en répétant ça pour tous les sous-menus, j'arrive à provoquer leur affichage tous ensembles lors du passage de la souris sur n'importe quel item.
Exemple :


.lignemenu:first-child:hover ~ .lignemenu:nth-child(2) .cellulemenu:first-child
{
	visibility: visible;
}

.lignemenu:first-child:hover ~ .lignemenu:nth-child(2) .cellulemenu:nth-child(2)
{
	visibility: visible;
}

.lignemenu:first-child:hover ~ .lignemenu:nth-child(2) .cellulemenu:nth-child(5)
{
	visibility: visible;
}


Pour améliorer un peu ça, je fais en sorte que lorsqu'on passe de la première ligne à le seconde (donc d'un item à un sous-menu), seul le sous-menu visé reste visible. C'est assez facile puisque par défaut, toutes les cellules de la deuxième ligne qui étaient visibles grâce au hover sur la première disparaissent dès qu'on la quitte :

// J'ai numéroté mes cellules avec un id="cellN"
#cell6:hover
{
	visibility: visible;
}

#cell7:hover
{
	visibility: visible;
}

#cell10:hover
{
	visibility: visible;
}


Bon, reste que c'est pas terrible que tous les sous-menus apparaissent ensemble. Je relance donc encore l'appel pour le petit bout de solution qui me manque.
Ok, j'ai la solution : j'utilise bien un tableau, mais avec une seule ligne. Et au lieu de considérer chaque cellule comme un item de mon menu, je la considère comme le conteneur qui va rassembler un item et son éventuel sous-menu.
Surviennent alors quelques nouvelles problématiques comme par exemple sur le border-radius moins simples à mettre en oeuvre, mais globalement j'obtiens le résultat attendu.
Modifié par louisss (22 Apr 2013 - 16:07)