Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HTML table fixed header with max column widths and padding using jQuery

I have a HTML table with a header that I am locking to the top of my browser with jQuery once the user has scrolled down past it. I've seen a lot of solutions to this particular problem on SO and elsewhere, but cannot get past a roadblock I've hit.

I have been able to get my jQuery to lock the header fine (I have a < tr > within my < thead > containing my column headers, and I've given that < tr > an ID of "theadTrId").

$(document).ready(function () {
   var widths = new Array();

   //create array of <th> widths
   var i = 0;
   $('th').each(function () {
       widths[i] = $(this).width();
       i++;
   });

   var elementPosTop = $('#theadTrId').offset().top;
   $(window).scroll(function () {
       SetWidths();
   });

   var SetWidths = function () {
       var wintop = $(window).scrollTop();

       if (wintop > elementPosTop) {
           $('#theadTrId').css({ "position": "fixed", "top": "0" });

           //<th> and <td> widths in 1st column
           $('#th1').width(widths[0]);
           $('#td1').width(widths[0]);

           //<th> and <td> widths in 2nd column
           $('#th2').width(widths[1]);
           $('#td2').width(widths[1]);

           //x number of other columns with same logic...
       } else {
           $('#theadTrId').css({ "position": "inherit" });
       }
   };
});

This works fine and locks the header to the top of the window when scrolling down and puts it back to default when scrolling back up, but for the life of me I cannot get the < th > and < td > column widths to line up when the following CSS is added:

td {
    max-width: 200px;
}
td, th {
    padding: 10px;
}

Should I remove that styling, all headers and their columns line up perfectly. This styling is required and cannot be removed. Table width also needs to be set at 100%. Any suggestions?

jsFiddle here (you can see desired behavior if you delete the last 2 CSS properties, issue is most pronounced in Firefox): http://jsfiddle.net/aKe6j/59/

like image 445
Citrus Avatar asked Sep 25 '26 08:09

Citrus


1 Answers

Try this (the fiddle), I think it can be the solution:

    <style>
    table {
        width: 100%;
    }
    td {
        background-color: #BCE6E6;    
    }
    #theadTrId {
        background-color: #6699FF;
    }
    #th1 {
        width: 110px;
    }
    #th2 {
        width: 235px;
    }
    #th3 {
        width: 80px;
    }
    td {
        max-width: 200px;
    }
    td, th {
        padding: 10px;
    }

    </style>
    </head>
    <table border="1">
        <thead>
            <tr id="theadTrId">
                <th id="th1">Column 1</th>
                <th id="th2">Column 2</th>
                <th id="th3">Column 3</th>
            </tr>
        </thead>

        <tbody id="tbody">

        </tbody>
    </table>
    <script>
    //loop to add 40 rows
for (var i=0;i < 41; i++)
{ 
    var jj = 1;
    $("#tbody").append("<tr><td id='td"+(jj++)+"'>Content " + i + "</td><td id='td"+(jj++)+"'>Content " + i + "</td><td id='td"+(jj++)+"'>Content " + i + "</td></tr>")
}

var widths = new Array();
//create array of <th> widths
var i = 0;
$('th').each(function () {
    widths[i] = $(this).context.offsetWidth;

    i++;
});

var elementPosTop = $('#theadTrId').offset().top;
$(window).scroll(function () {
    SetWidths();
});

var SetWidths = function () {
       var wintop = $(window).scrollTop();

       if (wintop > elementPosTop) {
           $('#theadTrId').css({ "position": "fixed", "top": "0" });
           //use the css rulz to change also the max-width for that particular td
           //it can be rolled back afther
           //<th> and <td> widths in 1st column
           $('#th1').css('width',widths[0]);
           $('#td1').css('width',widths[0]);
           $('#td1').css('max-width',widths[0]);
           //<th> and <td> widths in 2nd column
           $('#th2').css('width',widths[1]);
           $('#td2').css('width',widths[1]);
           $('#td2').css('max-width',widths[1]);
           //<th> and <td> widths in 3rd column
           $('#th3').css('width',widths[2]);
           $('#td3').css('width',widths[2]);
           $('#td3').css('max-width',widths[2]);

       } else {
           $('#theadTrId').css({ "position": "inherit" });
           // if you need the max-width again 
           $('#td0').css('max-width',200);
           $('#td1').css('max-width',200);
           $('#td2').css('max-width',200);
       }
   };
    </script>
like image 108
Alessandro Gabrielli Avatar answered Sep 27 '26 00:09

Alessandro Gabrielli



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!