Search
Close this search box.

Html Table with Fixed Header and Scrollable Body

I have created the world’s greatest web control. OK, it’s more like I reinvented the wheel. I present to you a cross-browser table with a fixed header and scrollable body.

Column 1Column 2Column 3 
Row A-1Row A-2Row A-3
Row B-1Row B-2Row B-3
Row C-1Row C-2Row C-3
Row D-1Row D-2Row D-3
Row E-1Row E-2Row E-3
Row F-1Row F-2Row F-3
Row G-1Row G-2Row G-3

The magic is in a bit of tomfoolery. There are actually a few stacked controls. The code is produced with the following:

<div style="
margin: 0; padding: 0; border-collapse: collapse; width: 519px; height: 100px; overflow: hidden; border: 1px solid black;"
>
<table style="
margin: 0; padding: 0; border-collapse: collapse; color: White; width: 517px; height: 20px; text-align: left; background-color: Blue;"
>
<colgroup>
<col
width="200px"
/>
<col
width="150px"
/>
<col
width="150px"
/>
<col
width="16px"
/>
</colgroup>
<tbody>
<tr style="
margin: 0; padding: 0; border-collapse: collapse;"
>
<th style="
margin: 0; padding: 0; border-collapse: collapse;"
>
Column 1
</th>
<th style="
margin: 0; padding: 0; border-collapse: collapse;"
>
Column 2
</th>
<th style="
margin: 0; padding: 0; border-collapse: collapse;"
>
Column 3
</th>
<th style="
margin: 0; padding: 0; border-collapse: collapse;"
>
 
</th>
</tr>
</tbody>
</table>
<div style="
margin: 0; padding: 0; border-collapse: collapse; width: 517px; height: 77px; overflow: auto;"
>
<table style="
margin: 0; padding: 0; border-collapse: collapse; width: 500px;"
>
<colgroup>
<col
width="200px"
/>
<col
width="150px"
/>
<col
width="150px"
/>
</colgroup>
<tbody style="
margin: 0; padding: 0; border-collapse: collapse;"
>
<tr style="
margin: 0; padding: 0; border-collapse: collapse;"
>
<td style="
border: 1px solid lightgrey;"
>
Row A-1
</td>
<td style="
border: 1px solid lightgrey;"
>
Row A-2
</td>
<td style="
border: 1px solid lightgrey;"
>
Row A-3
</td>
</tr>
<tr style="
margin: 0; padding: 0; border-collapse: collapse;"
>
<td style="
border: 1px solid lightgrey;"
>
Row B-1
</td>
<td style="
border: 1px solid lightgrey;"
>
Row B-2
</td>
<td style="
border: 1px solid lightgrey;"
>
Row B-3
</td>
</tr>
<tr style="
margin: 0; padding: 0; border-collapse: collapse;"
>
<td style="
border: 1px solid lightgrey;"
>
Row C-1
</td>
<td style="
border: 1px solid lightgrey;"
>
Row C-2
</td>
<td style="
border: 1px solid lightgrey;"
>
Row C-3
</td>
</tr>
<tr style="
margin: 0; padding: 0; border-collapse: collapse;"
>
<td style="
border: 1px solid lightgrey;"
>
Row D-1
</td>
<td style="
border: 1px solid lightgrey;"
>
Row D-2
</td>
<td style="
border: 1px solid lightgrey;"
>
Row D-3
</td>
</tr>
<tr style="
margin: 0; padding: 0; border-collapse: collapse;"
>
<td style="
border: 1px solid lightgrey;"
>
Row E-1
</td>
<td style="
border: 1px solid lightgrey;"
>
Row E-2
</td>
<td style="
border: 1px solid lightgrey;"
>
Row E-3
</td>
</tr>
<tr style="
margin: 0; padding: 0; border-collapse: collapse;"
>
<td style="
border: 1px solid lightgrey;"
>
Row F-1
</td>
<td style="
border: 1px solid lightgrey;"
>
Row F-2
</td>
<td style="
border: 1px solid lightgrey;"
>
Row F-3
</td>
</tr>
<tr style="
margin: 0; padding: 0; border-collapse: collapse;"
>
<td style="
border: 1px solid lightgrey;"
>
Row G-1
</td>
<td style="
border: 1px solid lightgrey;"
>
Row G-2
</td>
<td style="
border: 1px solid lightgrey;"
>
Row G-3
</td>
</tr>
</tbody>
</table>
</div>
</div>

It doesn’t look too impressive. After all, it’s nothing more than some carefully stacked controls. However, there are a few features that make this worthwhile. The most important is cross-browser compatibility. We have tested this with IE7, IE8, IE9, IE10 Beta, FF3, Chrome, and Mac Safari1.

The other major issue is that this does not work on mobile browsers. We have tried with iOS and Android. The reason is quite simple. Mobile browsers don’t have scroll bars. If you need to make this work on a mobile browser, your best bet is to load a separate style-sheet that undoes everything.

Issues aside, let’s tear into this thing. I want to first point out the issues that are pretty standard. Just about everything has a style=”margin: 0; padding: 0; border-collapse: collapse;”. This kills the slight differences between browsers with margins, borders, spacing, and padding. This is also why most of the large, block elements have defined widths.

The next significant fact is the use of colgroup. Most of us dismiss this element when creating tables. However, it is one of the most effective ways to lock down column widths2. This is very important to us; we need our two tables to stay aligned.

Now that the widths are OK, we have to lock down the heights. This is almost the sole source of magic. First, we fix the height of the containing box. Then, we fix the height of the header. Finally, we give the remaining room to the containing block for the body, minus 3 pixels for cross-browser rendering. It is definitely worth nothing that the body table does not have a height specified. This is necessary.

The rest of the magic comes from the overflow styles. Our first overflow tag is on the main block. We set the overflow to hidden. This tells the browser to simply hide anything that doesn’t fit in the box3. Then, we set the inner div to have an overflow of auto. This tells the div to display scroll bars if the table is bigger than the div4.

That, in a nutshell, does it. Yes, there are a lot of cool extras you can pile on this framework. The version I developed is extremely more advanced than this. However, the bosses on let me give away so much free code.

1There is a minor graphical glitch. Different browsers have different sized scroll bars. As such, there are a few pixels between the borders on a few browsers.
2If the cell has a single string longer than the width, it will push the column borders and keep things from aligning. However, if you keep your columns sized appropriately for your data, the table will just grow the row vertically.
3If you removed this and the border, the control would probably downgrade nicely to mobile browsers. However, it also would keep the control from looking like a nice cohesive control.
4If you want to keep the scroll bar visible, replace the overflow: auto with overflow-x: hidden; overflow-y: scroll;

posted on Tuesday, April 19, 2011 8:21 PM

This article is part of the GWB Archives. Original Author: freestylecoder

Related Posts