63

Is there a CSS/JavaScript technique to display a long HTML table such that the column headers stay fixed on-screen and the first coloumn stay fixed and scroll with the data.

I want to be able to scroll through the contents of the table, but to always be able to see the column headers at the top and the first column on the left.

If there is a jQuery plugin that would be great! If it helps the only browser I care about is Firefox.

6
  • 1
    Partial dup: stackoverflow.com/questions/673153/… Commented Mar 26, 2009 at 2:04
  • 2
    Doesn't seems like a duplicate as this question requires fixed column as well. Commented May 31, 2013 at 19:39
  • 5
    I voted to reopen this question out of principle. Dozens of upvotes and favorit'ing, apparently someone finds it useful. Yes it requires a long answer. That's what jfiddle and other similar tools are for. Commented May 17, 2016 at 15:26
  • 1
    Google brought me to this question on my first searches, but the answers are outdated and not very satisfying. I eventually found the answer here: stackoverflow.com/a/50516259/982107 Commented Feb 22, 2019 at 10:28
  • 1
    I don't see why this question is closed. The problem is clearly defined. The question should accept answers with potentially more modern techniques. Commented Oct 30, 2022 at 14:05

10 Answers 10

18

Working example of link posted by pranav:

http://jsbin.com/nolanole/1/edit?html,js,output

FYI: Tested in IE 6, 7, & 8 (compatibility mode on or off), FF 3 & 3.5, Chrome 2. Not screen-reader-friendly (headers aren't part of content table).

EDIT 5/5/14: moved example to jsBin. This is old, but amazingly still works in current Chrome, IE, and Firefox (though IE and Firefox might require some adjustments to row heights).

Sign up to request clarification or add additional context in comments.

3 Comments

doesn't work for me in winxp ie8 or ff3.6
The link to the jQuery library hosted on jQuery.com changed, and their redirect was incorrect... so it stopped working in ALL browsers. I've fixed the link to point to the file on Google's servers instead - hopefully that one should be more reliable.
Thanks. This helped me a lot. I had to modify the code to use setTimeout() to get it to work with larger tables, but this is a nice example.
3

The jQuery DataTables plug-in is one excellent way to achieve excel-like fixed column(s) and headers.

Note the examples section of the site and the "extras".
http://datatables.net/examples/
http://datatables.net/extras/

The "Extras" section has tools for fixed columns and fixed headers.

Fixed Columns
http://datatables.net/extras/fixedcolumns/
(I believe the example on this page is the one most appropriate for your question.)

Fixed Header
http://datatables.net/extras/fixedheader/
(Includes an example with a full page spreadsheet style layout: http://datatables.net/release-datatables/extras/FixedHeader/top_bottom_left_right.html)

1 Comment

note: from my experience (correct me if I'm wrong), it only works if all of your table cells have colSpan and rowSpan = 1.
2

In 2024, this is possible with just HTML and CSS: https://jsfiddle.net/8oyj42nL/3/

/* THE IMPORTANT BITS */
table {
  /* Wide enough to go off the page */  
  width: 1000px;
}

thead th {
  position: sticky;
  top: 0;
}

th:first-child {
  position: sticky;
  left: 0;
  /* Make the top left corner cover the other column headers */
  z-index: 2;
}

thead th:first-child {
  /* Make the top left corner cover the other row headers */
  z-index: 3;
}



/* Visual clarity */
th { background: #93E9BE; }
td { background: #CECECE; }
th:first-child { background: #FFFFC2 }
thead th:first-child { background: purple; }

/* Prettier spacing */
thead { text-align: left; }
td, th { padding-left: 1em; height: 5em; }
th:first-child { padding-left: 0; }
<table>
<tbody>
  <thead>
    <tr>
      <th></th>
      <th>Column 1 header</th>
      <th>Column 2 header</th>
      <th>Column 3 header</th>
      <th>Column 4 header</th>
    </tr>
  </thead>
</tbody>
  <tr>
    <th>Row 1 header</th>
    <td>Data 1.1</td>
    <td>Data 2.1</td>
    <td>Data 3.1</td>
    <td>Data 4.1</td>
  </tr>
  <tr>
    <th>Row 2 header</th>
    <td>Data 1.2</td>
    <td>Data 2.2</td>
    <td>Data 3.2</td>
    <td>Data 4.2</td>
  </tr>
  <tr>
    <th>Row 3 header</th>
    <td>Data 1.3</td>
    <td>Data 2.3</td>
    <td>Data 3.3</td>
    <td>Data 4.3</td>
  </tr>
  <tr>
    <th>Row 4 header</th>
    <td>Data 1.4</td>
    <td>Data 2.4</td>
    <td>Data 3.4</td>
    <td>Data 4.4</td>
  </tr>
</table>

Comments

1

If what you want is to have the headers stay put while the data in the table scrolls vertically, you should implement a <tbody> styled with "overflow-y: auto" like this:

<table>
  <thead>
    <tr>
      <th>Header1</th>
       . . . 
    </tr>
   </thead>
   <tbody style="height: 300px; overflow-y: auto"> 
     <tr>
       . . .
     </tr>
     . . .
   </tbody>
 </table>

If the <tbody> content grows taller than the desired height, it will start scrolling. However, the headers will stay fixed at the top regardless of the scroll position.

7 Comments

thanks, that helps with the fixed header part but what about the fixed column?
overflow-y is ms specific. You'll have to use a plain overflow:auto.
@levik: does not work in almost all browsers at least using HTML 5 DOCTYPE in standrad mode
This does not work...
It doesn't work at all !
|
0
<script>
   $(document).ready(function () {
   $("#GridHeader table").html($('#<%= GridView1.ClientID %>').html());
   $("#GridHeader table tbody .rows").remove();
   $('#<%= GridView1.ClientID %> tr:first th').hide();
});
</script>

<div id="GridHeader">
    <table></table>
</div>

<div style="overflow: auto; height:400px;">
    <asp:GridView ID="GridView1" runat="server" />
</div>

1 Comment

Is it possible to use this method with "responsive" columns (no fixed width defined)?
0

Not quite perfect, but it got me closer than some of the top answers here.

Two different tables, one with the header, and the other, wrapped with a div with the content

<table>
  <thead>
    <tr><th>Stuff</th><th>Second Stuff</th></tr>
  </thead>
</table>
<div style="height: 600px; overflow: auto;">
  <table>
    <tbody>
      //Table
    </tbody>
  </table>
</div>

Comments

-2

I know you can do it for MSIE and this limited example seems to work for firefox (not sure how extensible the technique is).

2 Comments

First linked didn't work for me. Second one does now show how to produce fixed first column.
Both links in answer are dead.
-2

The first column has a scrollbar on the cell right below the headers

<table>
    <thead>
        <th> Header 1</th>
        <th> Header 2</th>
        <th> Header 3</th>
    </thead>
    <tbody>
        <tr>
            <td>
                <div style="width: 50; height:30; overflow-y: scroll"> 
                    Tklasdjf alksjf asjdfk jsadfl kajsdl fjasdk fljsaldk 
                    fjlksa djflkasjdflkjsadlkf jsakldjfasdjfklasjdflkjasdlkfjaslkdfjasdf
                </div>
            </td>
            <td>
                Hello world
            </td>
            <td> Hello world2
        </tr>
    </tbody>
</table>

1 Comment

I think you've misunderstood what's being asked. We want to be able to scroll to different cells in a (large) table.
-2

YUI DataTable

I don't know if YUI DT has this feature but I won't be surprised if it does.

2 Comments

Thanks I took a look at that. It does have a scrolling table but that does have a fixed header but not the fixed coloumn that I need. developer.yahoo.com/yui/examples/datatable/dt_fixedscroll.html
yeah, I couldn't find that either from their list of examples.
-3

Here is a good jQuery plugin, working in all browsers!

You have a fixed header table without fixing its width.

Check it: https://github.com/benjaminleouzon/tablefixedheader

Disclaimer: I am the author of the plugin.

1 Comment

Guess, the correct URL here would be fixedheadertable.com

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.