If you are not using IE or FireFox, try clicking "Run Code Snippet" below directly - I think it will show you all you need to "know" without all the babble. It is sticky table headers without any JavaScript at all. Just CSS / HTML.
I have seen many complicated solutions for sticky HTML table columns based on JavaScript, JQuery and advanced CSS. They are probably very good, and work well in several browsers, but the approach below should be very simple to implement (it can't get any more trivial) and be natively supported in all the latest browsers except IE11 and FireFox. No complexity to deal with.
I have also seen frequent suggestions to use two tables in sequence where the first one is fixed showing column values only, and the second table hides its column headers and shows value rows only. This seems quite clunky.
I have seen several other approaches as well.
Based on my limited testing the below works in the latest versions of Edge, Chrome, Opera and Vivaldi, but not in IE or FireFox (no errors will show up, there will just be no sticky headers - it degrades gracefully). I am not set up with enough test resources to be able to verify the compatibility exactly. Importantly there is not a single line of JavaScript code that can break.
The core of this "solution" is this CSS extract:
th {
position: sticky;
top: 0px;
}
It seems this will make the table header cells <th>
stick to its parent div's top border (top: 0px
), and this is apparently all that is needed to achieve sticky column headers in most recent browser versions.
Furthermore you can put several div's in the flow each with their own tables, or you can put several tables in the same div for that matter. It seems to work OK automagically.
I have a large test table with sorting enabled, and sorting also works fine when you click on the sticky headers.
The below sample has been cut down to minimum whilst still trying to implement a proper test of the overall approach. I will post a second answer with a longer table with proper thead and tbody sections (excluded in this simple sample).
#testdiv {
background-color: wheat;
height: 180px;
width: 600px; /* Try commenting this out as well */
overflow: scroll;
}
th {
/* The two core settings for sticky table headers */
position: sticky;
top: 0px;
/* A few more settings for better display*/
background-color: purple;
color: white;
white-space: nowrap;
border: 1px solid black;
text-align: left;
}
table, td {
border-collapse: collapse;
border: 1px solid black;
white-space: nowrap; /* Try commenting this out as well */
}
<div id="testdiv">
<p>Just a leading paragraph for demonstration.</p>
<p>Scroll down and sideways to check the sticky table headers.</p>
<table id='testtable'>
<tr>
<th>This is the first column:</th>
<th>Column Two:</th>
<th>Third in line here:</th>
</tr>
<tr>
<td>A summer night a long time ago I saw a fox chase a firefly.</td>
<td>A winter night a long long time ago, I watched the aurora borealis dance in the sky.</td>
<td>Hello world.</td>
</tr>
<tr>
<td>What is your favorite color?</td>
<td>Time's Arrow.</td>
<td>Just a short while ago I was young.</td>
</tr>
<tr>
<td colspan="3">This is a colspan.</td>
</tr>
<tr>
<td>Live long and prosper.</td>
<td>Kosmonaut.</td>
<td>What is the airspeed velocity of an unladen swallow?</td>
</tr>
<tr>
<td>A base in space, just to protect the human race.</td>
<td>Unimatrix Zero.</td>
<td>Are there any women here?</td>
</tr>
<tr>
<td>Raven.</td>
<td>Beware, here be dragons.</td>
<td>Timeless.</td>
</tr>
<tr>
<td>Astronaut.</td>
<td>42</td>
<td>HTML and CSS, the fiddliest of endeavours.</td>
</tr>
<tr>
<td rowspan="3">This is rowspan.</td>
<td>Oh my God.</td>
<td>777</td>
</tr>
<tr>
<td>Holy Crap.</td>
<td>778</td>
</tr>
<tr>
<td>The neighbour of the beast.</td>
<td>668</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
<tr>
<td colspan="2" rowspan="2">This is colspan and rowspan.</td>
<td>1</td>
</tr>
<tr>
<td>1</td>
</tr>
<tr>
<td>Three</td>
<td>Columns</td>
<td>Here</td>
</tr>
</table>
<p>A trailing paragraph for demonstration.</p>
<p>A trailing paragraph for demonstration.</p>
<p>A trailing paragraph for demonstration.</p>
<p>A trailing paragraph for demonstration.</p>
<p>A trailing paragraph for demonstration.</p>
</div>