Reputation: 14922
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>
Upvotes: 52
Views: 38366
Reputation: 4153
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;
}
Upvotes: 64
Reputation: 71
Don't use border-collapse
and draw the lines as follows :
td, th {
border-bottom: 1px solid grey;
border-right: 1px solid grey;
}
table {
border-spacing: 0px;
border-left: 1px solid grey
}
th {
background-color:#c5e8ec;
position: sticky;
position: -webkit-sticky;
border-top: 1px solid grey;
top:0;
}
Upvotes: 7
Reputation: 565
You can add
.table {
border-collapse: separate;
border-spacing: 0;
}
Upvotes: 45
Reputation: 17
Another working solution (tested at latest Chrome and FF) - wrap th/td content with divs and use those divs borders instead of cell's borders.
<div class="wrapper">
<table>
<thead>
<tr>
<th>
<div class="cell">head1</div>
</th>
<th>
<div class="cell">head2</div>
</th>
<th>
<div class="cell">head3</div>
</th>
<th>
<div class="cell">head4</div>
</th>
<th>
<div class="cell">head5</div>
</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<div class="cell">1</div>
</td>
<td>
<div class="cell">1</div>
</td>
<td>
<div class="cell">1</div>
</td>
<td>
<div class="cell">1</div>
</td>
<td>
<div class="cell">1</div>
</td>
</tr>
<tr>
<td>
<div class="cell">1</div>
</td>
<td>
<div class="cell">1</div>
</td>
<td>
<div class="cell">1</div>
</td>
<td>
<div class="cell">1</div>
</td>
<td>
<div class="cell">1</div>
</td>
</tr>
<tr>
<td>
<div class="cell">1</div>
</td>
<td>
<div class="cell">1</div>
</td>
<td>
<div class="cell">1</div>
</td>
<td>
<div class="cell">1</div>
</td>
<td>
<div class="cell">1</div>
</td>
</tr>
</tbody>
</table>
</div>
table {
border-collapse: collapse;
table-layout: fixed;
width: 500px;
}
.wrapper {
height: 150px;
overflow: auto;
}
td, th {
width: 150px;
height: 50px;
text-align: center;
font-size: 32px;
padding: 0;
}
th {
position: sticky;
top: 0;
left: 0;
background-color: #fff;
}
.cell {
border: 1px solid black;
height: 100%;
}
td .cell {
border-top: none;
border-left: none;
}
th .cell {
border-left: none;
}
td:first-child .cell,
th:first-child .cell {
border-left: 1px solid black;
}
Upvotes: 0