[css] How to add a margin to a table row <tr>

I have a table containing many rows. Some of these rows are class="highlight" and signify a row that needs to be styled differently and highlighted. What I'm trying to do is add some extra spacing before and after these rows so they appear slightly separated from the other rows.

I thought I could get this done with margin-top:10px;margin-bottom:10px; but it's not working. Anyone knows how to get this done, or if it could be done? Here's the HTML and I've set the 2nd tr in the tbody to class highlight.

<table>
<thead>
  <tr>
     <th>Header 1</th>
     <th>Header 2</th>
  </tr>
</thead>
<tbody>
  <tr>
     <td>Value1</td>
     <td>Value2</td>
  </tr>
  <tr class="highlight">
     <td>Value1</td>
     <td>Value2</td>
  </tr>
  <tr>
     <td>Value1</td>
     <td>Value2</td>
  </tr>
  <tr>
     <td>Value1</td>
     <td>Value2</td>
  </tr>
</tbody>
</table>

This question is related to css

The answer is


Because margin is ignored on tr, I usually use a workaround, by setting a transparent border-bottom or border-top and setting the background-clip property to padding-box so the background-color does not get painted underneath the border.

table {
   border-collapse: collapse; /* [1] */
}

th, td {
  border-bottom: 5px solid transparent; /* [2] */
  background-color: gold; /* [3] */
  background-clip: padding-box; /* [4] */
}
  1. Makes sure cells share a common border, but is completely optional. The solution works without it.
  2. The 5px value represents the margin that you want to achieve
  3. Sets the background-color of your row/cell
  4. Makes sure the background get not painted underneath the border

see a demo here: http://codepen.io/meodai/pen/MJMVNR?editors=1100

background-clip is supported in all modern browser. (And IE9+)

Alternatively you could use a border-spacing. But this will not work with border-collapse set to collapse.


A hack to give the appearance of margins between table rows is to give them a border the same color as the background. This is useful when styling a 3rd party theme where you can't change the html markup. Eg:

tr{ 
    border: 5px solid white;
}

You can create space between table rows by adding an empty row of cells like this...

<tr><td></td><td></td></tr>

CSS can then be used to target the empty cells like this…

table :empty{border:none; height:10px;}

NB: This technique is only good if none of your normal cells will be empty/vacant.

Even a non-breaking space will do to avoid a cell from being targetted by the CSS rule above.

Needless to mention that you can adjust the space's height to whatever you like with the height property included.


Here's a neat way I did it:

table tr {
    border-bottom: 4px solid;
}

That will add 4px of vertical spacing between each row. And if you wanted to not get that border on the last child:

table tr:last-child {
    border-bottom: 0;
}

Reminder that CSS3 pseudo-selectors will only work in IE 8 and below with selectivizr.


add this style before the class="highlighted" padding-bottom and display is inline-table


line-height can be the possible solution

tr
{
    line-height:30px;
}

I know this is kind of old, but I just got something along the same lines to work. Couldn't you do this?

tr.highlight {
    border-top: 10px solid;
    border-bottom: 10px solid;
    border-color: transparent;
}

Hope this helps.


I gave up and inserted a simple jQuery code as below. This will add a tr after every tr, if you have so many trs like me. Demo: https://jsfiddle.net/acf9sph6/

<table>
  <tbody>
     <tr class="my-tr">
        <td>one line</td>
     </tr>
     <tr class="my-tr">
        <td>one line</td>
     </tr>
     <tr class="my-tr">
        <td>one line</td>
     </tr>
  </tbody>
</table>
<script>
$(function () {
       $("tr.my-tr").after('<tr class="tr-spacer"/>');
});
</script>
<style>
.tr-spacer
{
    height: 20px;
}
</style>

This isn't going to be exactly perfect though I was happy to discover that you can control the horizontal and vertical border-spacing separately:

table
{
 border-collapse: separate;
 border-spacing: 0 8px;
}

The border-spacing property will work for this particular case.

table {
  border-collapse:separate; 
  border-spacing: 0 1em;
}

Reference.


Another possibility is to use a pseudo selector :after or :before

tr.highlight td:last-child:after
{
  content: "\0a0";
  line-height: 3em;
}

That might avoid issues with browser that don't understand the pseudo selectors, plus background-colors are not an issue.

The downside is however, that it adds some extra whitespace after the last cell.


A way to mimic the margin on the row would be to use the pseudo selector to add some spacing on the td.

.highlight td::before, .highlight td::after
{
  content:"";
  height:10px;
  display:block;
}

This way anything marked with the highlight class will be separated top and bottom.

https://jsfiddle.net/d0zmsrfs/


You might try to use CSS transforms for indenting a whole tr:

tr.indent {
   -webkit-transform: translate(20px,0);
   -moz-transform: translate(20px,0);
}

I think this is a valid solution. Seems to work fine in Firefox 16, Chrome 23 and Safari 6 on my OSX.


First of all, don't try to put a margin to a <tr> or a <td> because it won't work in modern rendering.

  • Solution 1

Although margin doesn't work, padding does work :

td{
    padding-bottom: 10px;
    padding-top: 10px;
}

Warning : This will also push the border further away from the element, if your border is visible, you might want to use solution 2 instead.

  • Solution 2

To keep the border close to the element and mimic the margin, put another <tr> between each of your reel table's <tr> like so :

<tr style="height: 20px;"> <!-- Mimic the margin -->
</tr>

For what is worth, I took advantage that I was already using bootstrap (4.3), because I needed to add margin, box-shadow and border-radius to my row, something I can't do with tables.

<div id="loop" class="table-responsive px-4">
<section>
    <div id="thead" class="row m-0">
        <div class="col"></div>
        <div class="col"></div>
        <div class="col"></div>
    </div>
    <div id="tbody" class="row m-0">
        <div class="col"></div>
        <div class="col"></div>
        <div class="col"></div>
    </div>
</section>
</div>

On css I added a few lines to mantain the table behavior of bootstrap

@media (max-width: 800px){
    #loop{
        section{
            min-width: 700px;
        }
    }
}

add a div to the cells that you would like to add some extra spacing:

<tr class="highlight">
 <td><div>Value1</div></td>
 <td><div>Value2</div></td>
</tr>
tr.highlight td div {
margin-top: 10px;
}

You can't style the <tr>s themselves, but you can give the <td>s inside the "highlight" <tr>s a style, like this

tr.highlight td {padding-top: 10px; padding-bottom:10px}