28172 sujets

CSS et mise en forme, CSS3

Bonjour à tous,

La propriété border-radius permet d'arrondir les coins d'une DIV ou d'une cellule, par exemple.
Mais je n'arrive pas à l'appliquer à une <table> complète.

Dans le code suivant, le tableau reste parfaitement carré :

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style type="text/css">
.Tableau { border-radius: 10px; border:1px solid #9ec3dd; padding: 10px; }
table { border-collapse: collapse; border-radius: 10px; }
td { border:1px solid #9ec3dd; }
.entete { background:#e2edf5; }
.pied { background:#eeeeee; }
</style> 
</head>
<body>
<div class="Tableau">
<table>
<tr class="entete"><td>Zone T1</td><td>Zone T2</td><td>Zone T3</td></tr>
<tr class="milieu"><td>Zone C1</td><td>Zone C2</td><td>Zone C3</td></tr>
<tr class="pied"  ><td>Zone P1</td><td>Zone P2</td><td>Zone P3</td></tr>
</div>
</body>
</html>


Certes cela fonctionne si on identifie les quatre coins et que l'on place la propriété radius correspondante sur chacune des cellules, mais tout serait plus simple si on pouvait l'appliquer de façon générale à la table. Est-ce possible ?

Vous allez dire que je suis un peu fainéant, mais en fait je génère mes tableaux dynamiquement, avec parfois des propriétés col-span ou row-span. Il n'est donc pas toujours facile d'identifier les coins.

Merci à vous.
Administrateur
Bonjour et bienvenue, Smiley smile

je vois des classes .entete, .milieu et .pied sur des éléments tr : il y a des éléments prévus exprès pour ça : thead, tfoot et tbody (dans cet ordre-là : tfoot est bien avant tbody (*)).
Et thead est à faire précéder d'un élément caption pour une meilleure accessibilité.
EDIT: exemple de code HTML correct : http://openweb.eu.org/articles/tableaux_css

Pour tenter de répondre à ta question : les sélecteurs CSS avancés permettent de cibler les 4 coins d'une table en connaissant un minimum sa structure, en particulier tableau avec cellules d'entête en haut ou à gauche ou les 2 (tableau à double entrée dans ce dernier cas).
Dans le cas d'un tableau "vertical" avec une (unique) ligne de cellules d'entête en haut, pas de pied de tableau tfoot et que des cellules de contenu dans tbody, ça donne les 4 sélecteurs suivants :
table > thead > tr > th:first-child {
/* */
}

table > thead > tr > th:last-child {
/* */
}

table > tbody > tr:last-child > td:first-child {
/* */
}

table > tbody > tr:last-child > td:last-child {
/* */
}

La compatibilité est celle de :last-child soit IE9+ de mémoire (de toute façon IE8 ne reconnait pas border-radius)
Qu'un tableau n'ait pas de coins arrondis sur IE8 et moins n'est pas bien grave. C'est de la cosmétique a priori.


(*) parce que pour imprimer une table qui fait 50 pages de haut en répétant entête et pied de table sur chaque page, ça reste possible d'imprimer la 1ère page sans même avoir reçu le contenu des 49 autres pages.
Modifié par Felipe (19 Jan 2012 - 12:24)
Un grand merci pour ta réponse.

En fait je n'utilise pas <tfoot> car je calcule généralement mes totalisations en même temps que la création de mon tableau. Devoir le placer avant oblige à mémoriser les données où à faire deux fois le traitement.

Enfin ce n'est pas grave, l'idée des first et last child est très intéressante et si je comprends bien pourrait être appliquée même s'il n'y a pas de <thead> et de <tbody>.

Ça pourrait résoudre mon problème, malheureusement ça ne fonctionne pas quand je l'applique à mon exemple.
Sous Firefox, il ne se passe rien, et Chrome applique l'arrondi au fond mais pas à la bordure.

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style type="text/css">
table { border-collapse: collapse;  }
th { border:1px solid #9ec3dd; }
td { border:1px solid #9ec3dd; }
thead { background:#e2edf5; }
tfoot { background:#eeeeee; }
table > thead > tr:first-child > th:first-child { border-radius: 10px 0px 0px 0px; }
table > thead > tr:first-child > th:last-child  { border-radius: 0px 10px 0px 0px; }
table > tfoot > tr:last-child  > th:first-child { border-radius: 0px 0px 0px 10px; }
table > tfoot > tr:last-child  > th:last-child  { border-radius: 0px 0px 10px 0px; }
}
</style> 
</head>
<body>
	<table>
	  <thead>
	    <tr><th>Zone T1</th><th>Zone T2</th><th>Zone T3</th></tr>
	    <tr><th>Zone T1</th><th>Zone T2</th><th>Zone T3</th></tr>
	  </thead>
	  <tfoot>
	    <tr><th>Zone P1</th><th>Zone P2</th><th>Zone P3</th></tr>
	    <tr><th>Zone P1</th><th>Zone P2</th><th>Zone P3</th></tr>
	  </tfoot>
	  <tbody>
	    <tr><td>Zone C1</td><td>Zone C2</td><td>Zone C3</td></tr>
	    <tr><td>Zone C1</td><td>Zone C2</td><td>Zone C3</td></tr>
	  </tbody>
	</table>
</body>
</html>


Me suis-je trompé quelque part ?
Bon, après avoir fait le tour de la question, essayé tout et son contraire, la conclusion s'impose : le border-radius ne peut pas s'appliquer à une table, ni à son contenu.

IE8 ne fait rien, mais là c'est plutôt normal.
Firefox n'arrondit ni la bordure, ni le background.
Chrome arrondit le background, mais pas la bordure.

Il est quand même dommage de ne pas avoir implémenté cette fonctionnalité sur les tableaux.


Pour ceux que ça intéresse, je suis quand même arrivé au résultat escompté par un moyen détourné : J'ai placé la table dans une DIV, avec le border-radius. Et ensuite j'ai supprimé la bordure externe de la table. C'est un peu tordu mais ça marche.

le CSS final (simplifié) se résume à ça :

div { border:1px solid #9ec3dd; border-radius: 10px; }
table { border-collapse: collapse; width:100%;}
td { border:1px solid #9ec3dd; }
table td:first-child { border-left:0px; }
table td:last-child { border-right:0px; }
table tr:first-child td { border-top:0px; }
table tr:last-child td { border-bottom:0px; }


(Pour utiliser last-child avec IE8, il faut utiliser une bib javascript)

Attention, pour que cela marche avec Firefox, les background doivent être placés sur la DIV, et non dans les cellules. Si vous voulez un entête ou une totalisation avec un fond différent, il peut être nécessaire de séparer les entêtes, corps et pied de votre tableau dans trois DIV et trois tables différentes.

Si quelqu'un a plus simple, je suis preneur...
Modifié par mutsum1 (19 Jan 2012 - 17:00)
mutsum1 a écrit :
Bon, après avoir fait le tour de la question, essayé tout et son contraire, la conclusion s'impose : le border-radius ne peut pas s'appliquer à une table, ni à son contenu.

IE8 ne fait rien, mais là c'est plutôt normal.
Firefox n'arrondit ni la bordure, ni le background.
Chrome arrondit le background, mais pas la bordure.
...
Pour ceux que ça intéresse, je suis quand même arrivé au résultat escompté par un moyen détourné : J'ai placé la table dans une DIV, avec le border-radius. Et ensuite j'ai supprimé la bordure externe de la table. C'est un peu tordu mais ça marche.
...
Attention, pour que cela marche avec Firefox, les background doivent être placés sur la DIV, et non dans les cellules. Si vous voulez un entête ou une totalisation avec un fond différent, il peut être nécessaire de séparer les entêtes, corps et pied de votre tableau dans trois DIV et trois tables différentes.

Si quelqu'un a plus simple, je suis preneur...

Je n'ai jamais essayé sur des tableaux mais j'ai effectivement remarqué des problèmes de rendu sous Firefox (ou autre) pour des implémentations avec border-radius et/ou image en background et/ou box-shadow : dans ces cas là j'applique un overflow:hidden à ma div et cela règle mon problème.
Merci à tous les deux.

Effectivement, c'est bien le border collapse qui annule le radius.
Et c'est dommage car cette spécificité facilite bien les choses.

Je crois que je vais continuer avec ma DIV, le border separate me parait un peu trop compliqué à gérer pour obtenir un résultat classique.


Ok pour le "overflow:hidden", ça corrige bien le défaut d'affichage sous Firefox.
Je vais pouvoir replacer mes background dans le tableau.

Encore merci
bonjour...

Un petit complément d'info...

css3 et ses display type table table-row table-cell offre une construction de table mais en div... bon ok c'est pas compatible avec tout les browser... mais ça s'envisage suivant l'utilisation finale...
De retour,

Le fait de supprimer la bordure externe pour placer le radius dans la DIV était une bonne idée, mais elle se heurte à un problème de taille sur les tableaux complexes.

Les attributs first et last-child (déclarés dans le CSS) sont appliqués de façon logique, et non physique.
Je m'explique : Ces attributs sont déclarés sur les première et dernière cellules d'une ligne ou d'une colonne, mais ces cellules, du fait de rowspan ou de colspan éventuels, ne sont pas forcément les cellules physiquement en bordure de tableau.

Le code CSS suivant :
table td:first-child { border-left:0px; }
table td:last-child { border-right:0px; }
table tr:first-child td { border-top:0px; }
table tr:last-child td { border-bottom:0px; }

ne supprime donc pas forcément la bordure externe.

Me voilà donc revenu à mon point de départ... Smiley decu

Si vous avez une idée...
YES, j'ai fini par trouver...

Alors pour ceux que ça intéresse, il est inutile de supprimer la bordure externe de la table. De toute façon ça ne marche pas. Le truc c'est de déplacer la table dans la div pour que leurs bordures se superposent.

J'ai donc appliqué un margin de -1px à la table. De cette façon celle-ci se cadre bien par rapport à la DIV en haut, à gauche, et en bas.
Reste le coté droit, qui lui dépend de la largeur de la table (le margin right n'a aucune incidence). Une largeur de 100% reproduit les 2 pixels d'écarts entre la DIV et la table. Il faut donc agrandir la table. Après quelques essais, j'ai appliqué une valeur de 100.3%, qui semble marcher dans tous les cas, même sur des DIV extra-larges.

Au final, mon css se résume à ça :
div { border:1px solid #9ec3dd; border-radius: 10px; overflow:hidden; }
table { border-collapse: collapse; width:100.3%; margin:-1px; }
td { border:1px solid #9ec3dd; }


C'est simple finalement, une fois que l'on a essayé tout le reste...
Bonjour,

sinon petite astuce pour que ça marche dans Firefox(a re-verifier pour les autres),
si tu veut appliquer un :
border-collapse:collapse;

il faut en passer par :
border-collapse:separate;
border-spacing:0px ;

et la , le border-radius est a nouveau applicable sur table.

cordialement,
GC


edit:
exemple css avec :first et last-child pour ton tableau en test plus haut :
table {border-collapse:separate;
border-spacing:0px ;
border-radius:1.2em;
box-shadow:0 0 5px black;padding:5px;
}
table td , table th {border:solid 1px white ;box-shadow:0 0 0 1px black, 0 0 3px black;background:#BDFF73;}

table thead :first-child  :first-child {border-radius:1em 0 0;}
table thead :first-child  :last-child  {border-radius:0 1em 0 0;}
table tfoot :last-child  :first-child  {border-radius:0 0 0 1em ;}
table tfoot :last-child  :last-child   {border-radius:0 0 1em ;}
/* etc .... */
tfoot :last-child th , thead :first-child th {background:turquoise;}
table tr th, table tr td  {padding:5px;text-shadow:1px 1px 1px white;}

Modifié par gc-nomade (24 Jan 2012 - 18:35)