DEV Community

Jamie Mc Manus
Jamie Mc Manus

Posted on • Updated on

Creating a Sticky Table Column

In this article I will show you how to create a sticky column on table scroll.

Alt Text
Image credit C messier

But Why ? 🤔🏛️

This is a question that led the Ancient Greek Philosopher Socrates to his eventual death , some say when he questioned why you would use a non responsive html table in our mobile centric world and then complain that it was not user friendly.
But seriously - sometimes using tables just makes sense, or is unavoidable. On mobile or just smaller screens in general a lot of the information in a table can end up being cut off because of our limited screen width , and scrolling horizontally could make other usefully identifying columns disappear from view leaving us in a bind. One solution is to make the identifying column stick in place on scroll.

What we'll build 👷

Postition:sticky

The key to this solution is using the CSS position:sticky. Applying this to say a div element will make it stick to its parent element. The good news is that this will also work for Table Cells !
( Word to the wise though , position sticky cannot be used on tr & thead elements )

Starting Out

Create a container div element , and within this you can create a good ol' fashioned HTML table with enough columns so that we'll be required to scroll horizontally.
Next we need to limit the width of the table parent to ensure scrolling. We can do this by adding a width and setting the overflow like below:

.films-container{
width:600px;
overflow:auto;
}
Enter fullscreen mode Exit fullscreen mode

This a table that has most of the information cut off.. which is perfect !

The Meat 🍖

We need to create a CSS class with the postion:sticky and the location it is going to stick when scrolling starts and the element gets to. We'll also set the z-index and background-color to ensure that it appears over any of the other elements and remains visible.

.stick-column{
position: -webkit-sticky;
position: sticky;
left: 0;
background: #ffff !important;
z-index:9;
}
Enter fullscreen mode Exit fullscreen mode

Now all we need to do is add this class to every td in the column want to stay in view.

Now that is all well and good but we can go one step further ( or not ) and apply this class when the user clicks on the column header so that column will stay visible. This gives the user the choice , which they always love.

Adding JavaScript

What we need to do is add an on click event to the headers which will let us add ( or remove ) the stick-column css class to all the td in the column.
The easiest way to achieve this is to use a combination of the html cellIndex property of our clicked header and the CSS nth-child selector.
Note that cellIndex starts at 0 , while nth-child starts at 1 , so we'll need to simply + 1 to match these.
We can then get all the td using the above and querySelectorAll. When we have these we can add our class , but first we need to remove the class from any other column that may have it as well because it will interfere with the current one.

function ClickColumn(){
  var index = this.cellIndex

  var selector = 'td:nth-child('+(index+1)+')'
  var cells = document.querySelectorAll(selector);

  // Check if trying to unclick the same column
  // If not then proceed , as we want to be able to unclick the functionality 
  if(!cells[0].classList.contains('stick-column')){
    // Get the Previous Clicked Element and remove Class 
    var previous = document.getElementsByClassName('stick-column');
    while(previous[0]) {
        previous[0].classList.remove('stick-column');
    }
  }

  for(var i = 0 ; i < cells.length ; i++) {
     if(cells[i].classList.contains('stick-column') ){
          cells[i].classList.remove('stick-column');
     }
     else{
         cells[i].classList.add('stick-column');
     }
  }
}
Enter fullscreen mode Exit fullscreen mode

now all thats left is to add this event to the table headers - you can do this inline individually if you wish , or all at once via JavaScript like below

document.querySelectorAll('#film-tbl thead td')
.forEach(e => e.addEventListener("click", ClickColumn )
);
Enter fullscreen mode Exit fullscreen mode

The Finished Product 🏁

And there we have it - click one of the headers and scroll away ! Of course there's plenty of room for improvement - we could allow multiple columns to stick or add some more CSS to highlight the sticky column .. but I'll leave that to you !

So until next time - Arrivederci ! 🎉

And if you're feeling generous you can buy me a coffee with the link below ( and yes its all for coffee, I drink a copius amount of it while writing ☕ )

Buy Me A Coffee

Top comments (2)

Collapse
 
smlombardi profile image
Steve Lombardi

Why make a simple sticky column tutorial so complicated by adding all that "click to make sticky" code?

Collapse
 
jamiemcmanus profile image
Jamie Mc Manus

Hi Steve
It was actually a feature that was requested to me at the time ! Different classes of users wanted to stick different columns that were important to them .