Freeze panes at top of table like Excel

software development


I have this php script that displays data retrieved from a mysql table in a html table. Now the customer asks if it would be possible, when the user retrieves more than one page of data to “freeze the header row on top of the table like in Excel”. Well, it’s not possible for me. But for a real web programmer it might be. Is there a way?

This signature line intentionally blank.


I’ll preface my response by saying that I don’t remember flat off the top of my head how to do this, but I do know that it’s possible. The key is to take advantage of the fact that tables can be divided into sections and that you can use CSS to make each section behave in a particular way. The three sections that you can divide a table into are called thead, tbody, and tfoot.

To get the headers to stick at the top, the first thing you will want to do is to put the grey boxes into a and put everything else into

. Then, using CSS, I believe you can use the height property to limit the size of tbody and then use overflow:scroll to add a scroll bar so that your customer can see all of his data.

While you’re at it, I would also recommend putting the blue total boxes at the bottom into a because then you can make sure they always show up as well. Your customer, then, would always be able to see the headers, always be able to see the totals, and is free to scroll through the data.

Unfortunately, any more detail than that is more than I can conjure up from the depths of my brain at the moment. Hopefully that at least gives you a starting direction. If you still need more help, feel free to ask and I’ll see if I can find any other resources to explain what I’m talking about a bit more.


I read up on thead, tbody, and tfoot, but I can’t get them to work in my table. I must be missing the style setting that makes the header stay at the top of the page. I couldn’t find anything on that.

I got a frames version to work. I wanted to avoid frames, and it’s tricky to get the header columns to line up with the body columns:

This signature line intentionally blank.


Try this awesome version out.

Max discount on any plan with promocode SCJESSEYTOTAL


That, actually, is very nice! :slight_smile:



Aha! That’s exactly the page I was thinking of when I was describing the trick in my post above. Or, well, it would have been, if I’d remembered it at the time. It is where I learned that trick from :slight_smile:


Wow, that is so cool. I had no idea you could do so much with styles.

I guess what I need to do is grab from the view source window of my browser everything after /*end basic styling, stick it in my page source between style tags, then edit my thead and tbody blocks to use the appropriate class.

Hey, when you get to this many lines when writing a reply in this forum you suddenly get a scroll bar on the right of the field. Is this the same kind of css trick except it somehow counts lines?

One and only one online html reference said that you had to use thead, tfoot, and tbody and they had to be in this order, but that doesn’t seem to be the case. This one:

This signature line intentionally blank.


Nope … that’s just the normal behavior of a text area field in a form that has attributes set to a given number of lines … when that number is exceeded, the form field does not grow but shows a scroll bar instead. :wink:



While it’s true that browsers are unlikely to enforce this restriction, the order of thead, tfoot, and tbody is a mandatory part of the HTML standard and your pages will not validate unless the correct ordering is observed. Of course, this is true of a lot of things in web development, where a web browser is a lot more permissive of mistakes than the standard dictates. The reason is that, at the end of the day, standards exist to say what is correct and browsers exist to display any webpage they see in a way that makes sense to the user, and since even today a lot of pages are not written correctly according to the standard, browsers need to allow some flexibility.

I would, however, encourage you to write your table in the way that the standard dictates: thead, tfoot, tbody. It may not seem like it matters much now, but I can say from personal experience that not paying attention to the little things can make a real mess further down the line.


Well, I often do that. You will need to use Javascript and CSS.

How it works is that we will put tables to different layers and use javascript to control which layer to display. Let me try to explain. I hope I won’t confuse you.

For example: There are 3 tabs in your top freeze head. “Tab 1”, “Tab 2”, “Tab 3”.

If you click on “Tab 1”, you will see “Table 1” and vice versa.

So what you will need to do:

  1. for the tab. Usually I put tabs in a table so that I can use onMouseOver, onMouseOut behaviors.
Tab 1
  1. put the tables into different layers
Table 1
  1. complete javascript functions.

function openTab(args){
for(i=1; i<=3; i++){
if (i==args) document.getElementByID(“menuContent”+i).style.display = “block”;
else document.getElementByID(“menuContent”+i).style.display = “none”;

Now, if you click on Tab 1, you will display Table 1. If you click on Tab 2, you will display Table 2.

These are not complete codes but to give you a guide line. You can view source and copy complete codes from

$50 off and 3 free domains with code: [color=#CC0000]DH3[/color] Sign Up NOW or More Codes Here


That looks cool in Firefox… but am I the only one that sees it like this in IE7?

I only ever use Firefox, but wanted to see if that was something that IE would wreck.

:stuck_out_tongue: Maximum savings promo code: MaxSavingsAtDH


Yeah that’s what I see on IE7 too.

$50 Discount 1LUCID50 Sign up now


[quote]That looks cool in Firefox… but am I the only one that sees it like this in IE7?

I only ever use Firefox, but wanted to see if that was something that IE would wreck.[/quote]
No you are not the only one … ya gotta “love” good ole IE (not!) :frowning:



Well, two more reports proves it’s not just me. :stuck_out_tongue:

Unfortunately, when something breaks that badly, it either doesn’t make sense to use it… or you need to add some browser sniffing that triggers a Plan B.

That type of breakage makes it look like you installed a site template and forgot to add your content. It needs to at least “break” into a normal table, without the pane freezing effect, but still retaining the content.

If that can’t be straightened out, then it would probably make more sense to use a floating DIV that returns to the top when the page is scrolled (like some sites do with their menus.

Those can probably break as well, but I think it would do so more gracefully, if no backup plan is in place.

I think if you’re not going to thoroughly test it and work out the bugs, it’s probably just best to just repeat the header every so many rows.

That can easily be done with a loop, if generating the table dynamically, where you just count the rows as you write them.

:stuck_out_tongue: Maximum savings promo code: MaxSavingsAtDH


How about this java demo:

Great, more scripting languages to learn! In the last couple of years I’ve been confusing myself by trying to learn VB, Perl, PHP, and Python simultaneously. Now I have to take on CSS, Java and Javascript. Meanwhile, my expertise in Primos and Henco Info becomes less and less marketable.

This signature line intentionally blank.


I’ve prepared a Gecko-friendly proof of concept that is simple to follow, but it won’t work on IE without a festival of hackery.

Max discount on any plan with promocode SCJESSEYTOTAL


At least that “breaks” in IE7 as a normal table, rather than losing all the data like the other one.

I guess if generating it dynamically, you could always check for IE7 and repeat the header every 10 rows, or something similar.

Edit: The other downside of breaking is that when it breaks in IE, it breaks for most people.

:stuck_out_tongue: Maximum savings promo code: MaxSavingsAtDH


What’s weird is that it doesn’t break in earlier versions of IE. Explorer 6 renders the reference version just fine. In that sense, the new version is actually a step backward since IE6 doesn’t handle it properly.

Unfortunately, I don’t have a copy of IE7 readily available, but I managed to find this, which works in both Firefox and IE6. Maybe we can get lucky and have it work in 7 as well?


Nope - that breaks worse than all of the others in IE7.

Even if you luck out and find one that covers the bases, or can be modded to work… it’s just a temporary fix until they make sure IE8 breaks stuff for no reason. :stuck_out_tongue:

:stuck_out_tongue: Maximum savings promo code: MaxSavingsAtDH


Oh wow. I think I might have figured out how “the reference version” makes this work. Turns out the secret is that it doesn’t make the table scroll, but rather leaves the scrolling to a wrapper and some other hackery to simulate a scrolling table. The trouble is, that reference code hasn’t been updated since before IE7 and the new browser broke some of the CSS filters the author used to make the hack work in IE6.

Since I’m feeling sort of bored tonight, I’m updating the code to make it a bit more futureproof and to pick up IE7 support. I’ll be putting the result on my blog later and I’ll be sure to link you guys to it when I finish.