Creating a Sticky Table Column
Tags: css, html, webdev, javascript
Published: 2021-07-14 22:16:58

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

<div  style ='font-size:small;float:right; '>
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7gowgz9odbi61h8qc1w0.jpg)
Image credit [C messier](https://commons.wikimedia.org/wiki/File:%CE%A3%CF%89%CE%BA%CF%81%CE%AC%CF%84%CE%B7%CF%82,_%CE%91%CE%BA%CE%B1%CE%B4%CE%B7%CE%BC%CE%AF%CE%B1_%CE%91%CE%B8%CE%B7%CE%BD%CF%8E%CE%BD_6616.jpg)
</div>

##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 👷
{% jsfiddle https://jsfiddle.net/9qzyb2wj/104/ result %}

###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](https://bugs.chromium.org/p/chromium/issues/detail?id=702927#c1) ) 

###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:
```css
.films-container{
width:600px;
overflow:auto;
}
```
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.
```css
.stick-column{
position: -webkit-sticky;
position: sticky;
left: 0;
background: #ffff !important;
z-index:9;
}
```
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](https://www.w3schools.com/jsref/prop_tabledata_cellindex.asp) property of our clicked header and the CSS `nth-child` [selector](https://developer.mozilla.org/en-US/docs/Web/CSS/:nth-child). 
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.

```javascript
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');
     }
  }
}
```

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
```javascript
document.querySelectorAll('#film-tbl thead td')
.forEach(e => e.addEventListener("click", ClickColumn )
);
```
###The Finished Product 🏁
{% jsfiddle https://jsfiddle.net/9qzyb2wj/104/  %}

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](https://cdn.buymeacoffee.com/buttons/default-black.png)](https://www.buymeacoffee.com/SUKaQp9)