How to put spacing between TBODY elements

I have a table like this:

<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>

I'd like to put some spacing between each tbody element, but padding and margin have no effect. Any ideas?


Solution 1:

Something like this will work, depending on your browser support requirements:

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

}

Solution 2:

Try this, if you don't mind not having borders.

<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>

Solution 3:

People will always have controversial opinions about using empty table elements to layout a page (as evidenced by this answer's downvote). I recognize this, but sometimes its easier to use them this way when you are working in a "quick and dirty" way.

I've used empty rows in past projects to space groups of table rows. I assigned the spacer rows a css class of their own and defined a height for that class that acted as a top and bottom margin for that group of table rows.

    .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>

If you don't have borders on your table cells, you could also define a height to your typical cell or row in your style sheet that evenly spaces out all rows of your table.

tr{
   height: 40px;
}

Solution 4:

I had been in trouble spacing properly multiple <tbody> with ::before pseudo, in presence of <tr> containing <td> with rowspan in a couple of browsers.

Basically, if you have a <tbody> structured like this:

<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>

And you follow who advises to write css on ::before pseudo element like this:

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

This will affect the rowspan, making table "losing" within the second <tr> how many <td>-rowspan are present in the first one.

So, if anyone encounters that type of problem, the solution is to style ::before pseudo in this way:

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

Here's a fiddle

Solution 5:

Here's another possibility that relies on :first-child which is not available in all browsers:

<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>