JSFiddle - React, Tailwind, and code Playground
HTML
<h1>Flexible header test</h1><hr>
<p>Some test data. Some test data. Some test data. Some test data. Some test data. Some test data. Some test data. Some test data. Some test data. Some test data. Some test data. Some test data. Some test data. Some test data. Some test data. Some test data. Some test data. Some test data. Some test data. Some test data. Some test data. Some test data. Some test data. Some test data. Some test data. Some test data. Some test data. Some test data. Some test data. Some test data. Some test data. Some test data. </p><hr>
<table class="flexitable" border="1" width="1000">
<tr class="flexitr">
<td>Data 1</td>
<td>Data 2</td>
<td>Data 3</td>
<td>Data 4</td>
<td>Data 5</td>
<td>Data 6</td>
<td>Data 7</td>
<td>Data 8</td>
</tr>
<tr><td>Data</td><td>Data</td><td>Data</td><td>Data</td><td>Data</td><td>Data</td><td>Data</td><td>Data</td></tr>
<tr><td>Data</td><td>Data</td><td>Data</td><td>Data</td><td>Data</td><td>Data</td><td>Data</td><td>Data</td></tr>
<tr><td>Data</td><td>Data</td><td>Data</td><td>Data</td><td>Data</td><td>Data</td><td>Data</td><td>Data</td></tr>
<tr><td>Data</td><td>Data</td><td>Data</td><td>Data</td><td>Data</td><td>Data</td><td>Data</td><td>Data</td></tr>
<tr><td>Data</td><td>Data</td><td>Data</td><td>Data</td><td>Data</td><td>Data</td><td>Data</td><td>Data</td></tr>
<tr><td>Data</td><td>Data</td><td>Data</td><td>Data</td><td>Data</td><td>Data</td><td>Data</td><td>Data</td></tr>
<tr><td>Data</td><td>Data</td><td>Data</td><td>Data</td><td>Data</td><td>Data</td><td>Data</td><td>Data</td></tr>
<tr><td>Data</td><td>Data</td><td>Data</td><td>Data</td><td>Data</td><td>Data</td><td>Data</td><td>Data</td></tr>
<tr><td>Data</td><td>Data</td><td>Data</td><td>Data</td><td>Data</td><td>Data</td><td>Data</td><td>Data</td></tr>
...
CSS
.flexitable td, .flexiholder td {
padding: 5px;
}
.flexitr {
background-color: #bbb;
}
.flexiholder {
position: fixed;
top: 0;
left: 0;
width: 100;
display: none;
}
JavaScript
var fhHeight = 0;
var ft = $('.flexitable');
var fhold = $('.flexiholder');
var win = $(window);
var ftr = $('.flexitr');
var hscrollTimer = -1;
$(window).scroll(function() {
// adjust left offset of flexi-header
//fhold.css({'left': '-'+win.scrollLeft()+'px'});
if(hscrollTimer != -1) clearTimeout(hscrollTimer);
hscrollTimer = setTimeout(function () {
fhold.animate({'left': '-'+win.scrollLeft()+'px'}, 'fast');
hscrollTimer = -1;
}, 250);
if(fhHeight==0 && (ft.offset().top - win.scrollTop()) <= 0 &&
!ftr.parent().hasClass('flexiholder')) {
fhHeight = ftr.height();
fhold.css('width', ft.outerWidth(true));
ftr.appendTo(fhold);
fhold.show();
}
else if(fhHeight!=0 && fhHeight!=-1 &&
(ft.offset().top - win.scrollTop() > fhHeight ||
ft.offset().top + ft.outerHeight(true) - win.scrollTop() < 0)) {
if(ft.offset().top + ft.outerHeight(true) - win.scrollTop() < 0) {
fhHeight = -1;
}
else {
fhHeight = 0;
}
ftr.prependTo(ft);
fhold.hide();
}
else if(fhHeight==-1 && ft.offset().top + ft.outerHeight(true) - win.scrollTop() > 0) {
fhHeight = 0;
}
//if(ftr.parent().hasClass('flexiholder')) {
// console.log('-'+win.scrollLeft()+'px');
//}
});