28172 sujets

CSS et mise en forme, CSS3

Bonjour,
j'ai réalisé un scrolling sur un tableau tout en gardant l'entête fixe.
La largeur du tableau est égale à 100%, quelques colonnes ont une largeur fixe, les autres vont prendre le reste du 100%.
Je veux que les entêtes (TH) prennent toute la largeur du tableau, et que les colonnes (TD) respecte la largeur des entêtes (TH).
Merci à vous Smiley smile

Voici le code :

#outer {
	padding-top:60px;
	width:100%;
	position:relative;
}
#inner {
	height:100px;
	overflow-x:hidden;
	overflow-y:auto;
	width:100%;
}
table{
	width:100%;
}
table thead {
	position:absolute;
	top:0;
	width:100%;
}


<div id="outer">
	<div id="inner">
		<table border="1">
			<thead>
				<tr>
					<th width="200">posuere urna</th>
					<th width="200">posuere urna</th>
					<th>posuere urna</th>
					<th>posuere urna</th>
					<th>posuere urna</th>
				</tr>
				<tr>
					<th>posuere urna</th>
					<th>posuere urna</th>
					<th>posuere urna</th>
					<th>posuere urna</th>
					<th>posuere urna</th>
				</tr>
			</thead>
			<tbody>
				<tr>
					<td>posuere urna</td>
					<td>posuere urna</td>
					<td>posuere urna</td>
					<td>posuere urna</td>
					<td>posuere urna</td>
				</tr>
				<tr>
					<td>posuere urna</td>
					<td>posuere urna</td>
					<td>posuere urna</td>
					<td>posuere urna</td>
					<td>posuere urna</td>
				</tr>
				<tr>
					<td>posuere urna</td>
					<td>posuere urna</td>
					<td>posuere urna</td>
					<td>posuere urna</td>
					<td>posuere urna</td>
				</tr>
				<tr>
					<td>posuere urna</td>
					<td>posuere urna</td>
					<td>posuere urna</td>
					<td>posuere urna</td>
					<td>posuere urna</td>
				</tr>
				<tr>
					<td>posuere urna</td>
					<td>posuere urna</td>
					<td>posuere urna</td>
					<td>posuere urna</td>
					<td>posuere urna</td>
				</tr>
				<tr>
					<td>posuere urna</td>
					<td>posuere urna</td>
					<td>posuere urna</td>
					<td>posuere urna</td>
					<td>posuere urna</td>
				</tr>
				<tr>
					<td>posuere urna</td>
					<td>posuere urna</td>
					<td>posuere urna</td>
					<td>posuere urna</td>
					<td>posuere urna</td>
				</tr>
			</tbody>
		</table>
	</div>
</div>	
Bonsoir,

C'est assez tordu à réaliser avec ces histoires de pourcentages puisqu'en passant la balise <thead> en position absolue, celle-ci perd la largeur que lui conférait le tableau nativement.

Ajouter cette règle CSS pour retrouver une largeur équivalente serait trop simple...
thead {width: 100%;}


Cela ne marche pas et je me suis donc penché sur les balises <th> dont on peut modifier tranquillement la largeur. Seul souci : il faut d'abord retrouver une largeur globale de 100% avant de spécifier la largeur fixe de 200px pour les deux premières colonnes, afin que les trois suivantes puissent se partager la largeur restante de la fenêtre (capiche ?) Smiley confus

La seule solution que j'ai trouvé consiste à ajouter une ligne supplémentaire où l'on fusionne toutes les cellules à l'aide de l'attribut colspan. Après cela, on ne peut toujours pas spécifier une largeur de 100%, mais il est possible de définir volontairement une très grande valeur, ce qui aura pour effet d'occuper la totalité de la fenêtre en terme de largeur.

HTML :
<div id="outer">
	<div id="inner">
		<table>
			<thead>
				<tr>
					<th colspan="5"></th>
				</tr>
				<tr>
					<th class="fixe">posuere urna</th>
					<th class="fixe">posuere urna</th>
					<th>posuere urna</th>
					<th>posuere urna</th>
					<th>posuere urna</th>
				</tr>
				<tr>
					<th>posuere urna</th>
					<th>posuere urna</th>
					<th>posuere urna</th>
					<th>posuere urna</th>
					<th>posuere urna</th>
				</tr>
			</thead>
			<tbody>
				<tr>
					<td class="fixe">posuere urna</td>
					<td class="fixe">posuere urna</td>
					<td>posuere urna</td>
					<td>posuere urna</td>
					<td>posuere urna</td>
				</tr>
				<tr>
					<td>posuere urna</td>
					<td>posuere urna</td>
					<td>posuere urna</td>
					<td>posuere urna</td>
					<td>posuere urna</td>
				</tr>
				<tr>
					<td>posuere urna</td>
					<td>posuere urna</td>
					<td>posuere urna</td>
					<td>posuere urna</td>
					<td>posuere urna</td>
				</tr>
				<tr>
					<td>posuere urna</td>
					<td>posuere urna</td>
					<td>posuere urna</td>
					<td>posuere urna</td>
					<td>posuere urna</td>
				</tr>
				<tr>
					<td>posuere urna</td>
					<td>posuere urna</td>
					<td>posuere urna</td>
					<td>posuere urna</td>
					<td>posuere urna</td>
				</tr>
				<tr>
					<td>posuere urna</td>
					<td>posuere urna</td>
					<td>posuere urna</td>
					<td>posuere urna</td>
					<td>posuere urna</td>
				</tr>
				<tr>
					<td>posuere urna</td>
					<td>posuere urna</td>
					<td>posuere urna</td>
					<td>posuere urna</td>
					<td>posuere urna</td>
				</tr>
			</tbody>
		</table>
	</div>
</div>


CSS :
body {
	margin: 0;
	padding: 0;
}

#outer {
	padding-top: 60px;
	position: relative;
}

#inner {
	height: 100px;
	overflow-x: hidden;
	overflow-y: auto;
}

table{
	width: 100%;
	border-collapse: collapse;
}

thead {
	position: absolute;
	left: 0;
	top: 0;
}

th, td {
	border: solid 1px #000;
}

th[colspan] {
	width: 5000px;
	border: none;
}

.fixe {
	width: 200px;
}


Tout cela reste de la grosse bidouille et je ne suis pas sûr que ce soit interprété correctement sur tous les navigateurs. En plus d'un point de vue sémantique on se retrouve avec une balise <th> vide, ce qui n'arrange sûrement pas l'accessibilité...
Merci jeremy, mais les cellules (td et th) de la même colonne n'ont pas la même largeur !!
Sur Firefox 8 et Internet Explorer 9 j'obtiens un résultat satisfaisant. Bien sûr il reste un décalage entre les éléments <th> et <td> à cause de la barre verticale de scroll, mais ça je ne sais pas si on peut y remédier efficacement... Smiley ohwell

Je pense qu'il faudrait de toute façon opter pour des positionnements axés sur des balises <div> pour les titres de colonnes et ne garder le tableau que pour le contenu.
jeremy-p a écrit :
Bien sûr il reste un décalage entre les éléments &lt;th&gt; et &lt;td&gt; à cause de la barre verticale de scroll

Non, ce n'est pas à cause du scroll, essayer de donner une largeur à une cellule (entete th) et vous allez voir que les cellules de la même colonne ne vont pas respecter cette largeur.
Ah oui mais à partir du moment où on a sorti le <thead> du flux, il est normal qu'on ne retrouve pas un comportement "synchrone" entre l'en-tête d'une colonne et ses cellules de contenu. C'est d'ailleurs pour cela que j'ai ajouté la classe "fixe" qui permet d'attribuer une même largeur à ces deux types de cellules pour qu'on retrouve une taille homogène de part et d'autre du tableau.

HTML :
<thead>
	<tr>
		<th [b]class="fixe"[/b]>posuere urna</th>
		<th [b]class="fixe"[/b]>posuere urna</th>
		...
	</tr>
	...
</thead>
<tbody>
	<tr>
		<td [b]class="fixe"[/b]>posuere urna</td>
		<td [b]class="fixe"[/b]>posuere urna</td>
		...
	</tr>
	...
</tbody>


CSS :
.fixe {
	width: 200px;
}


Ici on aura bien une largeur de 200px pour les deux premières en-têtes, mais aussi pour les deux premières cellules, ce qui permettra une correspondance des colonnes. Après, libre à vous de modifier cette largeur dans le fichier CSS ou bien même de rajouter davantage de classes ou d'autres règles s'il y a plusieurs largeurs à fixer.
jeremy-p a écrit :
Ici on aura bien une largeur de 200px pour les deux premières en-têtes, mais aussi pour les deux premières cellules, ce qui permettra une correspondance des colonnes.


Absolument pas! plutôt on aura une correspondance des 2 premiers colonnes uniquement (qui ont une largeur bien définie). Les cellules (th et td) des colonnes qui n'ont pas une largeur définie ne seront pas correspondantes, leurs largeurs dépendent de leur contenu.
Donc la seule solution (qui ne répond pas à mes exigences) est d'attribuer une largeur pour toutes les colonnes.