could you explain some more, in detail, what you mean by "I need the column heading rows to remain fixed and scroll the rows an necessary" ?
–
TomAug 3 '12 at 15:10

"I need the column heading rows to remain fixed and scroll the rows an necessary." What do you mean by that exactly? Do you mean that the top row will not scroll, but the rows below it will?
–
Cypress FrankenfeldAug 3 '12 at 15:10

@Tom, the actual table I have has over 1000 green rows, I need the two blue header rows to remain visible as you scroll the screen down.
–
KM.Aug 3 '12 at 15:11

@Cypress Frankenfeld, I have seen many examples like the one you reference. My problem is how to make that work for my table, and yes, I'll give away the max bounty points for a working example using my table.
–
KM.Aug 3 '12 at 16:16

The only way I was able to get it to work was with a bit of trickery alright.
I separated the header as in the first example. But due to the extremly custom multiple different widths in the header, the most reliable way, keeping everything aligned, was to copy the th rows also into the second table but without text inside. That made them "invisible" but forced the columns in the second table to align as expected.

It feels a bit hackish and I'm sure there is a proper solution but it seems to work well in the meantime.

Edit -- August 7th 2012

Is there any way to "box" this entire table construct up in up 100% of
the screen width and change the height for height:150px; to something
more dynamic, like $(window).height()-200

There surely is a more elegant way of doing it but I was able to make the table more dynamic.

The width was less of an issue as I capped the toal width at about 95% and hard-capped the table(s) at a min-width: 600px; for the header and a min-width: 584px for the body, thus ensuring the table stays aligned at all times.

For the dynamic height I used jQuery, binding a resize function to the windows resize event:

You will notice some styles are in the css (top-right) in the fiddle while others are not. My CSS is not very strong and some styles when I moved them from the elements into the CSS area started to be irgnored. I moved into CSS what I could and left the rest hard-coded not to break it. I'm sure someone working with CSS everyday will be able to sort that out for you.

I also added some ids to some elements for CSS and for the jQuery as required.
I suppose for the CSS it can use classes instead. I leave that to you.

SummaryI'm sure there is a way more elegant way to achieve what you want and probably some script-wiz got a plugin for it. Until then this seems to work. What could also happen is that the columns start miss-aligning close to 600 pixels again if a lot of long data is entered into the columns but as stated, this is a very personalised solution and you may need to add some dynamic calculations for some widths with jQuery over time.

Edit -- August 9th 2012

Regarding setting the width of a td I mentioned in the comments. I fixed the issue with the long text in the first column using the classes I mentioned. Works in IE, FF and Chrome.

I used the logic mentioned in the comments. You might find a much better naming convention. I simply used the main-column+ a on/off switch per sub-column. this works out as follows for column 1 styles:

I have assigned the first td a class of col01-100 which means 50px.
The second td has now a class of col01-011, indicating this td still belongs into the first main column but has a width of sub-column 2 (50px) and 3(75px). This adds up to 125px.

I hope this makes sense but if not I gladly continue the discussion in a chat and work the measurements out with you if that is something you want to apply.

I've found many demos like this on the web. the problem is when I try to make it work on my table, they fail. My table has two header rows, and use colspans, can you incorporate that into your demo?
–
KM.Aug 3 '12 at 15:18

@KM.: I have a look, can't fiddle around with it though until later tonight. I definetly post a response though then.
–
François WahlAug 3 '12 at 15:19

looks good. However, when the table is wider than the screen, the vertical scroll bar is hidden off screen. Is there any way to "box" this entire table construct up in up 100% of the screen width and change the height for height:150px; to something more dynamic, like $(window).height()-200
–
KM.Aug 6 '12 at 12:10

@KM.: Sorry for the long wait. I wasn't able to sit down and focus on that until tonight. I edited my answer and added a DEMO to a more dynamic grid. I capped the total width of the table at 95% of the screen width with a minimum width of about 600 pixels. Anything below 600 starts causing alignment issues, at least now the table parts will move in sync. I added dynamic height calculations using jQuery as well. Hope this will help point you into the right direction.
–
François WahlAug 7 '12 at 20:13

does this run with little client side processing? In attempting to use your answer from my previous question, occasionally the table was too large and the browser would crash. There were several thousand table rows and 50 or so columns, each with a checkbox+onchange script
–
KM.Aug 10 '12 at 14:02

@KM. It simply clones the thead from the table and use the scroll event. I don't think it would crash.. but let me try to set a fiddle with thousands of rows and see. But is this something close to what you want?
–
VegaAug 10 '12 at 14:06

I seem to have the other solution working without and scroll event or and js so you don't have to.
–
KM.Aug 10 '12 at 14:31

@KM. Well it is more of manual vs automated. In other solution, you have to copy paste the thead in a separate table and have a div that scrolls. In my solution it is generated by javascript.
–
VegaAug 10 '12 at 14:41

I'm generating the entire page with code, so duplicating the header is trivial.
–
KM.Aug 10 '12 at 14:59

I use DataTables as well. Works fairly well (only a few oddities that I stumbled upon), and it does a lot of the grunt work for you. Can take some time for larger tables on older browsers though.
–
MatthewKremerAug 10 '12 at 19:53

I may as well provide an option for you. This assumes the browser window is being scrolled.

The idea here is that a clone of your table is made and everything but the thead is stripped out of it. It is fixed to the top of the viewport and hidden.

When the user scrolls past the top of the table, the cloned table is displayed. I have also included a resize event to handle changes to the viewport's width. There are some minor hiccups with keeping the fixed header and the table aligned horizontally, but it's not a big issue.

Here is a demo using your table as source (I moved a lot of the inline styles to CSS just to make things easier to read):

If you .clone() the thead and put it in the table all of the columns retain their original width.

Update: I realized that IE 6 and 7 were having problems and I fixed them. The issue was that those versions of IE don't allow you to position the thead directly. As a result, I changed it so that it moves the thead tr instead, but only if the browser is IE < 8.

Another bug was that IE < 9 had problems with .prependTo(). I'm not sure if it is just IE Tester or not, but I resolved the issue by using .after().

Edit

I didn't realize that K.M. wanted a fixed height table. If you look at my example above you'll see that the table header is fixed if the browser scrolls past the top of the table. However, from my understanding this is not what he/she wanted.

I have tested this in the following browsers on my Mac.

Safari (5.1.7)

Firefox (11.0)

Chrome (21.0.1180.75)

And I have tested this in Windows 7 with:

IE 8 and 9 using IE Tester

Firefox (5.0.1, 6.0.2, 7.0.1, 8.0.1, 10.0.2)

Chrome (12.0.742.91)

Safari (5.1.5)

It is broken in IE 6 and 7, but I didn't look into seeing if there was a fix.

I've been searching for something that works in IE7, this is it. However in Chrome, IE8, IE9, the table header becomes misaligned by a few pixels horizontally upon scrolling. Any ideas how to sort this?
–
MarcusOct 15 '12 at 18:17

I have an idea for you. You will split your table into two tables. One of them will acting as the header and the second will acting as the rest of all cells and rows.
The trick in the following:
Placing two fixed width and height divs vertical adjacent to themselves. the upper one will loads the header table and the n the lower will acts for the table body. in the lower div you will set vertical overflow. By this way you will have simple solution's that supports your header move with data scrolling.

It seems the best way to go about this is two tables. Outer table with headers, and one big row with an inner table inside that. The div should be css'ed overflow: scroll or auto with a set height (via css or javascript). You will have to set specific widths on all the columns. I think the best way to go about that is giving a class for each header, and make sure the corresponding columns in the inner table have the same classes.