28172 sujets

CSS et mise en forme, CSS3

Bonjour,

J'ai fait un menu horizontal (un bandeau de navigation, en fait) dont vous pouvez voir un aperçu ici.

La hauteur de ce bandeau de navigation est variable en fonction de la hauteur du texte (et j'aimerais, si possible, que cela reste le cas). Elle est donc indiquée par un simple "padding: 2em 0;" dans la CSS. Le problème, c'est que :
. j'aimerais que la hauteur au-dessus et en-dessous du texte soit la même, bien entendu ;
. je voudrais pouvoir "ajouter" 10 pixels en bas de chaque lien pour y placer une image de "triangle inversé" (on voit ce petit triangle orange dans l'aperçu que j'ai mis en lien ci-dessus) indiquant que l'on se trouve bien sur cette page ;

Du coup, cela me pose quelques problèmes :
. l'espace sous le texte est nécessairement plus petit (10 pixels de moins) que l'espace au-dessus (j'ai triché sur l'aperçu en mettant un padding de 2.5em en-dessous) ;
. je ne peux pas mettre de "border" noir entre les différents liens (ils "dépasseraient" de 10 pixels vers le bas) ;
. le fond du bandeau de navigation "descend" trop vers le bas, comme on le voit bien sur l'aperçu que j'ai proposé.

Quelqu'un aurait-il une idée pour résoudre ces quelques problèmes ? Merci d'avance !

Voici le code que j'utilise pour créer ce bandeau de navigation : le code HTML d'abord :
<div id="navigation">
	<ul>
		<li class="current_page_item"><a class="first" href="http://sxjpl.free.fr/biblio/" accesskey="1">Accueil</a></li>
		<li class="current_page_item"><li>
		<a class="large" href="http://sxjpl.free.fr/biblio/infos">Infos pratiques</a></li>

		<li class="current_page_item"><li>
		<a class="large" href="http://sxjpl.free.fr/biblio/evenements">&Eacute;v&eacute;nements</a></li>
		<li class="current_page_item"><li>
		<a class="large" href="http://sxjpl.free.fr/biblio/adultes">Livres adultes</a></li>
		<li class="current_page_item"><li>
		<a class="last large" href="http://sxjpl.free.fr/biblio/enfants">Livres enfants</a></li>
	</ul>
</div>

Et le code CSS ensuite :
#navigation { overflow: hidden; }
	#navigation ul, #navigation li { padding: 0; margin: 0; display: inline; list-style: none; }
		#navigation li a { background: #9C0 url("../img/nav_arrow_s.png") 0 bottom no-repeat; float: left; display: block; color: #FFF; line-height: 1em; width: 97px; padding: 2em 0; text-align: center; font-size: 1em; text-transform: uppercase; white-space: nowrap; border-right: 1px solid #FFF; }
			#navigation li a.large { background: #9C0 url("../img/nav_arrow_l.png") 0 bottom no-repeat; width: 146px; }
			#navigation li a.last { border: 0; }
			#navigation li a:hover, #navigation li a:focus, #navigation li.current_page_item a { background-position: -97px bottom; background-color: #F90; }
				#navigation li a.large:hover, #navigation li a.large:focus, #navigation li.current_page_item a.large { background-position: -146px bottom; }

Modifié par Fix (23 Feb 2011 - 09:41)
À ta place je mettrais ta "nav-arrow" dans un span que je cacherait avec jQuery et que j'afficherait au survol... Smiley ohwell
Pourquoi pas... Mais n'est-ce pas gênant d'avoir un élément purement visuel inscrit "en dur" dans le code HTML ?
N'y aurait-il pas moyen de le conserver dans le background ?

Au passage, je viens de me rendre compte que le code HTML que j'ai donné est faux. Le "bon" code fait la différence entre le lien correspondant à la page sur laquelle on se trouve (il a une class "current_page_item") et les autres liens (qui, eux, n'ont pas de class du tout).

Je devrais pouvoir me servir de cela pour afficher mon image de "nav_arrow" sous le lien actif... mais comment ?

Voici donc le bon code :
<div id="navigation">
    <ul>
        <li class="current_page_item"><a class="first" href="http://sxjpl.free.fr/biblio/" accesskey="1">Accueil</a></li>
        <li><a class="large" href="http://sxjpl.free.fr/biblio/infos">Infos pratiques</a></li>
        <li><a class="large" href="http://sxjpl.free.fr/biblio/evenements">&Eacute;v&eacute;nements</a></li>
        <li><a class="large" href="http://sxjpl.free.fr/biblio/adultes">Livres adultes</a></li>
        <li><a class="last large" href="http://sxjpl.free.fr/biblio/enfants">Livres enfants</a></li>
    </ul>
</div>

Modifié par Igor (12 Feb 2011 - 09:50)
Bonsoir,

Je me permets de revenir à la charge, mon problème n'étant toujours pas résolu.

J'ai retravaillé mon code. Mais actuellement, j'ai un effet de "clignotement" à chaque fois que la souris arrive sur un de mes boutons de navigation, ou en sort (on voit clignoter vert, puis orange). C'est visible en ligne ici. Je rappelle que mes problèmes concernent le bandeau de navigation en haut de page (contenant les liens "Accueil", "Infos pratiques", etc.).

J'ai eu beau triturer mon code CSS, je ne vois pas ce qui est à l'origine de ce clignotement. Quelqu'un pourrait-il m'aider ? Je fais mes tests sous Firefox 3.6.13 (avec Windows 7).

Merci de votre aide !
Plusieurs solutions.

En CSS3, tu peux utiliser border-image.
En CSS2.1 (supporté dans IE8), tu peux utiliser un pseudo élément :after positionné en absolu.

Et en CSS supporté aujourd'hui par papy IE7, tu peux utiliser une image de fond qui agira comme un masque de 10px de haut en bas de tes éléments de menu. J'ai préparé une image pour démo (à voir sur fond coloré), c'est du 2 en 1 avec l'image normale en haut et l'état «actif» en bas.

On doit pouvoir imaginer deux ou trois autres solutions.

PS: pas d'effet de clignotement pour moi, Firefox 4 sous Mac.
Modifié par fvsch (20 Feb 2011 - 22:57)
J'oublie les 2 premières solutions, puisqu'elles ne sont pas supportées dans IE7.

C'est précisément la dernière que j'ai utilisée... avec les inconvénients que j'ai expliqués dans mon premier billet. Je me permets de les rappeler :
. à l'intérieur de chaque lien, l'espace sous le texte sera de 10 pixels plus petit que l'espace au-dessus du texte (on peut tricher en faisant un padding 2em au-dessus du texte, et un padding de 2.5em par exemple en-dessous, mais ça reste une solution assez approximative) ;
. je ne peux pas mettre de "border" noir entre les différents liens (ils "dépasseraient" de 10 pixels vers le bas).

Je me permets également de rappeler mon code HTML actuel :
<div id="navigation">
	<ul>
		<li class="current_page_item"><a class="first" href="http://sxjpl.free.fr/biblio/" accesskey="1">Accueil</a></li>
		<li><a class="large" href="http://sxjpl.free.fr/biblio/infos">Infos pratiques</a></li>
		<li><a class="large" href="http://sxjpl.free.fr/biblio/agenda">Animations</a></li>
		<li><a class="large" href="http://sxjpl.free.fr/biblio/adultes">Livres adultes</a></li>
		<li><a class="last large" href="http://sxjpl.free.fr/biblio/jeunesse">Livres jeunesse</a></li>
	</ul>
</div>

ainsi que mon code CSS :
#navigation, #navigation li a { overflow: hidden; background: #9CC url("../img/white_bottom.png") 0 bottom repeat-x; }
	#navigation ul, #navigation li { padding: 0; margin: 0; display: inline; list-style: none; }
		#navigation li a { float: left; display: block; color: #FFF; line-height: 1em; width: 101px; padding: 2em 0 2.6em 0; text-align: center; font-size: 1em; text-transform: uppercase; white-space: nowrap; border-right: 1px solid #FFF; }
			#navigation li a.large { width: 161px; }
			#navigation li a:hover, #navigation li a:focus { background-color: #C03; }
			#navigation li.current_page_item a { background: #C03 url("../img/nav_arrow.png") center bottom no-repeat; }


Enfin, le tout est visible sur cette page.

PS : l'effet de clignotement semble avoir disparu pour moi aussi, depuis que j'ai modifié les couleurs ! Bizarre, bizarre...
Modifié par Fix (21 Feb 2011 - 07:58)
Fix a écrit :
on peut tricher en faisant un padding 2em au-dessus du texte, et un padding de 2.5em par exemple en-dessous, mais ça reste une solution assez approximative

Tu fais du padding en pixels et on n'en parle plus. Genre 20px en haut, 30px en bas.

Pour le reste, il n'y a pas de solution miracle:

1. L'image de fond «masque» marche dans IE7, mais ne te permet pas d'utiliser une bordure entre les éléments. (On peut tenter de gruger avec quelques astuces mais ça devient pas mal compliqué.)
2. Rajouter un élément décoratif avec un SPAN vide (positionné en absolu) marche dans IE7, mais ça fait un code HTML pas très propre (pas grave du tout ici) et si on utilise un CMS qui génère un code HTML précis on n'a pas forcément cette possibilité.
3. Rajouter un pseudo-élément décoratif avec :after (positionné en absolu) est plutôt propre mais ne marche pas dans IE7 (mais c'est pas la fin du monde!).
bonsoir,

Si je peut me permettre d'intervenir si tardivement. Smiley confused

la bordure noire (ou differente de la couleur du fond du conteneur principal) ne me semble pas necessaire.

Line-height et padding-bottom peuvent faire l'affaire.

Display:inline-block; (avec une petite correction su letter/word-spacing) peut aussi aider.

line-height peut servir avantageusement a donner la hauteur voulu a un element creer avec content via le pseudo "after", pour simuler une bordure.(pour ie7 la bordure sera en css en couleur du fond du conteneur principal)

Une image en tant que masque cachant une couleur de fond est a priori la solution la plus simple et solide.

fvsch a deja evoqué ces pistes.

je me suis permis de faire un test en partant de ton apercu.png basé sur inline-block + line-height + em + padding + masque + pseudo:after

http://gcyrillus.free.fr/essai/menu-test.html

cordialement
Je viens de regarder tout cela très attentivement. Je vais apprendre beaucoup de choses ! Un immense merci !

Il y a quand même certaines choses que je comprends mal : avec la première solution, pourquoi devoir changer mon code CSS pour un display:inline-block ? Et pourquoi devoir "corriger" letter-spacing et word-spacing ? Est-ce pour une question de compatibilité avec IE ? Si oui... alors en quoi mon code n'était-il pas compatible ?
Bonjour,
Fix a écrit :

Il y a quand même certaines choses que je comprends mal : avec la première solution, pourquoi devoir changer mon code CSS pour un display:inline-block ? Et pourquoi devoir &quot;corriger&quot; letter-spacing et word-spacing ? Est-ce pour une question de compatibilité avec IE ? Si oui... alors en quoi mon code n'était-il pas compatible ?


Si ton code fonctionne tu n'as aucune raison de le modifié, ce n'est qu'un test avec une approche ou point de vue diffèrent.

Pour inline-block, les éléments ainsi formatés se comportent comme des images ou des mots. l'indentation dans le code html est alors considéré comme un espace.

Word-spacing(le plus logique) permet d'éliminer cette espace et accoler les éléments les uns aux autres.Letter-spacing c'est pour G.Chrome.

J'ai mis un moment a te proposer cette approche, et ce qui m'a poussé a le mettre en ligne c'est cette histoire de bordure noire( a vrai dire je comprend pas trop , le blanc me semble mieux) et les padding.
Le line-height en em + padding en px permet de melanger ces deux unité pour calé a une image de fond et un affichage pouvant differer d'une config a une autre(dans ce cas, ce n'est pas universelle).

Pour te rendre compte des effets ou de l'utilité de tel ou tel règle je te propose de tout simplement de les enlevé ou de modifier leur valeur. (float+line-height+padding devraient aussi cohabité sans problémes Smiley smile ) .

Bonne continuation.
Merci pour ces explications... lumineuses !
Il ne me reste plus qu'à faire des tests, donc Smiley cligne

Bonne journée à tous !

Au passage, je considère ce billet comme résolu.
Modifié par Fix (23 Feb 2011 - 09:41)