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

12,431

Solution 1

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/

Solution 2

I think this is the way to do it. I'm not sure if this is what you're trying to explain.

<!DOCTYPE html>
<html>
    <head>
        <style>
            table, th, td {
                border: 1px solid black;
                border-collapse: collapse;
            }
            th, td {
                padding: 5px;
                text-align: left;
            }
        </style>
    </head>
    <body>
        <table>
            <tr>
                <th rowspan="2">Col1</th>
                <th rowspan="2">Col2</th>
                <th colspan="3">Col6</th>
                <th rowspan="2">Col7</th>
            </tr>
            <tr>
                <th>Col 3</th>
                <th>Col 4</th>
                <th>Col 5</th>
            </tr>
            <tr>
                <td colspan="6"></td>
            </tr>
            <tr>
                <td>Row 1</td>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
            </tr>
            <tr>
                <td colspan="6"></td>
            </tr>
            <tr>
                <td>Row 2</td>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
            </tr>
        </table>
    </body>
</html>
Share:
12,431
Eugene
Author by

Eugene

Updated on June 04, 2022

Comments

  • Eugene
    Eugene almost 2 years
    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

  • santiago arizti
    santiago arizti over 7 years
    there are some variations on this method, for example, if you don't need the margin below the TRs, you can get rid of the divs and style the tds instead. If you need all divs to be the same height even with different amounts of content you need some additional absolute position trickery. Also, keep in mind that you can also use a framework like Foundation or Bootstrap that has a column system and you can get rid of the table limitations altogether.
  • Eugene
    Eugene over 7 years
    Please read 2-nd point. I use Bootstrap-table for sorting and filtering. It also sort empty rows (i dont't know how to change such behavoiour). It's breaks table layout.
  • Eugene
    Eugene over 7 years
    @santiago-aritzi Looks like it's the best way in my case. But cells has big difference in content size. Div's has different sizes and it's break row structure.
  • santiago arizti
    santiago arizti over 7 years
    you can use that small script that I pasted in the answer. it doesn't need jquery but if you want you can use jquery and it would be more succinct. also, the padding is hardcoded in there, you might want to either query the padding on the fly too, or remove that padding altogether from the css