Spacing between thead and tbody

CssHtml TableSpacing

Css Problem Overview


I have a simple html table like this:

<table>
  <thead>
    <tr><th>Column 1</th><th>Column 2</th></tr>
  </thead>
  <tbody>
    <tr class="odd first-row"><td>Value 1</td><td>Value 2</td></tr>
    <tr class="even"><td>Value 3</td><td>Value 4</td></tr>
    <tr class="odd"><td>Value 5</td><td>Value 6</td></tr>
    <tr class="even last-row"><td>Value 7</td><td>Value 8</td></tr>
  </tbody>
</table>

And I would like to style it the following way:

  • header row with a box-shadow
  • whitespace between the header row and the first body row

Box Shadow on Header + Spacing to Body

I have tried different things:

table {
    /* collapsed, because the bottom shadow on thead tr is hidden otherwise */
    border-collapse: collapse;
}
/* Shadow on the header row*/
thead tr   { box-shadow: 0 1px 10px #000000; }
/* Background colors defined on table cells */
th         { background-color: #ccc; }
tr.even td { background-color: yellow; }
tr.odd td  { background-color: orange; }

/* I would like spacing between thead tr and tr.first-row */

tr.first-row {
    /* This doesn't work because of border-collapse */
    /*border-top: 2em solid white;*/
}

tr.first-row td {
    /* This doesn't work because of border-collapse */
    /*border-top: 2em solid white;*/
    /* This doesn't work because of the td background-color */
    /*padding-top: 2em;*/
    /* Margin is not a valid property on table cells */
    /*margin-top: 2em;*/
}

See also: http://labcss.net/#8AVUF

Does anyone have any tips on how I could do this? Or achieve the same visual effect (i.e. bod-shadow + spacing)?

Css Solutions


Solution 1 - Css

I think I have it in this fiddle and I updated yours:

tbody:before {
    content: "-";
    display: block;
    line-height: 1em;
    color: transparent;
}

EDIT better & simpler:

tbody:before {
    content:"@";
    display:block;
    line-height:10px;
    text-indent:-99999px;
}

This way text is really invisible

Solution 2 - Css

Moreover you can use Zero-Width Non-Joiner to minimize sinsedrix CSS:

tbody:before {line-height:1em; content:"\200C"; display:block;}

Solution 3 - Css

This will give you some white space between the header and table content

thead tr {
  border-bottom: 10px solid white;
}

Although setting the border colour is a bit of a cheat method, it will work fine.

Form investigation, you can't set box-shadow to a table row, but you can to table cells:

th {
  box-shadow: 5px 5px 5px 0px #000000 ;
}

(I'm not sure how you want the shadow to look like, so just adjust the above.)

Solution 4 - Css

This worked for me on Chrome (for other browsers I don't know).

.theTargethead::after
{
	content: "";
	display: block;
	height: 1.5em;
	width: 100%;
	background: white;
}

Such css code creates an empty white space between the thead and the tbody of the table. If I set the background to transparent, the first column of the above tr > th elements shows its own color (green in my case) making about the first 1 cm of the ::after element green too.

Also using the "-" sign in the row content : "-"; instead of the empty string "" can create problems when exporting the printed pages to file, i.e. pdf. Of course this is parser/exporter dependent. Such exported file opened with a pdf editor (for ex.: Ms word, Ms Excel, OpenOffice, LibreOffice, Adobe Acrobat Pro) could still contain the minus sign. The empty string doesn't have the same issue. No problems in both cases if the printed html table is exported as image: nothing is rendered.

I didn't notice any issue even using

content : "\200C";

Solution 5 - Css

So box-shadow doesn't work well on the tr element... but it does work on a pseudo content element; sinsedrix put me on the right track and this is what I ended up with:

table {
    position: relative;
}

td,th {padding: .5em 1em;}

tr.even td { background-color: yellow; }
tr.odd td  { background-color: orange; }

thead th:first-child:before {
    content: "-";
    
    display: block;
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    z-index: -1;
    
    box-shadow: 0 1px 10px #000000;
    padding: .75em 0;
    
    background-color: #ccc;
    color: #ccc;
}

thead th {
    padding-bottom: 2em;
}

Solution 6 - Css

While all the solutions above are great, the result is inconsistent across browsers, so I figured out a better way to do it based on my heinous experience with email templates. Just add a dummy tbody in-between the actual tbody and the thead, nested in the dummy tbody should be a td with height set to the desired spacing. Example below

<table>
  <thead>
    <tr>
      <td>
      </td>
    </tr>
  </thead>
  // Dummy tbody
  <tbody>
    <tr>
      <td class="h-5"></td>
    </tr>
  </tbody>
  // Actual tbody
  <tbody class="rounded shadow-outline">
    <tr v-for="(tableRow, i) in tableBody" :key="`tableRow-${i}`">
      <td v-for="tableRowItem in tableRow" :key="tableRowItem" class="table-body">
        {{ tableRowItem }}
      </td>
    </tr>
  </tbody>
</table>

Solution 7 - Css

This should do the trick:

table {
  position: relative;
}
thead th { 
  // your box shadow here
}
tbody td {
  position: relative;
  top: 2rem; // or whatever space you want between the thead th and tbody td
}

And this should play nice with most browsers.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionBenView Question on Stackoverflow
Solution 1 - CsssinsedrixView Answer on Stackoverflow
Solution 2 - Cssuser2718944View Answer on Stackoverflow
Solution 3 - CssACarterView Answer on Stackoverflow
Solution 4 - Csswilly wonkaView Answer on Stackoverflow
Solution 5 - CssBenView Answer on Stackoverflow
Solution 6 - CssAbdulGafar Olamide AjaoView Answer on Stackoverflow
Solution 7 - CssDavid GaskinView Answer on Stackoverflow