131

Meaning making the resultant table look less like this:

[===ROW===]
[===ROW===]
[===ROW===]
[===ROW===]

... and more like this:

[===ROW===]

[===ROW===]

[===ROW===]

[===ROW===]

I tried adding

margin-bottom:1em;

to both td and tr but got nothing. Any ideas?

Josh Darnell
  • 11,304
  • 9
  • 38
  • 66
MGOwen
  • 6,562
  • 13
  • 58
  • 67
  • 2
    Why not cellspacing and cellpadding? – KV Prajapati Aug 12 '09 at 04:21
  • 1
    Cellspacing will give spacing between columns also. – rahul Aug 12 '09 at 04:22
  • 4
    Cellspacing and cellpadding are not valid (X)HTML. You should not use them. – freiksenet Aug 12 '09 at 04:24
  • 8
    @freiksenet: You're wrong. They're perfectly valid strict HTML4 (http://www.w3.org/TR/html401/struct/tables.html#h-11.2.1), XHTML1 (http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd) and even XHTML1.1 (http://www.w3.org/MarkUp/DTD/xhtml-table-1.mod). – mercator Aug 12 '09 at 09:06
  • 1
    Possible duplicate of [Space between two rows in a table?](http://stackoverflow.com/questions/351058/space-between-two-rows-in-a-table) – ThisClark Jan 15 '17 at 22:52

12 Answers12

301

All you need:

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

That assumes you want a 1em vertical gap, and no horizontal gap. If you're doing this, you should probably also look at controlling your line-height.

Sort of weird that some of the answers people gave involve border-collapse: collapse, whose effect is the exact opposite of what the question asked for.

Rifky Niyas
  • 1,737
  • 10
  • 25
John Haugeland
  • 9,230
  • 3
  • 37
  • 40
97
table {
    border-collapse: collapse;
}

td {
    padding-top: .5em;
    padding-bottom: .5em;
}

The cells won't react to anything unless you set the border-collapse first. You can also add borders to TR elements once that's set (among other things.)

If this is for layout, I'd move to using DIVs and more up-to-date layout techniques, but if this is tabular data, knock yourself out. I still make heavy use of tables in my web applications for data.

Ryan Florence
  • 13,361
  • 9
  • 46
  • 63
  • Did you test it? It seems td's can have padding with or without collapse. Borders work with collapse, but not on IE. – Kobi Aug 12 '09 at 05:38
  • This worked. Annoying that margins don't work, but it doesn't matter in this case. Thanks. – MGOwen Aug 13 '09 at 00:46
  • 34
    This is a really bad approach. You're modifying the box of the cells to position the cells, rather than just positioning the cells, by fusing the cells together because you want them to be apart. The second the cells need backgrounds, you're screwed. The correct approach is border separate, not border collapse, using the border separation to define, you know, the border separation. – John Haugeland May 29 '13 at 17:08
  • @John Haugeland Yes, I was surprised to come back to this question after 6 years and learn this. I wonder if maybe border-separate didn't work in all major browsers in 2009 when I asked this. Are you sure it works properly now? – MGOwen Feb 10 '15 at 01:33
  • 2
    It's almost the very first piece of CSS2 that got implemented, because browsers already had table gaps implemented for the HTML version that everyone used to use for pixel-accurate layout. Yes, I'm certain. :) – John Haugeland Feb 10 '15 at 01:56
  • 2
    It's one of those weird corners of CSS that nobody but the people who've read the spec know about. (There are a surprisingly large number of them. Similarly float should basically never be used the way it's used in practice.) – John Haugeland Feb 10 '15 at 01:56
14

If none of the other answers are satisfactory, you could always just create an empty row and style it with CSS appropriately to be transparent.

Flimm
  • 136,138
  • 45
  • 251
  • 267
  • 1
    Why the downvote? The other answers are problematic: rpflo's answer requires you to use border-collapse and to expand the padding of cells, making the cells appear larger rather than create spacing between them. John Haugeland's answer doesn't allow you to selectively apply the spacing to certain rows. I could go on but this answer is one option that worked for my use-case when none of the other answers did. – Flimm Feb 21 '14 at 11:11
  • 2
    The anonymous user's downvoted approach of specifying the height of individual rows with CSS is vastly superior to adding dummy content to the table, on the chance that you need to control individual rows, which isn't what this question was about. – John Haugeland Aug 15 '14 at 18:26
  • Fake rows also confuse tools which expect table rows to be table rows (like important accessibility tools for the disabled, and common plugins for exporting/sorting/reformatting/etc). There are many reasons to use styles to control the styling, rather than shoving fake stuff in, as a general rule. Read about Semantic Markup for more info. – MGOwen Jul 16 '20 at 07:05
  • 1
    @MGOwen Could you name the accessibility tools that would fail under this scenario, and how they would fail? I'm now sceptical of accessibility advice that doesn't mention specifics, there is a lot of bad accessibility advice out there that doesn't actually help anybody (for example, document outline advice for HTML 5 [was all wrong](https://adrianroselli.com/2016/08/there-is-no-document-outline-algorithm.html), accessibility tools do not work the way people say they work). – Flimm Jul 16 '20 at 08:23
  • 2
    Came here to say that I'm working on a problem that requires a very specified layout and this is probably the most elegant solution that **I completely overlooked**. Sometimes the simplest solutions are the best. – jhmckimm Jun 26 '21 at 05:53
  • If you need variable row spacing while still keeping the table layout across all rows, this is the answer – davidraedev Aug 09 '22 at 05:14
6

Simply you can use padding-top and padding-bottom on a td element.

Unit can anything from this list:

enter image description here

Demo Code:

td
{
  padding-top: 10px;
  padding-bottom: 10px;
}
<table>
  <tr>
    <th>Firstname</th>
    <th>Lastname</th>
  </tr>
  <tr>
    <td>Peter</td>
    <td>Griffin</td>
  </tr>
  <tr>
    <td>Lois</td>
    <td>Griffin</td>
  </tr>
</table>
Cœur
  • 37,241
  • 25
  • 195
  • 267
Abrar Jahin
  • 13,970
  • 24
  • 112
  • 161
5

If you don't have borders, or have borders and want the spacing inside the cells, you can use padding, or line-height. As far as I know, margin has no effect on cells and rows.
A CSS property for spacing of cells is border-spacing, but it doesn't work on IE6/7 (so you can use it depending on your crowd).

If all else fails you can use the old cellspacing attribute in your markup - but this will also give you spacing between the columns. Some CSS reset suggest you should set it anyway to get cross-browser support:

/* tables still need cellspacing="0" in the markup */

Flimm
  • 136,138
  • 45
  • 251
  • 267
Kobi
  • 135,331
  • 41
  • 252
  • 292
3

This is the way (I was thinking it's impossible):

First give the table only vertical border-spacing (for example 5px) and set it's horizontal border-spacing to 0. Then you should give proper borders to each row cell. For example the right-most cell in each row should have border on top, bottom and right. The left-most cells should have border on top, bottom and left. And the other cells between these 2 should only have border on top and bottom. Like this example:

<table style="border-spacing:0 5px; color:black">
    <tr>
        <td style="border-bottom:thin black solid; border-top:thin black solid; border-left:thin black solid;">left-most cell</td>
        <td style="border-bottom:thin black solid; border-top:thin black solid;">other cell</td>
        <td style="border-bottom:thin black solid; border-top:thin black solid;">other cell</td>
        <td style="border-bottom:thin black solid; border-top:thin black solid;">other cell</td>
        <td style="border-bottom:thin black solid; border-top:thin black solid; border-right:thin black solid;">right-most cell</td>
    </tr>
    <tr>
        <td style="border-bottom:thin black solid; border-top:thin black solid; border-left:thin black solid;">left-most cell</td>
        <td style="border-bottom:thin black solid; border-top:thin black solid;">other cell</td>
        <td style="border-bottom:thin black solid; border-top:thin black solid;">other cell</td>
        <td style="border-bottom:thin black solid; border-top:thin black solid;">other cell</td>
        <td style="border-bottom:thin black solid; border-top:thin black solid; border-right:thin black solid;">right-most cell</td>
    </tr>
    <tr>
        <td style="border-bottom:thin black solid; border-top:thin black solid; border-left:thin black solid;">left-most cell</td>
        <td style="border-bottom:thin black solid; border-top:thin black solid;">other cell</td>
        <td style="border-bottom:thin black solid; border-top:thin black solid;">other cell</td>
        <td style="border-bottom:thin black solid; border-top:thin black solid;">other cell</td>
        <td style="border-bottom:thin black solid; border-top:thin black solid; border-right:thin black solid;">right-most cell</td>
    </tr>
</table>
Flimm
  • 136,138
  • 45
  • 251
  • 267
Arash Esmaeili
  • 179
  • 2
  • 6
1

In my opinion, the easiest way to do is adding padding to your tag.

td {
 padding: 10px 0
}

Hope this will help you! Cheer!

Huy Le
  • 339
  • 1
  • 2
  • 11
  • 3
    This creates extra space inside the table row. If the table rows have colors that will not look good. – Kokodoko Jan 13 '17 at 11:44
1

the padding in the TD works if you want the space to have the same background color as the td

in my case, requirement was for white space between header row and whatever was above it

by applying this styling to a single cell, i was able to get the desired separation. It was not necessary to add it to all cells... Arguably not the MOST elegant, but possibly more elegant than separator rows.

<td colspan="10"> 
    <div class="HeaderRow" 
         style="margin-top:10px;">
            <%# Eval("VendorName")%>
     </div>
</td>  
greg
  • 1,673
  • 1
  • 17
  • 30
-1

You could also just modify the height for each row using CSS.

<head>
 <style>
 tr {
   height:40px;
 }
</style>
</head>

<body>
<table>

<tr> <td>One</td> <td>Two</td> </tr>
<tr> <td>Three</td> <td>Four</td> </tr>
<tr> <td>Five</td> <td>Six</td> </tr>

</table>
</body>

You could also modify the height of the <td> element, it should give you the same result.

-1

Create an another <tr> just below and add some space or height to content of <td>

enter image description here

Checkout the fiddle for example

https://jsfiddle.net/jd_dev777/wx63norf/9/

Jaydeep Chauhan
  • 122
  • 2
  • 9
  • This is considered bad practice. One of the reasons is that tools (like readers for disabled users) expect table rows to be table rows, and will export/read/interpret your "fake" rows mixed in with the real ones. See the first time this same answer was given in 2014, above. – MGOwen Jul 16 '20 at 07:00
-2

If you stick with the design using tables the best idea will be to give an empty row with no content and specified height between each rows in the table.

You can use div to avoid this complexity. Just give a margin to each div.

rahul
  • 184,426
  • 49
  • 232
  • 263
  • 1
    There are still good reasons to use tables (like tabular data). You're right, empty rows is certainly a silly route :P But there is a solution, border-collapse. – Ryan Florence Aug 12 '09 at 04:32
-4

Add following rule to tr and it should work

float: left

Sample (Open it in IE9 offcourse :) ): http://jsfiddle.net/zshmN/

EDIT: This isn't a legal or correct solution as pointed out by many, but if you are left with no option and need something this will work in IE9.

So all those who are giving down votes, please let us know correct solution as well

  • 3
    This approach prevents automatic lining of columns when cells contain data with different dimensions - the table mark-up is essentially pointless. It works well enough in the examples provided, but it's not an advisable technique. Alter a cell's text to see what I mean. – verism Apr 27 '13 at 21:07
  • Hey @verism, sorry but I didn't get your point. Can you explain it bit more? Or if you can provide a fiddle where this method fails as I have been using this method extensively and would like to take care of scenarios where it fails. – Sandeep Choudhary May 05 '13 at 06:47
  • There's no clear delineation of columns; which means the tabular data loses its visual structure and becomes harder to read. http://jsfiddle.net/verism/zshmN/5/ – verism May 06 '13 at 01:31
  • @verism ya this is one issue, but we can define fix width columns. I know this is not a good solution, but I didn't found any other solution which works on IE9 – Sandeep Choudhary May 31 '13 at 05:30
  • 1
    Floating table rows isn't legal according to the CSS specification. CSS2 section 17 requires that display:table-row elements be within display:table-row-group, -header-group, or -footer-group elements. However, the floating algorithm according to section 9 injects an anonymous block parent. This means that the table row no longer has a legal parent layout, and the browser is guessing what to do. This is flat out incorrect. – John Haugeland Aug 27 '14 at 20:11
  • On top of that, this is conceptually incorrect. The purpose of float is to put inline block elements into the partial reflow. There is no partial reflow in a table; tables are governed by either the one-pass or two-pass algorithm. This is not what floating is meant to do. On top of that, floating throws away a great number of the metrics that the table 2-pass rebalance algorithm needs to do its work. That you have to specify which browser to look at your code in should suggest to you that your code is wrong. – John Haugeland Aug 27 '14 at 20:12
  • I agree with all that this is not correct solution, but when left with no approach, is there a better way to handle this scenario. Even I'm too looking for some good and legal solution. – Sandeep Choudhary Aug 28 '14 at 21:11