2

While setting up an excel style table with html and css with a sticky head I realized that the borders on the head of the table looked strange.

Here's the code:

table {
  border-collapse: collapse;
  position: relative;
}

tr:nth-child(even) {
  background-color: lightgray;
}

th {
  background-color: lightblue;
  position: sticky;
  top: 0;
}

th,
td {
  border: 1px solid black;
  padding: 10px 20px;
}
<table>
  <thead>
    <tr>
      <th>Column 1</th>
      <th>Column 2</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Row 1</td>
      <td>Row 1</td>
    </tr>
    <tr>
      <td>Row 2</td>
      <td>Row 2</td>
    </tr>
  </tbody>
</table>

JSFiddle: https://jsfiddle.net/cpotdevin/5j3ah247/

The following images show how it looks in three different browsers.

Chrome: The upper and lower borders on the sticky row disappear. enter image description here

Firefox: All inner borders disappear. enter image description here

Safari: Same as in chrome. enter image description here

I also tried not using border-collapse: collapse; and instead using the cellspacing=0 attribute on the table but this makes inner borders look thicker than I'd like.

enter image description here

JSFiddle: https://jsfiddle.net/cpotdevin/wxvn1crL/

What can I do to solve this? I want the borders to always look like they do when the table head has not entered the sticky state. enter image description here

EDIT

As pointed out by @JonMac1374 this question was already answered here.

This was my implementation of that solution.

  • Does this answer your question? [Border style do not work with sticky position element](https://stackoverflow.com/questions/50361698/border-style-do-not-work-with-sticky-position-element) – JonMac1374 Dec 18 '19 at 15:03

3 Answers3

5

one work around could be a shadow:

tested width today's latest Chrome & Firefox

https://jsfiddle.net/4npw6q5j/ or demo below you can check on, to comment and see if that can be an alternative for you.

table {
  position: relative;
}

tr:nth-child(even) {
  background-color: lightgray;
}

th {
  background-color: lightblue;
  position: sticky;
  top: 0;box-shadow:0 1px
}

th,
td {
  border: 1px solid black;
  padding: 10px 20px;
}
<table cellspacing=0>
  <thead>
    <tr>
      <th>Column 1</th>
      <th>Column 2</th>
      <th>Column 3</th>
      <th>Column 4</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Row 1</td>
      <td>Row 1</td>
      <td>Row 1</td>
      <td>Row 1</td>
    </tr>
    <tr>
      <td>Row 2</td>
      <td>Row 2</td>
      <td>Row 2</td>
      <td>Row 2</td>
    </tr>
    <tr>
      <td>Row 3</td>
      <td>Row 3</td>
      <td>Row 3</td>
      <td>Row 3</td>
    </tr>
    <tr>
      <td>Row 4</td>
      <td>Row 4</td>
      <td>Row 4</td>
      <td>Row 4</td>
    </tr>
    <tr>
      <td>Row 5</td>
      <td>Row 5</td>
      <td>Row 5</td>
      <td>Row 5</td>
    </tr>
    <tr>
      <td>Row 6</td>
      <td>Row 6</td>
      <td>Row 6</td>
      <td>Row 6</td>
    </tr>
    <tr>
      <td>Row 7</td>
      <td>Row 7</td>
      <td>Row 7</td>
      <td>Row 7</td>
    </tr>
  </tbody>
</table>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
G-Cyrillus
  • 101,410
  • 14
  • 105
  • 129
0

border-collapse: collapse will remove the one of the overlapping borders. If you really don't like the thick border effect, you can create 2 tables, one for <thead>, another for tbodyand set td{border-top: 0px !important;}:

tr:nth-child(even) {
  background-color: lightgray;
}
table{
  border-collapse: collapse;
}
.title {
  background-color: lightblue;
  position: sticky;
  top: 0;

}

th,
td {
  border: 1px solid black;
  padding: 10px 20px;
}
td{
  border-top: 0px !important;
}
<table cellspacing="0" width="500" class="title">
  <thead>
    <tr>
      <th>Column 1</th>
      <th>Column 2</th>
    </tr>
  </thead>
</table>
<table cellspacing="0" width="500">
  <tbody>
    <tr>
      <td>Row 1</td>
      <td>Row 1</td>
    </tr>
    <tr>
      <td>Row 2</td>
      <td>Row 2</td>
    </tr>
  </tbody>
</table>

Result:

enter image description here

Nova
  • 364
  • 1
  • 15
0

You need to use border-collapse: separate and set only the bottom and left borders.

The edges of the table can be targeted to fill in the missing borders as follows:

table {
  position: relative;
  border-collapse: separate;
}

tr:nth-child(even) {
  background-color: lightgray;
}

th {
  background-color: lightblue;
  position: sticky;
  top: 0;
}

th, td{
  border-color:black;
  border-style:solid;
  border-width:0 0 1px 1px;
  padding: 10px 20px;
}

th{
  border-top-width:1px;
}

th:last-child, td:last-child
{
  border-right-width:1px;
}

tr:last-child td{
  border-bottom-width:1px;
}

JSFiddle

JonMac1374
  • 466
  • 2
  • 7