How to Create Table With First Column Frozen?

Here is a HTML technique that can be used to create a table for data such that we can freeze the first column and add a scrollbar for rest of the columns as illustrated below.

Heading
Heading
Heading
This is a long Heading
Heading
Heading
Heading
Heading
Heading
Heading
Heading
Heading
 
Heading Heading Heading Heading Heading Heading Heading Heading Heading
xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx
xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx
xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx
xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx
xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx
xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx
xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx
xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx
xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx
xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx
xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx

HTML Used to create above table structure is:

<div id="table_div">
<table cellspacing="0" cellpadding="0" width="100%" border="0">
<tr>
<td id="table_heading">
<table cellspacing="0" cellpadding="0" id="heading_table">
<tr><th>Heading</th></tr>
<tr><td>Heading</td></tr>
<tr><td>This is a long Heading</td></tr>
<tr><td>Heading</td></tr>
<tr><td>Heading</td></tr>
<tr><td>Heading</td></tr>
<tr><td>Heading</td></tr>
<tr><td>Heading</td></tr>
<tr><td>Heading</td></tr>
<tr><td>Heading</td></tr>
<tr><td>Heading</td></tr>
<tr><td>Heading</td></tr>
<tr><td class="last_th"> </td></tr>

</table>
</td>
<td>
<div id="table_data">
<table cellspacing="0" cellpadding="0" id="data_table">
<tr>
<th>Heading</th>
<th>Heading</th>
<th>Heading</th>
<th>Heading</th>
<th>Heading</th>
<th>Heading</th>
<th>Heading</th>
<th>Heading</th>
<th class="last_td">Heading</th>
</tr>
<tr>
<td>xxxx</td>
<td>xxxx</td>
<td>xxxx</td>
<td>xxxx</td>
<td>xxxx</td>

<td>xxxx</td>
<td>xxxx</td>
<td>xxxx</td>
<td class="last_td">xxxx</td>
</tr>
<tr>
<td>xxxx</td>
<td>xxxx xxxx</td>
<td>xxxx</td>

<td>xxxx</td>
<td>xxxx</td>
<td>xxxx</td>
<td>xxxx</td>
<td>xxxx</td>
<td class="last_td">xxxx</td>
</tr>
<tr>
<td>xxxx</td>

<td>xxxx</td>
<td>xxxx</td>
<td>xxxx</td>
<td>xxxx</td>
<td>xxxx</td>
<td>xxxx</td>
<td>xxxx</td>
<td class="last_td">xxxx</td>
</tr>

<tr>
<td class="long_ht">xxxx</td>
<td class="long_ht">xxxx</td>
<td class="long_ht">xxxx</td>
<td class="long_ht">xxxx</td>
<td class="long_ht">xxxx</td>
<td class="long_ht">xxxx</td>
<td class="long_ht">xxxx</td>
<td class="long_ht">xxxx</td>

<td class="last_td long_ht">xxxx</td>
</tr>
<tr>
<td>xxxx</td>
<td>xxxx</td>
<td>xxxx</td>
<td>xxxx</td>
<td>xxxx</td>
<td>xxxx</td>

<td>xxxx</td>
<td>xxxx</td>
<td class="last_td">xxxx</td>
</tr>
<tr>
<td>xxxx</td>
<td>xxxx</td>
<td>xxxx</td>
<td>xxxx</td>

<td>xxxx</td>
<td>xxxx</td>
<td>xxxx</td>
<td>xxxx</td>
<td class="last_td">xxxx</td>
</tr>
<tr>
<td>xxxx</td>
<td>xxxx</td>

<td>xxxx</td>
<td>xxxx</td>
<td>xxxx</td>
<td>xxxx</td>
<td>xxxx</td>
<td>xxxx</td>
<td class="last_td">xxxx</td>
</tr>
<tr>

<td>xxxx</td>
<td>xxxx</td>
<td>xxxx</td>
<td>xxxx</td>
<td>xxxx</td>
<td>xxxx</td>
<td>xxxx</td>
<td>xxxx</td>
<td class="last_td">xxxx</td>

</tr>
<tr>
<td>xxxx</td>
<td>xxxx</td>
<td>xxxx</td>
<td>xxxx</td>
<td>xxxx</td>
<td>xxxx</td>
<td>xxxx</td>

<td>xxxx</td>
<td class="last_td">xxxx</td>
</tr>
<tr>
<td>xxxx</td>
<td>xxxx</td>
<td>xxxx</td>
<td>xxxx</td>
<td>xxxx</td>

<td>xxxx</td>
<td>xxxx</td>
<td>xxxx</td>
<td class="last_td">xxxx</td>
</tr>
<tr>
<td class="last_row">xxxx</td>
<td class="last_row">xxxx</td>
<td class="last_row">xxxx</td>

<td class="last_row">xxxx</td>
<td class="last_row">xxxx</td>
<td class="last_row">xxxx</td>
<td class="last_row">xxxx</td>
<td class="last_row">xxxx</td>
<td class="last_td_row">xxxx</td>
</tr>
</table>
<div class="height_for_safari"></div>
</div>

</td>
</tr>
</table>
</div>

CSS Rules Used to create above table structure is

#table_div {margin:10px 0; width:450px; background-color:#FFF;}
#table_div td {vertical-align:top;}
#table_heading {background-color:#FFF; border:1px solid #688FA3;}
#heading_table {width:100%; padding:0; border:0;}
#heading_table th {background-color:#B8CAD4; border-bottom:1px solid #688FA3; padding:0 6px; vertical-align:middle; height:35px; font:bold 11px Arial, Helvetica, sans-serif; color:#000; margin:0;}
#heading_table td {background-color:#FFF; border-bottom:1px solid #688FA3; padding:0 6px; vertical-align:middle; height:35px; font:bold 11px Arial, Helvetica, sans-serif; color:#000; margin:0;}
#heading_table td.last_th {border-right:0; border-bottom:0; margin:0; height:5px; padding:0;}
#table_data {width:400px; border-right:1px solid #688FA3; border-top:1px solid #688FA3; border-bottom:1px solid #688FA3; overflow:auto; background-color:#FFF;}
#data_table {width:100%; padding:0; border-bottom:1px solid #688FA3; margin:0; background-color:#FFF;}
.height_for_safari {height:15px; background-color:#FFF;}
#data_table th {background-color:#B8CAD4; border-bottom:1px solid #688FA3; vertical-align:middle; height:35px; font:bold 11px Arial, Helvetica, sans-serif; color:#000; margin:0; text-align:center; border-right:1px solid #688FA3; padding:0 6px;}
#data_table td {background-color:#FFF; border-bottom:1px solid #688FA3; vertical-align:middle; height:35px; font:bold 11px Arial, Helvetica, sans-serif; color:#000; margin:0; text-align:center; border-right:1px solid #688FA3; text-align:center; white-space:nowrap; padding:0 2px;}
#data_table .long_ht {height:42px;}
#data_table td.last_td {border-right:0; border-bottom:1px solid #688FA3; }
#data_table td.last_row {border-right:1px solid #688FA3; border-bottom:0; }
#data_table td.last_td_row {border-right:0; border-bottom:0; }
* html #table_data {width:400px; overflow-x:scroll; overflow-y:visible; }

Please note that I wanted to show just the horizontal scrollbar and not the vertical scrollbar. For FireFox this was easy as all I had to do was declare overflow:auto style for the div with scrollbar.

For Internet Explorer (IE), I had to specify following CSS rules for the div with scrollbar:
overflow-x:scroll – This adds horizontal scrollbar
overflow-y:visible – This makes sure that vertical scrollbar is not added.

Hence in order to use difference CSS rules for IE and FireFox, I had to use the following:
* html #table_data {width:400px; overflow-x:scroll; overflow-y:visible; } – Adding asterisk and html before the appropriate class or ID, makes sure that this rule is rendered by Internet Explorer (IE) only. FireFox ignores this rule.

If you have any problem recreating a table such as above, please leave me a comment and I’ll try to explain.

14 thoughts on “How to Create Table With First Column Frozen?”

  1. The first column, i.e. the one that is frozen will be the heading column and so, you should be able to control the height and width of each cell in that column. So, if the text wraps and the height of that particular cell increases then you will have to adjust rest of the columns accordingly. You can see this in the above table (I’ve modified the above table to show this).

    However, I do suggest declaring whitespace:nowrap style for the all the cells with data. This is because you do not have control over the length of the data and so, if the data wraps and increases the height of the cell then the columns will not line up.

  2. Is there any way to freeze the first row as well? So, if I scroll down, the first header row would stay frozen as well?

    Thanks,
    Jeff

  3. Dear Jeff,
    I’ve tried freezing the first row but it doesn’t work. If you have any solution please let me know.

    Shruti

  4. just what I was looking for, thanks !

    ps. I had a vertical scrollbar in IE7
    so I changed the last css line to:
    #table_data {width:400px; overflow-y: auto; overflow-y: hidden; }
    and now it works fine for firefox and IE7 !

  5. #header
    {
    width:790px;
    border-collapse:collapse;
    border: 1px solid #cccccc;
    margin-bottom:1px;
    }

    #header th
    {
    padding:5px;
    text-align:left;
    background-color: #e5e5fc;
    border: 1px solid #cccccc;
    font-size: .7em;
    }

    #header th.colmn2
    {
    vertical-align:bottom;
    }

    #details
    {
    height: 106px;
    width:806px;
    border: none;
    overflow: auto;
    overflow-x: hidden;
    }

    #data
    {
    width:790px;
    border-collapse:collapse;
    border: 1px solid #cccccc;
    }

    #data td
    {
    padding:5px;
    border: 1px solid #CCCCCC;
    }

    .colmn2
    {
    width: 25%;
    }

    AFR FTE DETAILS

    Budget Account
    FTE Class
    FTE Group
    Requested FTE

    In the above sample code, If u see the header (which is stable) while scrolling, You can see some table data can be viewable above the header row. Can u tell me how to hide that ?

  6. Hi Shruti,

    I used your approach of freezing a column in my project. It worked out really well. Now we are facing a small problem when the table data is a check box. If data is a check box then there is a problem in the alignment of the table with its row heading. My table is a dynamic one in which contents gets changes depends on others. So a label can become a check box and check box can become a label depends on the value that is chosen by user. That’s why i can;t use your .long_ht class. Can you please guide me on this?

  7. hi ,
    i visited your website for freezing issue in mozzila . but it is limited solutions if you are making something dynamic.then you have to set class attribute in every last td of row.so if you have any other solutions then just mail me.thanks in advance.

  8. This solution is working in IE but not in Mozilla firefox. Could you please provide solution for that?

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.