Scrollable Tables with Floating Header using CSS
Development Resource Project
Book Review: How to Implement Design Patterns in PHP
Using PHP pspell Spell Check Functions with a Custom Dictionary
JQuery Venetian Blinds Transition Effect
Installing Xdebug for use with Eclipse or Netbeans on Linux

Scrollable Tables with Floating Header using CSS

Saturday, 10 December 16, 12:31 pm
The secret here is to contain your table's rows in <thead> and <tbody> sections, and set these to display:block. Click Activate Demo to view the scrollable table:
<table class="scrollable"> <thead> <tr> <th> Name </th> <th> Species </th> </tr> </thead> <tbody> <tr> <td> Jane </td> <td> Lemur </td> </tr> <tr> <td> Mike </td> <td> Hamster </td> </tr> <tr> <td> Marcus </td> <td> Hippopotamus </td> </tr> <tr> <td> Naomi </td> <td> Badger </td> </tr> <tr> <td> Chris </td> <td> Racoon </td> </tr> <tr> <td> Mark </td> <td> Ferret </td> </tr> <tr> <td> Agata </td> <td> Bush baby </td> </tr> <tr> <td> Adrian </td> <td> Anaconda </td> </tr> <tr> <td> Natalie </td> <td> Raven </td> </tr> <tr> <td> Adam </td> <td> Gecko </td> </tr> <tr> <td> Reuben </td> <td> Llama </td> </tr> <tr> <td> Josephine </td> <td> Rabbit </td> </tr> <tr> <td> Melissa </td> <td> Goat </td> </tr> <tr> <td> Jo </td> <td> Iguana </td> </tr> <tr> <td> Tim </td> <td> Lynx </td> </tr> <tr> <td> Dave </td> <td> Baboon </td> </tr> </tbody> </table>
Name Species
Jane Lemur
Mike Hamster
Marcus Hippopotamus
Naomi Badger
Chris Racoon
Mark Ferret
Agata Bush baby
Adrian Anaconda
Natalie Raven
Adam Gecko
Reuben Llama
Josephine Rabbit
Melissa Goat
Jo Iguana
Tim Lynx
Dave Baboon
Here's the style rules. Only the thead and tbody rules are relevant for the scrolling effect. As well as both needing display:block, we also need height and overflow rules for the tbody:
<style> table.scrollable thead { display: block; } table.scrollable tbody { display: block; height: 200px; overflow-y: auto; overflow-x: hidden; } table.scrollable { border-spacing: 0; } table.scrollable td, table.scrollable th { border-bottom: 1px solid #ccc; padding: 2px 4px; } table.scrollable th { background: #f2f2f2; border-bottom: 1px solid #aaa; border-top: 1px solid #aaa; font-family: Roboto; font-weight: normal; text-align: center; padding: 8px 4px; text-transform: uppercase; } table.scrollable td:last-child, table.scrollable th:last-child { padding-right: 20px; } </style>
Note the last rule above, which gives right padding to the last <td> and <th> elements of every row. This is to allow space for the scrollbar, which otherwise would appear over the cell contents.

Now, because <thead> and <tbody> are both display:block, the headers would not normally align above the corresponding columns. If your content can be displayed using fixed width columns, you just need to set the same width for each <td> and its corresponding <th> and you're done.

For dynamic width columns however, I'm not aware of a way to make this happen via CSS alone, and instead I use some JQuery to set each header's width to match the column:
<script type="text/javascript"> $(document).ready( function() { // On this page, the table is inside a div that initially has display:none so we have to clear that or we can't get the width $('div.execode').css('display', '');   // Set each header to width of corresponding td $('table.scrollable tr th').each(function (idx, ele) { $(ele).width($('table.scrollable tr td').eq(idx).width()); });   // Restore the div's display:none style $('div.execode').css('display', 'none'); }); </script>

Please enter your comment in the box below. Comments will be moderated before going live. Thanks for your feedback!

Cancel Post

/xkcd/ METAR