egidiocs egidiocs - 8 months ago 59
jQuery Question

Fix thead on page scroll

A page with a table with several rows.
I want to fix thead when thead reach the top of the page when scrolling, using jquery or any given scripting.
I don't want to overflow the table itself.

Answer Source

You can use Lobstrosity's code with a slight modification: position: fixed instead of absolute.

position: fixed is now widely adopted by all browsers including IE8 and onwards. BTW fixed renders much nicer on mobile/tablet devices than position: absolute.

I found that on a table with dynamic widths for each column, the absolutely positioned <thead> would lose the widths of the rest of the columns, so to fix this I came up with the following code:

What this code does is as follows:

Determines the widths of each column in your table by looking up the CSS widths of the first <tbody> <tr> <td> row and storing these in an array for later. When the user scrolls the class 'fixed' is added to the <thead> (Default browser behaviour will alter the widths of the <th>'s and they won't match up with the <tbody>. So to fix this we retroactively set the widths of the <th> to the values we've read earlier.

Anyway here's the code:


table.entries {width: 100%;border-spacing: 0px;margin:0;}
table.entries thead.fixed {position:fixed;top:0;}


<table class="entries" id="entriestable">
            <td class="name">Ricky Bobby</td>
            <td class="addy"><i>Kent, GB</i></td>
            <td class="dob">20/08/1984</td>
            <td class="date">4 hours ago</td>


TableThing = function(params) {
    settings = {
        table: $('#entriestable'),
        thead: []

    this.fixThead = function() {
        // empty our array to begin with
        settings.thead = [];
        // loop over the first row of td's in &lt;tbody> and get the widths of individual &lt;td>'s
        $('tbody tr:eq(1) td', settings.table).each( function(i,v){

        // now loop over our array setting the widths we've got to the &lt;th>'s
        for(i=0;i<settings.thead.length;i++) {
            $('thead th:eq('+i+')', settings.table).width(settings.thead[i]);

        // here we attach to the scroll, adding the class 'fixed' to the &lt;thead> 
        $(window).scroll(function() {
            var windowTop = $(window).scrollTop();

            if (windowTop > settings.table.offset().top) {
                $("thead", settings.table).addClass("fixed");
            else {
                $("thead", settings.table).removeClass("fixed");
    var table = new TableThing();