Treehouse: Grow your CSS skills. Land your dream job.

Last updated on:

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 > offset.top) && (scrollTop < offset.top + $(this).height())) {
           $(".tableFloatingHeader", this).css("visibility", "visible");
           $(".tableFloatingHeader", this).css("top", Math.min(scrollTop - offset.top, $(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.addClass("tableFloatingHeader");
       clonedHeaderRow.css("position", "absolute");
       clonedHeaderRow.css("top", "0px");
       clonedHeaderRow.css("left", "0px");
       clonedHeaderRow.css("visibility", "hidden");
   });
   UpdateTableHeaders();
   $(window).scroll(UpdateTableHeaders);
});

Reference URL

Comments

  1. Ben
    Permalink to comment#

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

  2. Fred
    Permalink to comment#

    Does not work in IE7, too bad :(

    • Edgar
      Permalink to comment#

      This works fine in IE7.

    • Max
      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. Laxman Parmar
    Permalink to comment#

    it is something which is i am looking for thank you

    Laxman Parmar

  4. 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. Manjit
    Permalink to comment#

    Does this work on an iphone ?

    • Mike
      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. David
    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?
    Thanks

  7. Forbes Lindesay
    Permalink to comment#

    This is really useful.

  8. Aishwarya Shiva
    Permalink to comment#

    Nice..this gave an amazing look to my website http://www.wrangle.in
    Thanks alot for that :)

  9. Fabrizio
    Permalink to comment#

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

  10. Aravind
    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?

    • Kjeld
      Permalink to comment#

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

    • Kjeld
      Permalink to comment#

      I hacked it together for my site:

      originalHeaderRow = $("tr:first", this);
      originalHeaderRow.before(originalHeaderRow.clone());
      
      // 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. krajesiu
    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!
    Kris

Leave a Comment

Posting Code

We highly encourage you to post problematic HTML/CSS/JavaScript over on CodePen and include the link in your post. It's much easier to see, understand, and help with when you do that.

Markdown is supported, so you can write inline code like `<div>this</div>` or multiline blocks of code in in triple backtick fences like this:

```
<script>
  function example() {
    element.innerHTML = "<div>code</div>";
  }
</script>
```