How to add space between table rows with border without using border-spacing and empty rows

Eugene picture Eugene · Nov 15, 2016 · Viewed 10.9k times · Source
  1. I tried to use border-spacing attribute. But my table has header with multiple rows which are also affected by it. I need spaces only between rows in table body.
  2. I tried to use empty rows with some height. But i also use bootstrap-table for sorting and filtering. It sorts and filters empty rows too, and i didn't find clear way to fix it, so table layout breaks after sorting or filtering.
  3. Also table rows should have border.

What is the best way to create spaces between table rows with such limitations ? Table structure

<table>
<thead>
 <tr>
  <th>col1</th>
  <th>col2</th>
  <th colspan='2'>col3</th>
 </tr>
 <tr>
  <th colspan='2'></th>
  <th>col31</th>
  <th>col32</th>
 </tr>
</thead>
<tbody>
 <tr>
  <td>Abc11</td><td>Abc12</td><td>Abc13</td><td>Abc14</td>
 </tr>
 <tr><td>Abc21</td><td>Abc22</td><td>Abc23</td><td>Abc24</td>
 </tr>
</tbody>
</table>

Rough scheme of the table

Answer

santiago arizti picture santiago arizti · Nov 15, 2016

Normally <tr> should have no styling, specially if it is not to be inherited by <td>s, borders and margins are an example of what <tr>s should not have.

The easiest approach to your problem is to add <div>s inside the <td>s and style them instead, you can use something like this:

HTML:

<table>
    <tr>
        <td>
            <div>santiago</div>
        </td><td>
            <div>santiago</div>
        </td><td>
            <div>santiago</div>
        </td>
    </tr><tr>
        <td>
            <div>santiago</div>
        </td><td>
            <div>santiago</div>
        </td><td>
            <div>santiago</div>
        </td>
    </tr>
</table>

CSS:

table {
    /* to eliminate the default spacing between TDs*/
    border-collapse: collapse; 
}
td {
    /* let the divs do the spacing */
    padding: 0;
}
td div {
    border-style: solid;
    border-color: black;
    border-width: 1px 0;
    /* now, here you can add the margin */
    margin-bottom: 10px;
    /* just some nice padding, you don't really need this */
    padding: 10px;
}
td:first-child div {
    /* just side borders on first and last elements */
    border-left-width: 1px;
}
td:last-child div {
    /* just side borders on first and last elements */
    border-right-width: 1px;
}

Fiddle: https://jsfiddle.net/dow267ec/

Update: if content is of different heights and you cannot add a fixed height to all the divs, you can add this simple js next to your table and you should be fine. Again, I still recommend the columns (see zurb foundation) approach, but sometimes you have to make those tables work.

document.querySelectorAll("table tr").forEach(function(tr){
    var max = 0, divs = tr.querySelectorAll("td > div");
    divs.forEach(function(div){ max = Math.max(div.offsetHeight, max); });
    // 10 is the padding that we had.
    divs.forEach(function(div){ div.style.height = (max - (2 * 10)) + "px"; });
});

Here is the updated fiddle with this js enabled. You can add an id to the table to avoid hitting other tables.

Updated fiddle : https://jsfiddle.net/dow267ec/2/