JSFiddle - React, Tailwind, and code Playground
HTML
<div class="table-wrapper">
<table>
<thead>
<tr>
<th colspan="2">Vehicles</th>
</tr>
</thead>
<tbody>
<tr>
<th colspan="2" class="title">Cars</th>
</tr>
<tr>
<td>Opel</td>
<td>Corsa</td>
</tr>
<tr>
<td>Renault</td>
<td>Clio</td>
</tr>
<tr>
<td>Citroen</td>
<td>AX</td>
</tr>
<tr>
<th colspan="2" class="title">Motorbikes</th>
</tr>
<tr>
<td>Honda</td>
<td>Hornet</td>
</tr>
<tr>
<td>Yamaha</td>
<td>Virago</td>
</tr>
<tr>
<td>Suzuki</td>
<td>GSXR</td>
</tr>
<tr>
<th colspan="2" class="title">Planes</th>
</tr>
<tr>
<td>Boeing</td>
<td>737</td>
</tr>
<tr>
<td>Boeing</td>
<td>767</td>
</tr>
<tr>
<td>Boeing</td>
<td>777</td>
</tr>
</tbody>
</table>
</div>
CSS
.table-wrapper {
height: 180px;
overflow: hidden;
}
table {
font: arial;
text-align: left;
width: 300px;
}
tbody {
display: block;
height: 80px;
overflow: auto;
width: 100%;
}
JavaScript
//start scrolling
$('tbody').scroll(function() {
doStuff();
});
//initialize headers
var headers = [];
$('.title').each(function(index) {
var header = {
thead: $(this),
top: $(this).parent().index() * $(this).outerHeight(),
bottom: 0
};
headers.push(header);
});
//setup the first one
headers[0].thead.addClass('active');
$('thead').find('.active').remove();
$('.active').last().clone().appendTo($('thead'));
//calculate header container heights
for (var i = 0; i < headers.length; ++i) {
headers[i].bottom = (i+1 < headers.length) ? headers[i+1].top : 100000;
}
var headerIndex = 0;
function doStuff() {
var scroll = $('tbody').scrollTop();
if (scroll >= headers[headerIndex].top
&& scroll < headers[headerIndex].bottom) {
return true;
}
else {
//get new headerindex and update header
headers[headerIndex].thead.removeClass('active');
headerIndex = (scroll < headers[headerIndex].top) ? headerIndex-1 : headerIndex+1;
headers[headerIndex].thead.addClass('active');
$('thead').find('.active').remove();
$('.active').last().clone().appendTo($('thead'));
}
}