I'm working on a layout where I need the header of a horizontally scrollable middle table to remain sticky at the top while scrolling vertically. The headers for the left and right tables stick just fine, but I'm having trouble with the middle table's header (probably due to its horizontal scroll).
https://codepen.io/Reynaldo-Rodriguez-the-sasster/pen/XWLqRxo
.container {
position: relative;
display: flex;
}
table th {
position: sticky;
top: 0;
background: white;
}
.table-center {
overflow-x: scroll;
}
table,
th,
td {
border: 1px solid black;
}
th,
td {
padding: .5em 1em;
white-space: nowrap;
}
::-webkit-scrollbar {
-webkit-appearance: none;
background-color: transparent;
height: 7px;
}
::-webkit-scrollbar-thumb {
border-radius: 4px;
background-color: rgb(121 121 121);
box-shadow: none;
}
::-webkit-scrollbar-track {
background-color: white;
border: none;
}
<div class="container">
<div class="table-left">
<table>
<tr>
<th>RIDER #</th>
<th>RIDER NAME</th>
</tr>
<tr>
<td>#322</td>
<td>Chase Lanes</td>
</tr>
<tr>
<td>#87</td>
<td>Marshall Holbrook</td>
</tr>
<tr>
<td>#567</td>
<td>Marshall Holbrook</td>
</tr>
<tr>
<td>#143</td>
<td>Marshall Holbrook</td>
</tr>
<tr>
<td>#322</td>
<td>Chase Lanes</td>
</tr>
<tr>
<td>#87</td>
<td>Marshall Holbrook</td>
</tr>
<tr>
<td>#567</td>
<td>Marshall Holbrook</td>
</tr>
<tr>
<td>#143</td>
<td>Marshall Holbrook</td>
</tr>
<tr>
<td>#322</td>
<td>Chase Lanes</td>
</tr>
<tr>
<td>#87</td>
<td>Marshall Holbrook</td>
</tr>
<tr>
<td>#567</td>
<td>Marshall Holbrook</td>
</tr>
<tr>
<td>#143</td>
<td>Marshall Holbrook</td>
</tr>
</table>
</div>
<div class="table-center">
<table>
<tr>
<th>Lap 1</th>
<th>Lap 2</th>
<th>Lap 3</th>
<th>Lap 4</th>
<th>Lap 5</th>
<th>Lap 6</th>
<th>Lap 7</th>
<th>Lap 8</th>
<th>Lap 9</th>
<th>Lap 10</th>
<th>Lap 11</th>
<th>Lap 12</th>
<th>Lap 13</th>
<th>Lap 14</th>
<th>Lap 15</th>
<th>Lap 16</th>
<th>Lap 17</th>
<th>Lap 18</th>
<th>Lap 19</th>
<th>Lap 20</th>
<th>Lap 21</th>
<th>Lap 22</th>
<th>Lap 23</th>
<th>Lap 24</th>
<th>Lap 25</th>
<th>Lap 26</th>
<th>Lap 27</th>
<th>Lap 28</th>
<th>Lap 29</th>
<th>Lap 30</th>
</tr>
<tr>
<td>00:02.826</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>00:02.826</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>00:02.826</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
</tr>
<tr>
<td>00:02.826</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>00:02.826</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>00:02.826</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
</tr>
<tr>
<td>00:02.826</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>00:02.826</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>00:02.826</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
</tr>
<tr>
<td>00:02.826</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>00:02.826</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>00:02.826</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
</tr>
<tr>
<td>00:02.826</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>00:02.826</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>00:02.826</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
</tr>
<tr>
<td>00:02.826</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>00:02.826</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>00:02.826</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
</tr>
<tr>
<td>00:02.826</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>00:02.826</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>00:02.826</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
</tr>
<tr>
<td>00:02.826</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>00:02.826</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>00:02.826</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
</tr>
<tr>
<td>00:02.826</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>00:02.826</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>00:02.826</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
</tr>
<tr>
<td>00:02.826</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>00:02.826</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>00:02.826</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
</tr>
<tr>
<td>00:02.826</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>00:02.826</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>00:02.826</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
</tr>
<tr>
<td>00:02.826</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>00:02.826</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>00:02.826</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
<td>--:---:--</td>
</tr>
</table>
</div>
<div class="table-right">
<table>
<tr>
<th>FASTEST LAP</th>
<th>AVG LAP</th>
<th>OVERALL TIME</th>
</tr>
<tr>
<td>00:00</td>
<td>00:00</td>
<td>00:00</td>
</tr>
<tr>
<td>00:00</td>
<td>00:00</td>
<td>00:00</td>
</tr>
<tr>
<td>00:00</td>
<td>00:00</td>
<td>00:00</td>
</tr>
<tr>
<td>00:00</td>
<td>00:00</td>
<td>00:00</td>
</tr>
<tr>
<td>00:00</td>
<td>00:00</td>
<td>00:00</td>
</tr>
<tr>
<td>00:00</td>
<td>00:00</td>
<td>00:00</td>
</tr>
<tr>
<td>00:00</td>
<td>00:00</td>
<td>00:00</td>
</tr>
<tr>
<td>00:00</td>
<td>00:00</td>
<td>00:00</td>
</tr>
<tr>
<td>00:00</td>
<td>00:00</td>
<td>00:00</td>
</tr>
<tr>
<td>00:00</td>
<td>00:00</td>
<td>00:00</td>
</tr>
<tr>
<td>00:00</td>
<td>00:00</td>
<td>00:00</td>
</tr>
<tr>
<td>00:00</td>
<td>00:00</td>
<td>00:00</td>
</tr>
</table>
</div>
</div>
I was able to resolve this issue by using JS and translateY. Updated version is up in codepen if you guys are curious.
const middleTable = document.getElementById('middleTable');
const stickyMiddleHeader = document.getElementById('stickyMiddleHeader');
window.addEventListener('scroll', () => {
const scrollTop = window.scrollY;
const tableOffsetTop = middleTable.getBoundingClientRect().top + window.scrollY;
const translateY = scrollTop > tableOffsetTop ? scrollTop - tableOffsetTop : 0;
stickyMiddleHeader.style.transform = `translateY(${translateY}px)`;});