Reputation: 2543
I'm trying to get a sticky table header to work with a complex header. It works fine for standard tables. The table will stick at the top row and not the second causing the header to look "out of whack" or sort of staggered. I tried putting the position sticky on the thead and that didn't seem to do anything.
Here is my table:
table {
border: 1px solid black;
font-size: 14px;
margin: 10px 0;
position: relative;
}
thead tr th {
background-color: gray;
position: sticky;
top: -2px;
}
thead {
border: 1px solid black;
line-height: 1.25;
overflow: hidden;
}
td {
border: 1px solid black;
line-height: 1.25;
overflow: hidden;
padding: 4px;
}
<table class='sticky-table'>
<thead>
<tr>
<th rowspan="2">First column</th>
<th colspan="3">Top of second column</th>
</tr>
<tr>
<th>One</th>
<th>Two</th>
<th>Three</th>
</tr>
</thead>
<tbody>
<tr>
<td>First cell</td>
<td>Second cell</td>
<td>Third cell</td>
<td>Fourth cell</td>
</tr>
<tr>
<td>First cell</td>
<td>Second cell</td>
<td>Third cell</td>
<td>Fourth cell</td>
</tr>
<tr>
<td>First cell</td>
<td>Second cell</td>
<td>Third cell</td>
<td>Fourth cell</td>
</tr>
<tr>
<td>First cell</td>
<td>Second cell</td>
<td>Third cell</td>
<td>Fourth cell</td>
</tr>
<tr>
<td>First cell</td>
<td>Second cell</td>
<td>Third cell</td>
<td>Fourth cell</td>
</tr>
<tr>
<td>First cell</td>
<td>Second cell</td>
<td>Third cell</td>
<td>Fourth cell</td>
</tr>
<tr>
<td>First cell</td>
<td>Second cell</td>
<td>Third cell</td>
<td>Fourth cell</td>
</tr>
<tr>
<td>First cell</td>
<td>Second cell</td>
<td>Third cell</td>
<td>Fourth cell</td>
</tr>
<tr>
<td>First cell</td>
<td>Second cell</td>
<td>Third cell</td>
<td>Fourth cell</td>
</tr>
<tr>
<td>First cell</td>
<td>Second cell</td>
<td>Third cell</td>
<td>Fourth cell</td>
</tr>
<tr>
<td>First cell</td>
<td>Second cell</td>
<td>Third cell</td>
<td>Fourth cell</td>
</tr>
<tr>
<td>First cell</td>
<td>Second cell</td>
<td>Third cell</td>
<td>Fourth cell</td>
</tr>
<tr>
<td>First cell</td>
<td>Second cell</td>
<td>Third cell</td>
<td>Fourth cell</td>
</tr>
</tbody>
</table>
Upvotes: 4
Views: 3297
Reputation: 46
I believe the js below will solve the problem. There is some weirdness with the borders, but the ths stick properly.
var tableHeaderTop = document.querySelector('.sticky-table thead').getBoundingClientRect().top;
var ths = document.querySelectorAll('.sticky-table thead th')
for(var i = 0; i < ths.length; i++) {
var th = ths[i];
th.style.top = th.getBoundingClientRect().top - tableHeaderTop + "px";
}
table {
border: 1px solid black;
font-size: 14px;
margin: 10px 0;
position: relative;
}
thead tr th {
background-color: gray;
position: sticky;
top: -2px;
}
thead {
border: 1px solid black;
line-height: 1.25;
overflow: hidden;
}
td {
border: 1px solid black;
line-height: 1.25;
overflow: hidden;
padding: 4px;
}
<table class='sticky-table'>
<thead>
<tr>
<th rowspan="2">First column</th>
<th colspan="3">Top of second column</th>
</tr>
<tr>
<th>One</th>
<th>Two</th>
<th>Three</th>
</tr>
</thead>
<tbody>
<tr>
<td>First cell</td>
<td>Second cell</td>
<td>Third cell</td>
<td>Fourth cell</td>
</tr>
<tr>
<td>First cell</td>
<td>Second cell</td>
<td>Third cell</td>
<td>Fourth cell</td>
</tr>
<tr>
<td>First cell</td>
<td>Second cell</td>
<td>Third cell</td>
<td>Fourth cell</td>
</tr>
<tr>
<td>First cell</td>
<td>Second cell</td>
<td>Third cell</td>
<td>Fourth cell</td>
</tr>
<tr>
<td>First cell</td>
<td>Second cell</td>
<td>Third cell</td>
<td>Fourth cell</td>
</tr>
<tr>
<td>First cell</td>
<td>Second cell</td>
<td>Third cell</td>
<td>Fourth cell</td>
</tr>
<tr>
<td>First cell</td>
<td>Second cell</td>
<td>Third cell</td>
<td>Fourth cell</td>
</tr>
<tr>
<td>First cell</td>
<td>Second cell</td>
<td>Third cell</td>
<td>Fourth cell</td>
</tr>
<tr>
<td>First cell</td>
<td>Second cell</td>
<td>Third cell</td>
<td>Fourth cell</td>
</tr>
<tr>
<td>First cell</td>
<td>Second cell</td>
<td>Third cell</td>
<td>Fourth cell</td>
</tr>
<tr>
<td>First cell</td>
<td>Second cell</td>
<td>Third cell</td>
<td>Fourth cell</td>
</tr>
<tr>
<td>First cell</td>
<td>Second cell</td>
<td>Third cell</td>
<td>Fourth cell</td>
</tr>
<tr>
<td>First cell</td>
<td>Second cell</td>
<td>Third cell</td>
<td>Fourth cell</td>
</tr>
</tbody>
</table>
Upvotes: 3
Reputation: 3933
I do not like this solution, because the space is "hard" coded, but it works as desired, I think, isn't it?
table {
border: 1px solid black;
font-size: 14px;
margin: 10px 0;
position: relative;
}
thead tr th {
background-color: gray;
position: sticky;
top: -2px;
}
.header {
background-color: gray;
position: sticky;
top: 20px;
}
thead {
border: 1px solid black;
line-height: 1.25;
overflow: hidden;
}
td {
border: 1px solid black;
line-height: 1.25;
overflow: hidden;
padding: 4px;
}
<table class='sticky-table'>
<thead>
<tr>
<th rowspan="2">First column</th>
<th colspan="3">Top of second column</th>
</tr>
<tr>
<th class="header">One</th>
<th class="header">Two</th>
<th class="header">Three</th>
</tr>
</thead>
<tbody>
<tr>
<td>First cell</td>
<td>Second cell</td>
<td>Third cell</td>
<td>Fourth cell</td>
</tr>
<tr>
<td>First cell</td>
<td>Second cell</td>
<td>Third cell</td>
<td>Fourth cell</td>
</tr>
<tr>
<td>First cell</td>
<td>Second cell</td>
<td>Third cell</td>
<td>Fourth cell</td>
</tr>
<tr>
<td>First cell</td>
<td>Second cell</td>
<td>Third cell</td>
<td>Fourth cell</td>
</tr>
<tr>
<td>First cell</td>
<td>Second cell</td>
<td>Third cell</td>
<td>Fourth cell</td>
</tr>
<tr>
<td>First cell</td>
<td>Second cell</td>
<td>Third cell</td>
<td>Fourth cell</td>
</tr>
<tr>
<td>First cell</td>
<td>Second cell</td>
<td>Third cell</td>
<td>Fourth cell</td>
</tr>
<tr>
<td>First cell</td>
<td>Second cell</td>
<td>Third cell</td>
<td>Fourth cell</td>
</tr>
<tr>
<td>First cell</td>
<td>Second cell</td>
<td>Third cell</td>
<td>Fourth cell</td>
</tr>
<tr>
<td>First cell</td>
<td>Second cell</td>
<td>Third cell</td>
<td>Fourth cell</td>
</tr>
<tr>
<td>First cell</td>
<td>Second cell</td>
<td>Third cell</td>
<td>Fourth cell</td>
</tr>
<tr>
<td>First cell</td>
<td>Second cell</td>
<td>Third cell</td>
<td>Fourth cell</td>
</tr>
<tr>
<td>First cell</td>
<td>Second cell</td>
<td>Third cell</td>
<td>Fourth cell</td>
</tr>
</tbody>
</table>
Upvotes: 1