Table headers position:sticky and border issue
I have a table that I'm trying to get sticky headers, following this article. Except my table style has the headers with a border at the top and bottom.
The part I do not understand is that the top/bottom borders applied to the th
scroll away with the rest of the table instead of staying with the "stuck" header cells. Is there anything that can be done about this?
Working sample can be found here: https://codepen.io/smlombardi/pen/MNKqQY?editors=1100#0
let string = ''
console.log("oj")
for(let i=0; i<100; i++) {
string += `
<tr>
<td>Malcolm Reynolds</td>
<td>Captain</td>
<td>9035749867</td>
<td>mreynolds</td>
</tr>
`
}
document.getElementsByTagName('tbody')[0].innerHTML += string
.table-sticky-container {
height: 200px;
overflow-y: scroll;
border-top: 1px solid green;
border-bottom: 1px solid green;
}
.table-sticky {
th {
position: sticky;
top: 0;
z-index: 2;
border-top: 1px solid red !important;
border-bottom: 2px solid red !important;
}
}
<div class="table-sticky-container">
<table class="table table-sticky">
<thead class="thead-light">
<tr>
<th scope="col">Name</th>
<th scope="col">Title</th>
<th scope="col">ID</th>
<th scope="col">Username</th>
</tr>
</thead>
<tbody>
<tr>
<td>Malcolm Reynolds</td>
<td>Captain</td>
<td>9035749867</td>
<td>mreynolds</td>
</tr>
</tbody>
</table>
</div>
You can add
.table {
border-collapse: separate;
}
But unfortunately it looks bad, a better solution will be adding a workaround using a pseudo-element.
th:after,
th:before {
content: '';
position: absolute;
left: 0;
width: 100%;
}
th:before {
top: -1px;
border-top: 1px solid red;
}
th:after {
bottom: -1px;
border-bottom: 2px solid red;
}
.table-sticky-container {
height: 200px;
overflow-y: scroll;
border-top: 1px solid green;
border-bottom: 1px solid green;
}
.table-sticky th {
position: -webkit-sticky;
position: sticky;
top: 0;
z-index: 2;
}
th:after,
th:before {
content: '';
position: absolute;
left: 0;
width: 100%;
}
th:before {
top: -1px;
border-top: 1px solid red;
}
th:after {
bottom: -1px;
border-bottom: 2px solid red;
}
<link rel='stylesheet' href='https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/css/bootstrap.min.css'>
<div class="table-sticky-container">
<table class="table table-sticky">
<thead class="thead-light">
<tr>
<th scope="col">Name</th>
<th scope="col">Title</th>
<th scope="col">ID</th>
<th scope="col">Username</th>
</tr>
</thead>
<tbody>
<tr>
<td>Malcolm Reynolds</td>
<td>Captain</td>
<td>9035749867</td>
<td>mreynolds</td>
</tr>
<tr>
<td>Zoe Washburne</td>
<td>First Officer</td>
<td>8908980980</td>
<td>zwashburne</td>
</tr>
<tr>
<td>Kaylee Frye</td>
<td>Engineer</td>
<td>6678687678</td>
<td>kfrye</td>
</tr>
<tr>
<td>Malcolm Reynolds</td>
<td>Captain</td>
<td>9035749867</td>
<td>mreynolds</td>
</tr>
<tr>
<td>Zoe Washburne</td>
<td>First Officer</td>
<td>8908980980</td>
<td>zwashburne</td>
</tr>
<tr>
<td>Kaylee Frye</td>
<td>Engineer</td>
<td>6678687678</td>
<td>kfrye</td>
</tr>
</tbody>
</table>
</div>
The second solution
.table {
border-collapse: collapse;
}
.table-sticky thead th {
position: -webkit-sticky;
position: sticky;
top: 0;
z-index: 2;
box-shadow: inset 0 1px 0 red, inset 0 -2px 0 red;
}
You can add
.table {
border-collapse: separate;
border-spacing: 0;
}