How to add a fixed table header with a vertical scrollbar in content


Update : Now IE9 support modern CSS styles, then you should not use the tip describe here !

 

 

Today I loose my day on a specific IE7 bug:
it doesn’t take in account fixed height and overflow in table structure.

The concept is to use the thead tag (the tfoot tag if needed) for the fixed part and the tbody tag for the scrolling part:

<table>
  <thead>
  </thead>
  <tbody>
  </tbody>
</table>

With firefox 2 you just need this CSS code:

table>tbody {
  overflow: auto;
  height: 280px;
  overflow-x: hidden;
}

Simplicty, efficacity.

With IE7 you need to cheat and to add an extra div tag which support the overfllow rule. The div tag height must large enough to contain the table: thead height + tbody forced height.

<div class="tableContainer">
  <table>
    <thead>
    </thead>
    <tbody>
    </tbody>
  </table>
</div>

The CSS rules are now more complex:

div.tableContainer {
  width: 90%;       /* table width will be 99% of this*/
  height: 320px;    /* must be greater than tbody*/
  overflow: auto;
  margin: 0 auto;
}

table {
  width: 97%;  /*100% of container produces horiz. scroll in Mozilla*/
  border: none;
  border-spacing: 0px;
  background-color: transparent;
}

table>tbody {
  overflow: auto;
  height: 280px;
  overflow-x: hidden;
}

With that code every tr tag height is set to 280px on IE7, we need an extra rule:

table>tbody tr {
  height: auto;
}

But the thead is always glue with the tbody. We need to make it relative:

table>thead tr {
  position:relative;
  top: 0px;/*expression(offsetParent.scrollTop); IE5+ only*/
}

This is the fifth implementation of the day to fix this bug. I don’t know how to thanks Microsoft to make me earn money on customers. With Internet Explorer I don’t need to buy a Wii the improve my mind.

16 Responses to How to add a fixed table header with a vertical scrollbar in content

  1. matt dit :

    I build exactly what you show here, and i get no fixed header in Firefox. Do you have some actual working code i might see for references?

  2. encolpe dit :

    matt> My best source was http://home.tampabay.rr.com/bmerkey/examples/nonscroll-table-header.html

    You can name your table if it doesn’t work:

    <div class= »tableContainer »>
    <table id= »table-prets-titles » cellspacing= »0″ cellpadding= »0″>
    <thead class= »fixedHeader »>
    <tr>
    <th class= »tableFixedLeftCorner »>Type</th>
    <th class= »tableFixedNormal »>Title</th>
    <th class= »tableFixedRightCorner »> </th>
    </tr>
    </thead>

    <tbody class= »scrollContent »>
    </tbody>
    </table>

    table#table-prets-titles {
    width: 97%; /*100% of container produces horiz. scroll in Mozilla*/
    border: none;
    border-spacing: 0px;
    background-color: transparent;
    }

    table#table-prets-titles>tbody { /* IE7 ‘n FF2 */
    overflow: auto;
    height: 280px;
    overflow-x: hidden;
    }

    * table#table-prets-titles tbody { /* IE6 */
    overflow: auto;
    height: 280px;
    overflow-x: hidden;
    }

    table#table-prets-titles>thead tr { /* IE7 ‘n FF2 */
    position:relative;
    top: 0px;
    }

    * table#table-prets-titles thead tr { /* IE6 */
    position:relative;
    top: 0px;
    }

  3. matt dit :

    Thanks Enc

    Sadly, it fails in Safari/windows. The header scrolls up. Trying to figure out why. Any hunches?

    This would be perfect if i could solve for that

  4. encolpe dit :

    If the source example works on your browsers, you should remove all extra styles. It take me one day before to have something stable.

  5. glenn dit :

    Yes, I have the same issue. Would love for this to work on Safari/windows.

  6. cry dit :

    just try in FF3 with very few TR in the TBODY, and cry.

  7. tkempken dit :

    hi all

    i’ve found a working solution for FF3.

    1. Add ID to Tag

    2. Put these snipplet at the end of your page:

    var tbody=document.getElementById(‘myTableBody’);
    if(tbody.scrollHeight<=280) tbody.style.height= »auto »;

    It will check the scroll height and then change height to auto or not.
    It is a great workaround !

    thanks and happy new year!

    regards

  8. tkempken dit :

    oh there is lost something… (remove spaces)

    1. Add ID to Tag

    2. Put these snipplet at the end of your page:

    var tbody=document.getElementById(‘myTableBody’);
    if(tbody.scrollHeight<=280) tbody.style.height= »auto »;

  9. David dit :

    I had issues using the same source code encolpe used and discovered it was a DOCTYPE problem. If you’re having trouble, might want to look there.

  10. Maik dit :

    Hi

    thanks for your code but this one wont work in IE7:

    div.tableContainer { width: 90%; /* table width will be 99% of this*/ height: 320px; /* must be greater than tbody*/ overflow: auto; margin: 0 auto; }
    table { width: 97%; /*100% of container produces horiz. scroll in Mozilla*/ border: none; border-spacing: 0px; background-color: transparent; } table>tbody { overflow: auto; height: 280px; overflow-x: hidden; }
    table>tbody tr {
    height: auto;
    }
    table>thead tr {
    position:relative;
    top: 0px;/*expression(offsetParent.scrollTop); IE5+ only*/
    }

    H1H2

    L1H2
    L1H2
    L1H2
    L1H2
    L1H2

    Any Idea?

    • encolpe dit :

      This entry is just there to show the way. It should work on simple tables without extra style and I put no warranty on it if you add extra style in them.

  11. Mani dit :

    table {
    border: solid #66CC99;
    border-width: 0px 1px 1px 0px;
    width: 400px;
    }
    th, td {
    border: solid #66CC99;
    border-width: 1px 0px 0px 1px;
    padding: 4px;
    }
    th {
    background-color: #339999;
    color: #FFFFFF;
    }
    tr.alt td {
    background-color: #EEEEEE;
    }
    tbody {
    height: 200px;
    overflow-y: auto;
    overflow-x: hidden;
    }

    div {
    position: relative;
    height: 200px;
    width: 416px;
    overflow-y: scroll;
    overflow-x: hidden;
    border: solid #66CC99;
    border-width: 0px 0px 1px 0px;
    }
    table {
    border-width: 1px 1px 0px 0px;
    }
    thead tr {
    position: absolute;
    top: expression(this.offsetParent.scrollTop);
    }
    tbody {
    height: auto;
    }
    table tbody tr:first-child td {
    padding: 29px 4px 4px 4px;
    }

    HTML:

    HEADER 1
    HEADER 2
    HEADER 3
    HEADER 4

    content 1
    content
    content
    content

    content 2
    content
    content
    content

    content 3
    content
    content
    content

    content 4
    content
    content
    content

    content 5
    content
    content
    content

    content 6
    content
    content
    content

    content 7
    content
    content
    content

    content 8
    content
    content
    content

    content 9
    content
    content
    content

    content 10
    content
    content
    content

    content 11
    content
    content
    content

    content 12
    content
    content
    content

    content 13
    content
    content
    content

    content 14
    content
    content
    content

  12. Mani dit :

    table {
    border: solid #66CC99;
    border-width: 0px 1px 1px 0px;
    width: 400px;
    }
    th, td {
    border: solid #66CC99;
    border-width: 1px 0px 0px 1px;
    padding: 4px;
    }
    th {
    background-color: #339999;
    color: #FFFFFF;
    }
    tr.alt td {
    background-color: #EEEEEE;
    }
    tbody {
    height: 200px;
    overflow-y: auto;
    overflow-x: hidden;
    }

    div {
    position: relative;
    height: 200px;
    width: 416px;
    overflow-y: scroll;
    overflow-x: hidden;
    border: solid #66CC99;
    border-width: 0px 0px 1px 0px;
    }
    table {
    border-width: 1px 1px 0px 0px;
    }
    thead tr {
    position: absolute;
    top: expression(this.offsetParent.scrollTop);
    }
    tbody {
    height: auto;
    }
    table tbody tr:first-child td {
    padding: 29px 4px 4px 4px;
    }

    « HTML:

    HEADER 1
    HEADER 2
    HEADER 3
    HEADER 4

    content 1
    content
    content
    content

    content 2
    content
    content
    content

    content 3
    content
    content
    content

    content 4
    content
    content
    content

    content 5
    content
    content
    content

    content 6
    content
    content
    content

    content 7
    content
    content
    content

    content 8
    content
    content
    content

    content 9
    content
    content
    content

    content 10
    content
    content
    content

    content 11
    content
    content
    content

    content 12
    content
    content
    content

    content 13
    content
    content
    content

    content 14
    content
    content
    content

    « 

  13. Shailesh dit :

    The Last solution doesn’t work in FF 3.5

  14. encolpe dit :

    It is amazing how a not plone related article can be read and used years after its creation.
    The main idea was to deal with IE7 and Firefox 2 only.

  15. Mark Malek dit :

    I’ve had a really tough time at work building proper tables that have a fixed header and scrolling tbody that work in IE6, IE7, IE8, FF and Safari. We display lots of data both rows and columns.

    My solution for all this was spending about two weeks to write my own jQuery plugin. It does everything you need it to and very easily. To use it all you need to do is setup a table using valid HTML. (table tag, thead, tbody, etc) and the plugin will set up the table for you so that your header is fixed. There is also the optional fixed footer that can either be a clone of the header or something entirely different.

    you can check it out here: http://fixedheadertable.mmalek.com

    hope this helps any of you that have had the same issue! I’ve been finding that its a very common issue and there aren’t that many good working solutions. I tried RicoLive Grid but that was a disaster!

%d blogueurs aiment cette page :