Comment mettre l'espacement entre les éléments TBODY

95

J'ai une table comme celle-ci:

<table>
    <tfoot>
        <tr><td>footer</td></tr>
    </tfoot>
    <tbody>
        <tr><td>Body 1</td></tr>
        <tr><td>Body 1</td></tr>
        <tr><td>Body 1</td></tr>
    </tbody>
    <tbody>
        <tr><td>Body 2</td></tr>
        <tr><td>Body 2</td></tr>
        <tr><td>Body 2</td></tr>
    </tbody>
    <tbody>
        <tr><td>Body 3</td></tr>
        <tr><td>Body 3</td></tr>
        <tr><td>Body 3</td></tr>
    </tbody>
</table>

Je voudrais mettre un espacement entre chaque élément tbody, mais le remplissage et la marge n'ont aucun effet. Des idées?

nickf
la source
Est-il juste de répéter les balises «tbody»? Ce que j'ai toujours vu, c'est que tous les "<tr> .. </tr>" sont dans une seule balise "tbody '.
Saneef
23
Oui, c'est valable. La spécification dit: <! ELEMENT TABLE - - (CAPTION ?, (COL * | COLGROUP *), THEAD ?, TFOOT ?, TBODY +)> ce qui signifie qu'il doit y avoir un ou plusieurs tbodies. w3.org/TR/html4/struct/tables.html#h-11.2.1
nickf

Réponses:

56

Essayez ceci, si cela ne vous dérange pas de ne pas avoir de frontières.

<style>
table {
  border-collapse: collapse;
}

table tbody {
  border-top: 15px solid white;
}
</style>

<table>
    <tfoot>
        <tr><td>footer</td></tr>
    </tfoot>
    <tbody>
        <tr><td>Body 1</td></tr>
        <tr><td>Body 1</td></tr>
        <tr><td>Body 1</td></tr>
    </tbody>
    <tbody>
        <tr><td>Body 2</td></tr>
        <tr><td>Body 2</td></tr>
        <tr><td>Body 2</td></tr>
    </tbody>
    <tbody>
        <tr><td>Body 3</td></tr>
        <tr><td>Body 3</td></tr>
        <tr><td>Body 3</td></tr>
    </tbody>
</table>
Dave Jensen
la source
7
Essayez border-top: 15px solide transparent;
Steve Almond
3
Je voulais souligner cela. Utilisez transparentcomme couleur de bordure. Ce que @SteveAlmond a dit.
iheartcsharp
si le tableau / tbody / tr / td a une couleur d'arrière-plan, définir la couleur de la bordure sur transparentlui donnera la couleur d'arrière-plan de l'élément, essentiellement indiscernable du corps de l'élément. Vous auriez besoin de colorer explicitement la bordure de la couleur dans laquelle vous voulez qu'elle apparaisse (pour la rendre soi-disant invisible)
Guy Passy
81

Quelque chose comme ça fonctionnera, en fonction des exigences de prise en charge de votre navigateur:

tbody::before
{
  content: '';
  display: block;
  height: 15px;

}
MacNimble
la source
1
C'est la seule solution qui fonctionne lorsque vos cellules ont un arrière-plan que l'espace ne devrait pas avoir.
Laradda
Cela a bien fonctionné pour moi. Y a-t-il des inconvénients? Aussi, pourquoi deux deux points?
nh2
Excellente solution. Garde tout accessible!
Jason T Featheringham
1
@ nh2: les doubles-virgules sont pour le pseudo-contenu et les simples deux points pour les pseudo-sélecteurs. C'est une mise à jour de la syntaxe CSS. Tout utilisé pour utiliser simplement les deux points. Les navigateurs plus anciens ne prennent pas en charge les doubles deux points (comme, IE <= 8).
dbmikus
3
N'est-ce pas plus sûr à utiliser display: table-row;?
rachel
20

Les gens auront toujours des opinions controversées sur l'utilisation d'éléments de tableau vides pour mettre en page une page (comme en témoigne le vote négatif de cette réponse). Je reconnais cela, mais il est parfois plus facile de les utiliser de cette façon lorsque vous travaillez de manière " rapide et sale ".

J'ai utilisé des lignes vides dans des projets précédents pour espacer des groupes de lignes de tableau. J'ai attribué aux lignes d'espacement une classe css propre et défini une hauteur pour cette classe qui agissait comme une marge supérieure et inférieure pour ce groupe de lignes de tableau.

    .separator{
             height: 50px;
    }

   <table>
           <tr><td>Cell 1</td><td>Cell 2</td></tr>
           <tr><td>Cell 1</td><td>Cell 2</td></tr>
           <tr><td>Cell 1</td><td>Cell 2</td></tr>

           <tr class="separator" colspan="2"></tr>

           <tr><td>Cell 1</td><td>Cell 2</td></tr>
           <tr><td>Cell 1</td><td>Cell 2</td></tr>
           <tr><td>Cell 1</td><td>Cell 2</td></tr>

           <tr class="separator" colspan="2"></tr>

           tr><td>Cell 1</td><td>Cell 2</td></tr>
           <tr><td>Cell 1</td><td>Cell 2</td></tr>
           <tr><td>Cell 1</td><td>Cell 2</td></tr>
   </table>

Si vous n'avez pas de bordures sur les cellules de votre tableau, vous pouvez également définir une hauteur par rapport à votre cellule ou ligne typique dans votre feuille de style qui espère uniformément toutes les lignes de votre tableau.

tr{
   height: 40px;
}
kevtrout
la source
Eh bien, si vous allez ajouter du balisage supplémentaire, pourquoi ne pas simplement mettre une classe sur la première ligne de chaque corps?
nickf
Eh bien, cela pourrait être dû au fait que les lignes sont du code généré et que l'ajout d'une ligne distincte dans le balisage peut être plus facile à gérer que de créer un cas particulier pour la première ligne de contenu généré.
Rolf Rander
12
Votez contre tout ce que vous voulez, mais c'est la seule solution sans inconvénients - et même si cela viole la séparation, une ligne vide n'est pas si grave à l'OMI.
Xkeeper
11
Sans inconvénients, mes fesses! Essayez d'utiliser un lecteur d'écran à ce sujet et notez le nombre de lignes incorrect. Mieux encore, essayez de copier et coller le tableau dans une feuille de calcul. Vous reformaterez pendant des heures si vous avez beaucoup de contenu. Les tableaux sont destinés à afficher des données (et à être extrêmement accessibles), et non à caler la présentation entre les sections.
Jason T Featheringham
Ce n'est que visuel. Gardez à l'esprit que le HTML sont également des documents qui peuvent être traités, par conséquent, le contenu qu'ils contiennent doit être bien formaté. Comme mentionné ci-dessus, le copier-coller de la table ou l'utilisation du lecteur d'écran échouera. Une telle conception ne doit pas être encouragée. :: La solution de contenu est meilleure car elle ne gâche pas le balisage.
pawel-kuznik
12

J'avais eu du mal à espacer correctement plusieurs <tbody>avec ::beforepseudo, en présence de <tr>contenir <td>avec rowspan dans quelques navigateurs.

En gros, si vous avez une <tbody>structure comme celle-ci:

<tbody>
    <tr>
        <td>td 1</td>
        <td rowspan"2">td 2</td>
        <td>td 3</td>
        <td>td 4</td>
    </tr>
    <tr>
        <td>td 1</td>
        <td>td 2</td>
        <td>td 4</td>
    </tr>
</tbody>

Et vous suivez qui conseille d'écrire des css sur un ::beforepseudo élément comme celui-ci:

tbody::before
{
    content: '';
    display: block;
    height: 10px;
}

Cela affectera l'envergure de lignes, rendant la table "perdant" dans la seconde <tr>le nombre de <td>-rowspan présents dans la première.

Donc, si quelqu'un rencontre ce type de problème, la solution est de styliser ::beforepseudo de cette manière:

tbody::before
{
    content: '';
    display: table-row;
    height: 10px;
}

Voici un violon

Nineoclick
la source
6

Voici une autre possibilité qui repose sur: first-child qui n'est pas disponible dans tous les navigateurs:

<style>
table {
  border-collapse: collapse;
}

td {
  border: 1px solid black;
}

tbody tr:first-child td {
  padding-top: 15px;
}

</style>

<table>
    <tfoot>
        <tr><td>footer</td></tr>
    </tfoot>
    <tbody>
        <tr><td>Body 1</td></tr>
        <tr><td>Body 1</td></tr>
        <tr><td>Body 1</td></tr>
    </tbody>
    <tbody>
        <tr><td>Body 2</td></tr>
        <tr><td>Body 2</td></tr>
        <tr><td>Body 2</td></tr>
    </tbody>
    <tbody>
        <tr><td>Body 3</td></tr>
        <tr><td>Body 3</td></tr>
        <tr><td>Body 3</td></tr>
    </tbody>
</table>
Dave Jensen
la source
3
Celui-ci ne fonctionnera pas très bien si vous avez quelque chose qui dépend de la position du contenu par rapport à la taille de la cellule, comme une ombre de boîte, des images d'arrière-plan ou à peu près n'importe quoi d'autre.
Xkeeper
1
Juste pour clarifier pour que les autres trouvent cette réponse sur Google, je suppose que comme cela a été écrit en 2008, cette réponse maintenant (2015) a un support complet sur tous les principaux navigateurs? Au moins vérifier sur caniuse.com premier enfant semble bien pris en charge?
redfox05
6

Il suffit de définir displaycomme blocket cela fonctionnera.

table tbody{
    display:block;
    margin-bottom:10px;
    border-radius: 5px;
}
utilisateur007
la source
1
cette réponse devrait être la réponse acceptée car c'est la seule qui permette d'utiliser un corps bordé avec des colonnes "sans bordure".
robsonrosa
13
display:blockrompt l'alignement des colonnes entre les éléments du corps. Vous ne bénéficiez plus du moteur de mise en page des tableaux
M Conrad
4

De toutes les réponses données ci-dessus, seules les réponses de djenson47 retiennent séparation de la présentation et du contenu . L'inconvénient de la méthode du modèle de bordure réduite est que vous ne pouvez plus utiliser les attributs de bordure ou d' espacement des cellules du tableau pour séparer les cellules individuelles. Vous pourriez dire que c'est une bonne chose et qu'il existe des solutions de contournement, mais cela peut être pénible. Je pense donc que la méthode du premier enfant est la plus élégante.

Vous pouvez également définir votre classe TBODY ' propriété de débordement de sur autre chose que «visible». Cette méthode vous permet également de conserver un modèle de bordures séparées:

<style>
tbody {
    overflow: auto;
    border-top: 1px solid transparent;
}
</style>
<table>
    <tfoot>
        <tr><td>footer</td></tr>
    </tfoot>
    <tbody>
        <tr><td>Body 1</td></tr>
        <tr><td>Body 1</td></tr>
        <tr><td>Body 1</td></tr>
    </tbody>
    <tbody>
        <tr><td>Body 2</td></tr>
        <tr><td>Body 2</td></tr>
        <tr><td>Body 2</td></tr>
    </tbody>
    <tbody>
        <tr><td>Body 3</td></tr>
        <tr><td>Body 3</td></tr>
        <tr><td>Body 3</td></tr>
    </tbody>
</table>
Calvin
la source
Je cherchais à faire quelque chose de similaire, c'est parfait pour moi
Eruant
4

Comme le remplissage peut être appliqué aux TD, vous pouvez faire une astuce avec le signe +. Ensuite, il sera possible de donner un rembourrage supérieur aux TD du premier TR d'un corps:

// The first row will have a top padding
table tbody + tbody tr td {
    padding-top: 20px;
}

// The rest of the rows should not have a padding
table tbody + tbody tr + tr td {
    padding-top: 0px;
}

J'ai ajouté le "tbody + tbody" pour que le premier tbody n'ait pas de rembourrage supérieur. Cependant, ce n'est pas obligatoire.

Autant que je sache, il n'y a pas d'inconvénients :), mais n'a pas testé les anciens navigateurs.

Maarten
la source
2

Vous pouvez utiliser border-spacingdans une table avec des groupes de lignes de table pour ajouter un espace entre ces groupes. Cependant, je ne pense pas qu'il existe un moyen de spécifier quels groupes sont espacés et lesquels ne le sont pas.

<table>
  <thead>
    ...
  </head>
  <tbody>
    ...
  </tbody>
  <tbody>
    ...
  </tbody>
  <tfoot>
    ...
  </tfoot>
</table>

CSS

table {
  border-spacing: 0px 10px; /* h-spacing v-spacing */
}
OdraEncoded
la source
0

NOUVELLE RÉPONSE

Vous pouvez utiliser autant de <tbody>balises que vous le souhaitez. Je n'avais pas réalisé que c'était correct pour le W3C jusqu'à présent. Pour ne pas dire que ma solution ci-dessous ne fonctionne pas (c'est le cas), mais pour faire ce que vous essayez de faire, attribuez vos <tbody>classes de balises, puis référencez leurs <td>balises individuelles via CSS comme ceci:

table tbody.yourClass td {
    padding: 10px;
}

et votre HTML ainsi:

<table> 
<tbody>
<tr><td>Text</td></tr>
<tr><td>Text</td></tr>
<tr><td>Text</td></tr>
</tbody>
<tbody class="yourClass">    
<tr><td>Text</td></tr>
<tr><td>Text</td></tr>
<tr><td>Text</td></tr>
</tbody>
<tbody>
<tr><td>Text</td></tr>
<tr><td>Text</td></tr>
<tr><td>Text</td></tr>
</tbody>
</table>

Essayez ce gars :)

ANCIENNE RÉPONSE

quoi que vous fassiez, N'insérez PAS de lignes vides ...

vous ne devriez pas avoir plus d'un élément tbody dans votre table. ce que vous pouvez faire est de définir l'attribut class ou id dans vos <tr>éléments et de donner le <td>remplissage de leurs balises correspondantes :

table {
    border-collapse: collapse;
}

tr.yourClass td {
    padding: 10px;
}

Vous pouvez même attribuer <tr>une classe supplémentaire aux haut et bas de sorte qu'ils ne remplissent respectivement que le haut ou le bas:

tr.yourClass.topClass td {
    padding: 10px 0 0 0;
}

tr.yourClass.bottomClass td {
    padding: 0 0 10px 0;
}

et dans votre HTML, votre <tr>balise ressemblerait à ceci:

<table> 
<tbody>
<tr><td>Text</td></tr>
<tr><td>Text</td></tr>
<tr><td>Text</td></tr>
<tr class="yourClass topClass"><td>Text</td></tr>
<tr class="yourClass"><td>Text</td></tr>
<tr class="yourClass bottomClass"><td>Text</td></tr>
<tr><td>Text</td></tr>
<tr><td>Text</td></tr>
<tr><td>Text</td></tr>
</tbody>
</table>

J'espère que cela t'aides!

Jason
la source
0

La réponse djensen47 fonctionne très bien pour les navigateurs plus récents, cependant, comme cela a été souligné, IE7 ne fonctionne pas.

Ma solution de contournement pour ce problème pour prendre en charge les navigateurs plus anciens consistait à envelopper le contenu de chaque cellule dans un div. Ensuite, ajoutez une marge supérieure au div.

<table class="tbl">
<tr></tr>
<tr></tr>
<tr></tr>
<tr><td><div></div></td></tr>
</table>

CSS

.tbl tr td div {
    height:30px;
    margin-top:20px;
}

Le paramètre de hauteur maintient les cellules d'au moins 30 pixels de haut pour empêcher toute coloration de cellule utilisée à l'intérieur du div de s'effondrer autour du texte. Le bord supérieur crée l'espace souhaité en augmentant la hauteur de la rangée entière.

Jereme Guenther
la source
0

Je suis tombé sur cela en essayant de le résoudre moi-même. J'ai réussi à mettre une <br>balise juste avant la </tbody>balise de fermeture . C'est une solution purement visuelle, mais semble fonctionner sur la plupart des navigateurs que j'ai testés.

<table>
    <tbody>
        <tr>
            <td></td>
        </tr>
        <br>
    </tbody>
    <tbody>
        <tr>
            <td></td>
        </tr>
    </tbody>
</table>

Devrait également être accessible.

Ian
la source