Table with a fixed first column
On many web projects, we need to display tabular data. We don’t need a fancy library to deal with tables most of the time. When the amount of data is small, features such as virtualization are over-skilled. Regular HTML tables can do the job. But it does not mean that we cannot add handy features such as a fixed first column. Let’s start with a basic HTML table.
DATA1 DATA2 DATA3 DATA4 Some values Some values Some values Some values Other values Other values Other values Other values Other values Other values Other values Other values Other values Other values Other values Other values
With some styling, we end up with the following UI.
When horizontal scrolling is required, we want a fixed first column. Let’s see how to implement this feature in CSS. First, we need to use overflow-x:auto to make the scrollbar appears when necessary.
Sadly, setting this property directly to the table element seems to have no effect.
According to the CSS specifications, overflow properties only apply to block, flex, and grid containers. We could change the display property of the table. But, semantically, it’s a table, not a block. Therefore, I prefer to use a wrapper element.
class="container"> DATA1 DATA2 DATA3 DATA4 Some values Some values Some values Some values
.container overflow-x: auto; >
When we scroll horizontally, the first column should «stick» the left edge of the table. This is where sticky positioning comes to into play.
The idea about sticky positioning is that as you scroll, an element can «stick» to the edge.
Here’s what the CSS code would be like:
tr>th:first-child,tr>td:first-child position: sticky; left: 0; >
The tr>th:first-child,tr>td:first-child selector only applies sticky positioning to the first column cells.
This solution seems pretty good. But, not so fast! With that, you’ll get the following side effect:
The first column is sticky (and it works), but we can still see the content of other columns (under our first column) while we scroll.
To understand this issue, let’s have a look at our background definition:
tr:nth-child(odd) background: $white; > tr:nth-child(even) background: $gray-200; >
The background property is defined at the row level. It means that the cell has no background. However, we want the first column cells to have a background. So it hides other cells when we scroll.
We end up with this CSS:
tr:nth-child(odd) td background: $white; > tr:nth-child(even) td background: $gray-200; >
.container overflow-x: auto; > tr>th:first-child,tr>td:first-child position: sticky; left: 0; > tr:nth-child(odd) td background: $white; > tr:nth-child(even) td background: $gray-200; >
And really that’s it.
You can find the source code here.
How to Create an HTML Table with a Fixed Left Column and Scrollable Body
It is possible to create a table, which has a fixed left column and a scrollable body. For that, you’ll need to use some CSS. You can use the position property set to “absolute” for the first column and specify its width. Then use the overflow-x property set to “scroll” for the entire table.
In this snippet, we’ll show all the needed steps. Let’s start with creating HTML.
Create HTML
div> table> tr> th class="headcol">1 th> td class="long">LOREM IPSUM LOREM IPSUM td> td class="long">LOREM IPSUM LOREM IPSUM td> tr> tr> th class="headcol">2 th> td class="long">LOREM IPSUM LOREM IPSUM td> td class="long">LOREM IPSUM LOREM IPSUM td> tr> tr> th class="headcol">3 th> td class="long">LOREM IPSUM LOREM IPSUM td> td class="long">LOREM IPSUM LOREM IPSUM td> tr> tr> th class="headcol">4 th> td class="long">LOREM IPSUM LOREM IPSUM td> td class="long">LOREM IPSUM LOREM IPSUM td> tr> tr> th class="headcol">5 th> td class="long">LOREM IPSUM LOREM IPSUM td> td class="long">LOREM IPSUM LOREM IPSUM td> tr> tr> th class="headcol">6 th> td class="long">LOREM IPSUM LOREM IPSUM td> td class="long">LOREM IPSUM LOREM IPSUM td> tr> table> div>
Add CSS
table < border-collapse: separate; border-spacing: 0; border-top: 1px solid #000; > td, th < margin: 0; border: 1px solid #000; white-space: nowrap; border-top-width: 0px; > div < width: 450px; overflow-x: scroll; margin-left: 5em; overflow-y: visible; padding: 0; > .headcol < position: absolute; width: 5em; left: 0; top: auto; border-top-width: 2px; margin-top: -1px; > .headcol:before < content: 'Row '; > .long < background: #8cdba3; letter-spacing: 1em; >
Example of creating a table with a fixed left column and scrollable body:
html> html> head> title>Title of the document title> style> table < border-collapse: separate; border-spacing: 0; border-top: 1px solid #000; > td, th < margin: 0; border: 1px solid #000; white-space: nowrap; border-top-width: 0px; > div < width: 450px; overflow-x: scroll; margin-left: 5em; overflow-y: visible; padding: 0; > .headcol < position: absolute; width: 5em; left: 0; top: auto; border-top-width: 2px; margin-top: -1px; > .headcol:before < content: 'Row '; > .long < background: #8cdba3; letter-spacing: 1em; > style> head> body> div> table> tr> th class="headcol">1 th> td class="long">LOREM IPSUM LOREM IPSUM td> td class="long">LOREM IPSUM LOREM IPSUM td> tr> tr> th class="headcol">2 th> td class="long">LOREM IPSUM LOREM IPSUM td> td class="long">LOREM IPSUM LOREM IPSUM td> tr> tr> th class="headcol">3 th> td class="long">LOREM IPSUM LOREM IPSUM td> td class="long">LOREM IPSUM LOREM IPSUM td> tr> tr> th class="headcol">4 th> td class="long">LOREM IPSUM LOREM IPSUM td> td class="long">LOREM IPSUM LOREM IPSUM td> tr> tr> th class="headcol">5 th> td class="long">LOREM IPSUM LOREM IPSUM td> td class="long">LOREM IPSUM LOREM IPSUM td> tr> tr> th class="headcol">6 th> td class="long">LOREM IPSUM LOREM IPSUM td> td class="long">LOREM IPSUM LOREM IPSUM td> tr> table> div> body> html>
Result
1 | LOREM IPSUM LOREM IPSUM | LOREM IPSUM LOREM IPSUM |
---|---|---|
2 | LOREM IPSUM LOREM IPSUM | LOREM IPSUM LOREM IPSUM |
3 | LOREM IPSUM LOREM IPSUM | LOREM IPSUM LOREM IPSUM |
4 | LOREM IPSUM LOREM IPSUM | LOREM IPSUM LOREM IPSUM |
5 | LOREM IPSUM LOREM IPSUM | LOREM IPSUM LOREM IPSUM |
6 | LOREM IPSUM LOREM IPSUM | LOREM IPSUM LOREM IPSUM |