28172 sujets

CSS et mise en forme, CSS3

Bonjour,

J'ai une liste dont les éléments sont des images qui sont toutes de la même hauteur. Le nombre d'éléments dans la liste peut varier.

Cette liste est placée dans un conteneur dont la taille est définie en pixel.

J'aimerais que la hauteur de chaque élément <li> soit relative à cette taille fixe. De cette manière la liste va d'un bout a l'autre du bloc, quel que soit le nombre d'élément.

Html :

	<div id="main">
		<ul id="tabs">
			<li><img src="images/about.png"/></li>
			<li><img src="images/work.png"/></li>
			<li><img src="images/links.png"/></li>
			<li><img src="images/contact.png"/></li>
		</ul>
	</div>


Css:

		#main {
			position: relative;
			height: 600px;
			border: 1px solid red;
		}
		
		#tabs {
			list-style: none;
			margin: 0;
			padding: 0;
		
		}
		
		#tabs li {
			margin-top: 5px;

		}


J'ai hasardeusement tenter quelques méthodes mais sans succès.
Par exemple:
#tabs {height: auto;}

#tabs li {line-height: auto;}

#tabs li img {margin: auto;}

etc ...

Que puis-je faire ? Merci Smiley smile
Bonjour,

Comme base de travail, essaie un peu ceci :
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"   "http://www.w3.org/TR/html4/loose.dtd">
<html>
	<head>
		<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
		<title>Liste d'images modulable</title>
	<style type="text/css">
	#main {
		position: relative;
		height: 600px;
		border: 1px solid red;
	}
	#tabs {
		list-style: none;
		margin: 0;
		padding: 0;
	}
	#tabs li {
		margin-top: 5px;
	}
	li img {
		height: 100%;
		width: 100px; /* largeur de tes images, ici 100px par exemple */
	}
	</style>
	</head>
	<body>
		<div id="main">
			<ul id="tabs">
				<li><img src="images/about.png" alt="about" /></li>
				<li><img src="images/work.png" alt="work" /></li>
				<li><img src="images/links.png" alt="links" /></li>
				<li><img src="images/contact.png" alt="contact" /></li>
			</ul>
		</div>
		<script type="text/javascript">
			var li_img = document.getElementById('tabs').getElementsByTagName("li");
			var nbre_li = li_img.length;
			for(var x=0; x<nbre_li; x++){
				li_img[x].style.height = (600/nbre_li - 5) + "px";
			}
		</script>
	</body>
</html>

Modifié par lddsoft (25 May 2011 - 10:38)
Administrateur
ghilan a écrit :

J'aimerais que la hauteur de chaque élément &lt;li&gt; soit relative à cette taille fixe. De cette manière la liste va d'un bout a l'autre du bloc, quel que soit le nombre d'élément.

Hello,

A ma connaissance, le moyen le plus simple, le plus adapté et le plus pertinent pour ce type d'affichage très particulier est : le tableau de mise en page en HTML (ou mieux en CSS avec display: table-row).
En effet, c'est le comportement normal des cellules de tableau de se répartir automatiquement dans l'espace de leur parent.
Bonjour,

Merci de ta réponse, elle marche presque très bien, je ne pensais pas à une solution en Js mais après tout pourquoi pas, si ça marche ^^.

Ce qui me gêne est que les images sont étirée sur toute la hauteur du <li>, j'aimerais qu'elles soient à leur hauteur originale et centrée verticalement.

j'ai donc modifié le CSS de #tabs li img comme ceci:

#tabs li img {
	vertical-align: middle;
	width: 30px;
}


Seulement ça ne marche pas, l'image reprends bien sa hauteur originale mais reste collée à la baseline du <li> ...

Mais bon c'est un détail qui se règle facilement j'imagine, merci beaucoup pour ce petit code Js !

Au fait, je l'ai légèrement modifié pour qu'il récupère lui même la hauteur définie du conteneur #main, voici ce que ça donne:

var li_img = document.getElementById('tabs').getElementsByTagName("li"),
	nbre_li = li_img.length,
	main_height = window.getComputedStyle(document.getElementById('main'),
		null).getPropertyValue('height');
	main_height = main_height.substring(0, main_height.length-2);

for (var x=0; x<nbre_li; x++) {
	li_img[x].style.height = (main_height / nbre_li - 5) + "px";
}


Qu'en penses tu ? Est ce risqué d'utiliser getComputedStyle ? J'ai déjà lu, il me semble, que ce n'était pas vraiment compatible avec tout les navigateurs, ou un truc du genre ...

---
Edit pour la réponse de Raphael

Raphael a écrit :

Hello,

A ma connaissance, le moyen le plus simple, le plus adapté et le plus pertinent pour ce type d'affichage très particulier est : le tableau de mise en page en HTML (ou mieux en CSS avec display: table-row).
En effet, c'est le comportement normal des cellules de tableau de se répartir automatiquement dans l'espace de leur parent.


Oui en effet c'est plutôt une solution de ce genre que je cherchais. Je vais essayer de chipoter avec display: table-row. Merci ! Smiley biggrin Je vous tiens au courant.
Modifié par ghilan (25 May 2011 - 17:01)
Merci, en fait je ne suis pas sûr de bien comprendre. Est ce que je dois encore garder la structure html de la liste ?

En appliquant le display: table-row aux éléments <li> je n'obtiens pas vraiment ce que je recherche. Je dois les remplacer par des <div>, voir des <span> ?
Administrateur
ghilan a écrit :
Merci, en fait je ne suis pas sûr de bien comprendre. Est ce que je dois encore garder la structure html de la liste ?

En appliquant le display: table-row aux éléments &lt;li&gt; je n'obtiens pas vraiment ce que je recherche. Je dois les remplacer par des &lt;div&gt;, voir des &lt;span&gt; ?


Si tu optes pour cette solution, tu as deux pistes complètement différentes :
- soit tu passes en tableaux HTML, et tu changes tes <ul>, <li> en <table>, <tr>, <td>, etc.
- soit tu choisis un affichage via CSS et il ne faut surtout pas changer ton HTML (sinon cela n'aurait aucun avantage).

Petit exemple rapide :
<div id="main"> 
        <ul id="tabs"> 
            <li>bla</li> 
            <li>bla</li> 
            <li>bla</li> 
            <li>bla</li> 
        </ul> 
    </div> 

#main {    
    border: 1px solid red; 
} 
 
#tabs { 
    margin: 0; 
    padding: 0; 
 	display: table;
 	height: 600px;
 	width: 100%;
} 
 
#tabs li { 
		display: table-row;
}


PS : à mon avis, ton div #main ne sert à rien
PS2 : attention : les valeurs table, table-cell et table-row ne sont reconnues sur IE qu'à partir de la version 8 Smiley ohwell
Hum oui je vois, seulement j'ai un inconvénient maintenant, j'aurais peut être du en parler plus tôt mais je pensais que ça importait peu.

J'avais mis les coins gauches des <li> arrondis, maintenant ils sont tout ce qu'il y a de plus carré. Je suppose que c'est parce que une ligne de tableau ne peut avoir de coin arrondi ...

Autre souci, je n'arrive toujours pas a centrer verticalement les images. Décidément je ne suis vraiment pas doué pour le CSS Smiley decu

Le conteneur #main contiendra en fait d'autres éléments, c'est vrai que dans cet exemple il ne sert a rien mais c'est bien lui qui doit définir la hauteur.

Voilà donc comment est mon CSS actuellement:

		#main {
			height: 600px;
			border: 1px solid red;
		}
		  
		#tabs {  
			margin: 0;  
			padding: 0;  
			display: table;
			
			height: 100%; 
			width: 30px;   /* = largeur des images */
		}  
		  
		#tabs li {  
			display: table-row;
			
			border-top-left-radius: 8px;
			border-bottom-left-radius: 8px;
			-webkit-border-top-left-radius: 8px;
			-webkit-border-bottom-left-radius: 8px;
			-moz-border-radius-topleft: 15px;
			-moz-border-radius-bottomleft: 15px;
		}
		
		#tabs li img {
			vertical-align: middle; /* ne marche pas */
		}

Modifié par ghilan (25 May 2011 - 22:08)
Vu les soucis, j'en reviens quand même à ma solution (améliorée Smiley smile ) ou alors, il faut choisir d'utiliser un tableau html classique (table-tr-td).
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
    <title> Liste d'images modulable </title>
    <style type="text/css">
/*<![CDATA[*/
        #main {
                height: 600px;
                border: 1px solid red;
        }
        #tabs {
                list-style: none;
                margin: 0;
                padding: 0;
        }
        li img {
		/* largeur de tes images, ici 100px par exemple */
		width: 100px;
		/* hauteur de tes images, ici 50px par exemple */
		height: 50px;
        }
    /*]]>*/
    </style>
  </head>
  <body>
    <div id="main">
      <ul id="tabs">
		<li><img src="images/about.png" alt="about" /></li>
		<li><img src="images/work.png" alt="work" /></li>
		<li><img src="images/links.png" alt="links" /></li>
		<li><img src="images/contact.png" alt="contact" /></li>
      </ul>
    </div>
	<script type="text/javascript">
	//<![CDATA[
		var li_img = document.getElementById('tabs').getElementsByTagName("li"); // tableau des li de tabs
		var imag = document.getElementById('tabs').getElementsByTagName("img"); // tableau des images de tabs
		var nbre_li = li_img.length; // nombre d'images
		// calculer la différence entre la hauteur du li et celle de l'image
		var difference = (600/nbre_li)-50;
			// 600 = hauteur fixe du div #main (à adapter selon le cas)
			// 50 = hauteur fixe des images (à adapter selon le cas)
		for(var x=0; x<nbre_li; x++){
			li_img[x].style.height = (600/nbre_li) + "px"; // ajustement de la hauteur du li
			imag[x].style.marginTop = difference/2+"px"; // ajustement du margin-top de l'image
		}
    //]]>
    </script>
  </body>
</html>
Oui merci Iddsoft, ne maitrisant pas suffisamment la propriété css display je vais choisir la simplicité et ta solution javascript.

Par contre pour centrer verticalement l'image j'aurais quand même bien voulu le faire en css, ça ne doit pas être si compliqué que le display, j'image que c'est à ma portée ^^ C'est un peu exagérer de le faire en Js non ? Quand je fais des recherches sur le forum ou sur le net c'est vrai qu'il n'y a pas des masses de solution ... Smiley ohwell

Dommage que le CSS soit si performant pour certaines choses parfois pas très utiles et parfois si mal pensé sur des choses plus essentielles.
Administrateur
ghilan a écrit :

Dommage que le CSS soit si performant pour certaines choses parfois pas très utiles et parfois si mal pensé sur des choses plus essentielles.

C'est généralement (sans vouloir te vexer) parce que les gens ne connaissent pas assez bien CSS.
Sans avoir testé, je pense que "vertical-align: middle" sur les listes ou les images devrait fonctionner, et ça me semble être une solution très simple.
Modifié par Raphael (26 May 2011 - 16:52)
Non, t'inquiète pas, je suis le premier a dire que je manque de connaissance en CSS Smiley langue
Par contre j'ai essayé aussi le vertical-align: middle; mais je n'arrive pas a le faire fonctionner ... vraiment pas doué Smiley ohwell
Administrateur
Bon alors il est peut-être nécessaire d'avoir un élément à l'intérieur.
Après tout, les table-row ne sont que des <tr> (rangées de cellules) et ont généralement besoin de cellules à l'intérieur. Plein de propriétés ne s'y appliquent pas.
@ghilan
ghilan a écrit :
C'est un peu exagérer de le faire en Js non ?

Pourquoi "exagéré", alors que pas mal de développeurs web utilisent, pour de petits effets visuels, des librairies js beaucoup plus lourdes que ces quelques malheureuses lignes de javascript?
Le temps où l'on craignait que l'utilisateur ne désactive le javascript sur son navigateur est bel et bien révolu!
Alors pourquoi se priver d'un outil merveilleux comme javascript? De plus, je ne vois pas bien comment tu vas pouvoir aligner verticalement tes images, surtout en n'en connaissant pas nécessairement le nombre exact au départ (voir ton post initial).

Cordialement