This article is more a trick than a tutorial since the solution is very easy and works with just a few lines of code. The point is mostly to demonstrate how it works in the context of an real application layout, and since I could not find a satisfiable solution on the web.
Honesty first : the solution proposed has been inspired by discussions around the excellent Tailwind CSS framework. However, this tutorial isn't meant to be framework dependent. It is pure CSS, but it can surely be implemented using any utility-first CSS framework as Tailwind.
Let's dive in and create a very simple table wrapped in a div. This is really how simple our markup is going to be ! The table wrapper is a container that can be placed anywhere in your page. It may have a fixed height, or be part of a flexbox layout... This wrapper is just going to be scrollable if the table is larger.
The CSS is not very difficult either : once our wrapper is made scrollable, the only thing we have to do is to tell our headers to stick to the top of the wrapper by using sticky positionning. And that's it ! I have added some more optional CSS to make it look cleaner :
The interesting part comes now. You may have noticed the fixed height we've set on the wrapper to make it scrollable. In a real world application, we don't always want this. Instead, it is common to use flexbox (for example) to ensure that the screen height is fully used no matter what the screen size is.
In the following example, we've set a typical application layout with a menu bar and a sidebar. The table is placed on the center part of the screen and should fill it. But we may also want to make sure that some content placed before and after the table remains visible when we scroll the table. This content can be pagination, filters, searchbox, or anything related to the table that we want to see at anytime.
And that's it !