Persistant Headers on Tables

When you scroll down a page with a long table on it, typically the header of the table scrolls away and becomes useless. This code clones the table header and applies it at the top of the page once you have scrolled beyond it, and disappears when you have scrolled past the table.

View Demo

function UpdateTableHeaders() {
   $("div.divTableWithFloatingHeader").each(function() {
       offset = $(this).offset();
       scrollTop = $(window).scrollTop();
       if ((scrollTop > && (scrollTop < + $(this).height())) {
           $(".tableFloatingHeader", this).css("visibility", "visible");
           $(".tableFloatingHeader", this).css("top", Math.min(scrollTop -, $(this).height() - $(".tableFloatingHeader", this).height()) + "px");
       else {
           $(".tableFloatingHeader", this).css("visibility", "hidden");
           $(".tableFloatingHeader", this).css("top", "0px");

$(document).ready(function() {
   $("table.tableWithFloatingHeader").each(function() {
       $(this).wrap("<div class="divTableWithFloatingHeader" style="position:relative"></div>");
       $("tr:first", this).before($("tr:first", this).clone());
       clonedHeaderRow = $("tr:first", this)
       clonedHeaderRow.css("position", "absolute");
       clonedHeaderRow.css("top", "0px");
       clonedHeaderRow.css("left", "0px");
       clonedHeaderRow.css("visibility", "hidden");


  1. User Avatar
    Permalink to comment#

    Nice idea, I think it needs some improvement. It’s rather jumpy.

  2. User Avatar
    Permalink to comment#

    Does not work in IE7, too bad :(

    • User Avatar
      Permalink to comment#

      This works fine in IE7.

    • User Avatar
      Permalink to comment#

      Actually it doesn’t work in IE7 using IE7 Standards…

      (using IE9 — Developer Tools — Browser mode: IE7, Document Mode: IE7 standards)

      It clones the header, but it doesn’t persist it on the page. I am still trying to find a solution for this.

  3. User Avatar
    Laxman Parmar
    Permalink to comment#

    it is something which is i am looking for thank you

    Laxman Parmar

  4. User Avatar
    Sasha Bogdanovic

    The problem comes in of the table is wider than its container and horizontal scroll appears, which is very common in reports.

    In this case, cloned header should be able to scroll horizontally together with the table. So far I didn’t get a proper solution to that problem.

  5. User Avatar
    Permalink to comment#

    Does this work on an iphone ?

    • User Avatar
      Permalink to comment#

      I just took a look on my iphone, it KINDA works, not iphone slick working but still closer than most other people’s attempts i have found online so far

  6. User Avatar
    Permalink to comment#

    Awesome, it’s exactly what I was looking for.
    What should I do if I have a fixed header 200px high and the content starts 200px below? How can I modify the offset for my table headers?

  7. User Avatar
    Forbes Lindesay
    Permalink to comment#

    This is really useful.

  8. User Avatar
    Aishwarya Shiva
    Permalink to comment#

    Nice..this gave an amazing look to my website
    Thanks alot for that :)

  9. User Avatar
    Permalink to comment#

    Very nice.
    Is there a way to persist the header inside a div with auto scroll (overflow:auto;)?
    Thank you.

  10. User Avatar
    Permalink to comment#

    This is fine but when I scroll, the width each column of the header row is changed when comparing with the corresponding content rows… Any idea?

    • User Avatar
      Permalink to comment#

      Got the same problem just no, I’ll see what I can work out…

    • User Avatar
      Permalink to comment#

      I hacked it together for my site:

      originalHeaderRow = $("tr:first", this);
      // original css rules and tuff
      clonedHeaderRow.children().each( function( index ) {
          $(this).append("<div class='widthFix'></div>");
          $(this).css("padding-left", "0");
          $(this).css("padding-right", "0");
          $('.widthFix', this).width( originalHeaderRow.children().get( index ).clientWidth );

      I’m pretty sure it will break very easily on borders or oher thins, but it works for me.

  11. User Avatar
    Permalink to comment#

    Hi, thanks a lot for the script. It works perfectly.
    I have one question.
    In Your script, you clone first TR from table header.
    Can you tell me how to use your code if I have two rows in ?
    Generally your scirpt puts into floating DIV only first row.

    Thanks in advance for help!

Leave a Comment

Posting Code!

You may write comments in Markdown. This makes code easy to post, as you can write inline code like `<div>this</div>` or multiline blocks of code in triple backtick fences (```) with double new lines before and after.

Code of Conduct

Absolutely anyone is welcome to submit a comment here. But not all comments will be posted. Think of it like writing a letter to the editor. All submitted comments will be read, but not all published. Published comments will be on-topic, helpful, and further the discussion or debate.

Want to tell us something privately?

Feel free to use our contact form. That's a great place to let us know about typos or anything off-topic.