How to create sticky table headers using jQuery – jquery sticky plugin

Welcome those big, sticky, complicated problems. In them are your most powerful opportunities.
-Ralph Marston

 

Update: I ve converted this function into a jQuery plugin and put up a demo for it. If you d like to improve this plugin then you can clone it from github.

Here s a nice way to use jQuery and make table headers sticky when a page is scrolled down and the table headers reach the top. This is a feature in the new look that Google is sporting, in Google documents, Gmail etc. Obviously Google is not using jQuery to accomplish this and they are probably using some fancy code to do it. This is just a quick way to get it working on table headers.. <th> elements. In this setup we calculate the distance of the table from the top, check if it reaches 0 while scrolling and apply the CSS property position:fixed to it. If it falls back under the distance it had, then we revert the position to normal.

Pass in the table’s id to the function that follows it. For example if you have a table that had an id = “my_table”, then pass this in the document.ready function:

$(document).ready(function(){
    makeTableHeadersSticky("#my_table");
});

function makeTableHeadersSticky(tableId)
{
    //collect widths of all the th elements
    var thArr = $(tableId + " th");
    //create an array to hold the auto calculated widths of each element
    var thWidthsArr = [];
    $(tableId + " th").each(function(){
        thWidthsArr.push($(this).css("width"));
    });
    var pos = $(tableId).offset();
    //set the distance of the table from the top,
    //we ll need to make the headers sticky when this distance is 0  
    var thTop = pos.top + "px";
    //set the widths of the first and last tr's ths/tds...
    //this is done coz in some cases,
    //the widths will get messed up if the data was generated dynamically
    var count = 0;
    $(tableId + " tr:first-child>th").each(function(){
        $(this).css("width", thWidthsArr[count]);
        count++;
    });
    count = 0;
    $(tableId + " tr:last-child>td").each(function(){
        $(this).css("width", thWidthsArr[count]);
        count++;
    });
    $(window).scroll(function(){
        if($(window).scrollTop() > pos.top)
        {
            $(tableId + " tr:first-child").css("position", "fixed");
            $(tableId + " tr:first-child").css("top", "0px");
        }
        else
        {
            $(tableId + " tr:first-child").css("position", "relative");
            $(tableId + " tr:first-child").css("top", thTop);
        }
    });
}

Categories: How To, jQuery, Tips | 4 comments

Comments (4)

  1. This is exactly what I was hoping to find. Thanks for the code and it works perfectly.

  2. it does not work in ie7..

    • Well I m gonna have to take a look at it as soon as I can get hold of a windows machine, in the mean time, the plugin is on Github… consider improving it?

  3. Pingback: 20 jQuery Plugins and Tutorials for Sticky Layer or Table Header | Witty Sparks

Leave a Reply

Required fields are marked *

*