Chrome, FF, Edge
the simplest solution is to use th { position: sticky; top: 0; }
/* JUST COMMON TABLE STYLES... */
table { border-collapse: collapse; width: 100%; }
th, td { background: #fff; padding: 8px 16px; }
.tableFixHead {
overflow: auto;
height: 100px;
}
.tableFixHead thead th {
position: sticky;
top: 0;
}
<div class="tableFixHead">
<table>
<thead>
<tr><th>TH 1</th><th>TH 2</th></tr>
</thead>
<tbody>
<tr><td>A1</td><td>A2</td></tr>
<tr><td>B1</td><td>B2</td></tr>
<tr><td>C1</td><td>C2</td></tr>
<tr><td>D1</td><td>D2</td></tr>
<tr><td>E1</td><td>E2</td></tr>
</tbody>
</table>
</div>
IE11
To sloppily support IE11 (2.5% market share as of 10/2018), a bit jaggy but at least TH
s are on top – you could add this JavaScript:
function isIE() {
return navigator.userAgent.indexOf('MSIE') > -1 || navigator.appVersion.indexOf('Trident/') > -1
}
if (isIE()) {
// Fix table head
function tableFixHead(ths) {
var sT = this.scrollTop;
[].forEach.call(ths, function(th) {
th.style.transform = "translateY(" + sT + "px)";
});
}
[].forEach.call(document.querySelectorAll(".tableFixHead"), function(el) {
var ths = el.querySelectorAll("thead th");
el.addEventListener("scroll", tableFixHead.bind(el, ths));
});
}
which will (since IE ignores sticky
position) use transform translateY
to position the TH elements.
PS: the above JS (without the wrapping if
statement) works pretty decently for all other evergreen browsers too – in case position: sticky;
does not fits your needs…