Fixed Table Headers with Pure CSS: Sticky On Scroll
Standard HTML tables are not very complex, and generally do not need to be. However, there may come a scenario where you have large amounts of data or very little space to display the data.
In these cases, fixed table headers that are sticky on scroll can be a perfect solution! Luckily, there are a few simple and useful ways to accomplish this with pure CSS. In this article, we'll walk through applying fixed headers and sidebars to your tables with examples.
The Table Data
First, we'll start with creating some table data that we can display on the screen. We'll use a somewhat large amount of data to illustrate the use of a sticky header in just a moment:
<table>
<thead>
<tr>
<th>Artist</th>
<th>Album</th>
<th>Song</th>
<th>Date</th>
</tr>
</thead>
<tbody>
<tr>
<td>B.B. King</td>
<td>Completely Well</td>
<td>The Thrill Is Gone</td>
<td>1969</td>
</tr>
<tr>
<td>Freddie King</td>
<td>Getting Ready... (World)</td>
<td>Going Down</td>
<td>1971</td>
</tr>
<tr>
<td>Allman Brothers Band</td>
<td>The Allman Brothers Band</td>
<td>Trouble No More</td>
<td>1969</td>
</tr>
<tr>
<td>Jimi Hendrix</td>
<td>Are You Experienced</td>
<td>Purple Haze</td>
<td>1967</td>
</tr>
<tr>
<td>Buddy Guy</td>
<td>I Was Walkin' Through The Woods</td>
<td>Stone Crazy</td>
<td>1986</td>
</tr>
</tbody>
</table>
Fixed Table Headers at the Page Level
When creating fixed table headers at the page level, you're ensuring that whenever any part of your table is in the viewport, its header row is also visible to the user.
This is easily accomplished with just a few lines of CSS code:
th {
position: sticky;
position: -webkit-sticky;
top: 0px;
z-index: 2;
}
As you scroll up and down the page, you'll notice the behavior of the table column headers are different as parts of the table start to fall out of view. This ensures that no matter which portion of the data you're looking at, you always have the header indicators to reference and identify each of the columns.
The top
property value of 0px ensures that the table header always remains at the very top of the viewable area, and the z-index
value of 2 ensures that the table header always remains a layer above its data so it's always visible and never covered.
Fixed Row Headers
By default, the web browser will assume that the fixed items in question will the table column headers. Similarly to fixed column headers, you can also create sticky row headers by adding in the scope
selector:
th[scope="row"] {
position: sticky;
position: -webkit-sticky;
left: 0px;
z-index: 2;
}
You'll also need to ensure that your th
tags change from the top table row to only the first column in each row:
<table>
<thead>
<tr>
<th>Artist</th>
<td>Album</td>
<td>Song</td>
<td>Release Date</td>
</tr>
</thead>
<tbody>
<tr>
<th>B.B. King</th>
<td>Completely Well</td>
<td>The Thrill Is Gone</td>
<td>1969</td>
</tr>
<tr>
<th>Freddie King</th>
<td>Getting Ready... (World)</td>
<td>Going Down</td>
<td>1971</td>
</tr>
<tr>
<th>Allman Brothers Band</th>
<td>The Allman Brothers Band</td>
<td>Trouble No More</td>
<td>1969</td>
</tr>
<tr>
<th>Jimi Hendrix</th>
<td>Are You Experienced</td>
<td>Purple Haze</td>
<td>1967</td>
</tr>
<tr>
<th>Buddy Guy</th>
<td>I Was Walkin' Through The Woods</td>
<td>Stone Crazy</td>
<td>1986</td>
</tr>
</tbody>
</table>
Artist | Album | Song | Release Date |
---|---|---|---|
B.B. King | Completely Well | The Thrill Is Gone | 1969 |
Freddie King | Getting Ready... (World) | Going Down | 1971 |
Allman Brothers Band | The Allman Brothers Band | Trouble No More | 1969 |
Jimi Hendrix | Are You Experienced | Purple Haze | 1967 |
Buddy Guy | I Was Walkin' Through The Woods | Stone Crazy | 1986 |
Column headers will do just fine without defining a scope
as they are assumed to be the default.
Other Useful Tidbits
Here is some important information you'll need to remember for cross-browser compatibility:
- Both horizontal and vertical scroll will allow you to better fit tables within a responsive layout. So, if you have super wide tables that look great on desktop but not on mobile, use the above tips to add a horizontal scroll to your table with fixed row headers.
- The
caption
element will not stick in place within a table scroll. As you scroll left to right, it will disappear and reappear. - Firefox is the only known browser at the time of this writing that supports
position: sticky
on thethead
element. For this reason, we are assigning it to theth
elements as a workaround. - Safari on MacOS and iOS requires the use of
-webkit-sticky
for theposition
property. - There is no support for fixed table headers in any version of Internet Explorer. Time to upgrade!
Conclusion
That's it for fixed table headers and responsive tables! It's a very simple hack to get the result you're looking for, but can be highly beneficial to your users in cases where you are displaying large amounts of data.
Make sure to test this feature thoroughly across multiple devices and web browsers to ensure you're getting the display results you need.
Created: April 24, 2021
Comments
There are no comments yet. Start the conversation!