user1112081
user1112081

Reputation: 661

CSS table border spacing inside only

I have trying to work this out for months, and Google hasn't helped me. I'm trying to have spacing between <td> and <th> tags in a table, but when I do, it does spacing in the outside. Therefore, the table isn't inline with anything else. So it looks like the table has some padding.

I can't seem to find a solution.

Here is an example of the issue

Upvotes: 66

Views: 59512

Answers (6)

Abhishek Goel
Abhishek Goel

Reputation: 19731

Here is the cool hack to do that

table {
    border-collapse: inherit;
    border-spacing: 10px;
    width: calc(100% + 20px);
    margin-left: -10px;
}

use margin-left: -10px; to remove left padding but in the right there will be 20px padding. Now to update it use width: calc(100% + 20px);

Upvotes: 5

TLindig
TLindig

Reputation: 50090

I optimized the solution with transparent border so it has no more obliquely cut inner borders.

1) let table fill horizontal and collapse the borders:

table {
  width: 100%;
  border-collapse: collapse;
}

2) Set all borders of table cells to width 0 and prevent background is drawn below the border.

td {
  border: 0px solid transparent;
  background-clip: padding-box;
}

3) Set inner space with transparent border but not to first row and column.

tr > td + td {
  border-left-width: 10px;
}

tr + tr > td {
  border-top-width: 10px;
}

here is a jsbin

Upvotes: 27

Marc Stober
Marc Stober

Reputation: 10517

I found a way to do this with negative margins and improves on Steven's answer in that it lets you make the table take up 100% even if it doesn't have enough content. The solution is to make the table width 100% and use a negative margin on a containing element:

#container {
    margin: 0 -10px;
}
table {
    border-collapse: separate;
    border-spacing: 10px;
}
td, th {
    background-color: #ccf;
    padding: 5px;
}

See it as a jsFiddle

Upvotes: 21

doubleJ
doubleJ

Reputation: 1216

Similar to what Steven Vachon said, negative margin may be your best bet.

Alternatively, you can use calc() to fix the problem.

CSS:

/* border-collapse and border-spacing are css equivalents to <table cellspacing="5"> */

.boxmp {
    width:100%;
    border-collapse:separate;
    border-spacing:5px 0;
}

/* border-spacing includes the left of the first cell and the right of the last cell
    negative margin the left/right and add those negative margins to the width
    ios6 requires -webkit-
    android browser doesn't support calc()
    100.57% is the widest that I could get without a horizontal scrollbar at 1920px wide */

.boxdual {
    margin:0 -5px;
    width:100.57%;
    width:-webkit-calc(100% + 10px);
    width:calc(100% + 10px);
}

Just add whatever margin you take off or the width will be too narrow (100% isn't wide enough).

Upvotes: 11

Steven Vachon
Steven Vachon

Reputation: 3980

Use negative margins and a container with positive padding.

#container {
    box-sizing: border-box; /* avoids exceeding 100% width */
    margin: 0 auto;
    max-width: 1024px;
    padding: 0 10px;    /* fits table overflow */
    width: 100%;
}

table {
    border-collapse: separate;
    border-spacing: 10px;
    margin: 0 -10px;    /* ejects outer border-spacing */
    min-width: 100%;    /* in case content is too short */
}

td {
    width: 25%;     /* keeps it even */
}

Just make sure that you have substantial content for it to stretch the table to 100% width, or else it'll be 20px too narrow.

More info: svachon.com/blog/inside-only-css-table-border-spacing/

Upvotes: 3

JumpStomp
JumpStomp

Reputation: 277

Had the same problem, the border spacing property was adding space around the table as well, and to my knowledge, there wasn’t anyway to limit it to only ‘the inside’, so I used transparent borders instead:

table td {
   border-left: 1em solid transparent;
   border-top: 1em solid transparent;
}

This sets ‘border spacing’ as normal, except that there’s ‘unwanted’ spacing at the top and left of the table.

table td:first-child {
   border-left: 0;
}

Selects the first column.

table tr:first-child td {
   border-top: 0;
}

Selects the td elements of the first row (assuming that the top of the table starts with a tr element, change accordingly for th).

Upvotes: 26

Related Questions