views:

234

answers:

8

I've tried several methods to get a scroll bar from html table with a fixed header but had no luck. I think I need a solution where the header is somehow "attached" to the table body (rather than the typical nested table solution). Every solution I tried messes up the width of the header columns and the body columns. In other words they get out of synch and the columns of the header don't line up properly with those of the scrolling table. The widths of the headers and the columns vary from column to column.

Is there any way for me to achieve this? I'd rather not use javascript. Oh and I need this to work in IE as well.

Thanks

Update: It is pretty important for me to get this functionality. I need the fixed header for both column and row headers. So far no solution has worked properly. I considered making the headers separate tables, but this wouldn't work when scrolling since the headers would stay fixed.

It seems like there would be many use cases for fixed html headers so it is surprising to me that there is no adequate solution.

(oh and I tried the option suggested by opatut in the link, but it doesnt work in all browsers and I need this work in IE, firefox and chrome...if it doesnt work in ie6 thats OK).

Oh and if I must fix the column widths or row heights, thats ok too, I would just be glad to have a working fixed header html table (cross-browser).

+1  A: 

My first answer didn't attempt to fix both headers and columns. Here's an example that should work in all typical browsers (but it may need some tweaking).

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
<html xmlns="http://www.w3.org/1999/xhtml"&gt;
<head>
    <title></title>
</head>
<body>

  <style>
    th { text-align: center; border: 1px solid black; padding:3px; }
    td { text-align: center; border: 1px solid black; padding:3px; }
    th.c1, td.c1 { width: 100px; }
    th.c2, td.c2 { width: 150px; }
    th.c3, td.c3 { width: 60px; }
    th.c4, td.c4 { width: 100px; }
    th.c5, td.c5 { width: 150px; }
    th.c6, td.c6 { width: 60px; }

    #rowScroll { height: 100px; } /* Subtract the scrollbar height */
    #contentScroll { height: 100px; width: 300px; }
    #colScroll { width: 272px; } /* Subtract the scrollbar width */
  </style>

    <table cellspacing="0" cellpadding="0" style="float: left;" style="width:300px; height:100px;" >
      <tr>
        <td id="void" style="border: 0;">
        </td>
        <td id="rowHeaders" style="border: 0;">
          <div id="colScroll" style="overflow-x:hidden;">
            <table cellspacing="0" cellpadding="0" style="width: 600px;">
              <tr>
                <th class="c1">A</th>
                <th class="c2">B</th>
                <th class="c3">C</th>
                <th class="c4">D</th>
                <th class="c5">E</th>
                <th class="c6">F</th>
              </tr>
            </table>
          </div>
        </td>
      </tr>
      <tr>
        <td id="colHeaders" style="border: 0;">
          <div id="rowScroll" style="overflow-y:hidden">
            <table cellspacing="0" cellpadding="0">
              <tr><td>R1</td></tr>
              <tr><td>R2</td></tr>
              <tr><td>R3</td></tr>
              <tr><td>R4</td></tr>
              <tr><td>R5</td></tr>
              <tr><td>R6</td></tr>
              <tr><td>R7</td></tr>
              <tr><td>R8</td></tr>
              <tr><td>R9</td></tr>
            </table>
          </div>
        </td>
        <td id="content" style="border: 0;">
          <div id="contentScroll" style="overflow:auto">
            <table cellspacing="0" cellpadding="0" style="width: 600px;">
              <tr><td class="c1">A1</td><td class="c2">B1</td><td class="c3">C1</td><td class="c4">D1</td><td class="c5">E1</td><td class="c6">F1</td></tr>
              <tr><td class="c1">A2</td><td class="c2">B2</td><td class="c3">C2</td><td class="c4">D2</td><td class="c5">E2</td><td class="c6">F2</td></tr>
              <tr><td class="c1">A3</td><td class="c2">B3</td><td class="c3">C3</td><td class="c4">D3</td><td class="c5">E3</td><td class="c6">F3</td></tr>
              <tr><td class="c1">A4</td><td class="c2">B4</td><td class="c3">C4</td><td class="c4">D4</td><td class="c5">E4</td><td class="c6">F4</td></tr>
              <tr><td class="c1">A5</td><td class="c2">B5</td><td class="c3">C5</td><td class="c4">D5</td><td class="c5">E5</td><td class="c6">F5</td></tr>
              <tr><td class="c1">A6</td><td class="c2">B6</td><td class="c3">C6</td><td class="c4">D6</td><td class="c5">E6</td><td class="c6">F6</td></tr>
              <tr><td class="c1">A7</td><td class="c2">B7</td><td class="c3">C7</td><td class="c4">D7</td><td class="c5">E7</td><td class="c6">F7</td></tr>
              <tr><td class="c1">A8</td><td class="c2">B8</td><td class="c3">C8</td><td class="c4">D8</td><td class="c5">E8</td><td class="c6">F8</td></tr>
              <tr><td class="c1">A9</td><td class="c2">B9</td><td class="c3">C9</td><td class="c4">D9</td><td class="c5">E9</td><td class="c6">F9</td></tr>
            </table>
          </div>
        </td>
      </tr>
    </table>

  <script src="../js/jquery-1.4.2.min.js" type="text/javascript"></script>
  <script type="text/javascript">
    var content = $("#contentScroll");
    var headers = $("#colScroll");
    var rows = $("#rowScroll");
    content.scroll(function () {
      headers.scrollLeft(content.scrollLeft());
      rows.scrollTop(content.scrollTop());
    });
  </script>
</body>
</html>
John Fisher
+1  A: 
opatut
+4  A: 

A simple search on Google could also have helped you.

Look at this question.

Ismail
A: 

It's a bit too much code to put in here directly, but what it comes down to is, at minimum, you'll need some hefty CSS for this. Using javascript and jQuery can lighten that, so I'll include links to both methods.

HTML + CSS Only

You can use the source on this page to copy an example of how you can do exactly what you're asking via CSS and HTML. This is reported as working in pretty much all current browsers (Opera 7.x + (All Platforms), Mozilla 1.x + (All Platforms), IE 6.x + (Windows), Safari 1.x + (MacOS), Konqueror 3.x + (Linux / BSD)), but if you have to go back to IE 5.x, it starts to fail.

Javascript/jQuery

If you decide that you're open to including Javascript and jQuery, there's a second option that looks a bit simpler to implement: this blog article shows how.

JGB146
A: 

I know you're trying to avoid Javascript, but I was in exactly the same boat as you (struggling with what to do for days on the exact challenge for a new application) and solved the problem in about 10 minutes once I found Datatables:

Working example of a solution: http://www.datatables.net/examples/basic_init/scroll_y.html

It EXACTLY matches header and body columns width-wise every time. Widths can be specified, but it's also intelligent enough to auto size. Column highlighting and sorting is supported by default using the provided sample CSS. Switching to a paginated model (what I ended up using) is a single line of code. And....the best part--if you're concerned that your user might not have Javascript turned on, it degrades perfectly back to standards-compliant HTML tables. IMHO, it's the least painful, most feature rich solution out there that fully supports IE.

If it makes you feel any better, I've used this solution on both a government (military) site and an international bank's websites....both the most demanding and strictest customers I've ever come across...and both were extremely happy with the results.

bpeterson76
A: 

Try my solution, it's bug free and optimized for performance (not sacrificing functionality):

http://code.google.com/p/js-scroll-table-header/

If you try it and need any help, just ask, I'm the author.

Raveren
A: 

You can use DataTables without JavaScript. It won't have sorting but the table, headers and divs that are hosting them will work. Just look at the page source - it has 3 divs each with a table with identical widths in thead. Top and bottom just provide header and footer and the one in the middle provides data. It's actually pretty close to your original idea that you need to heep these parts separated.

ZXX
A: 

Hi Dude,

I have implemented scrollable functionality in my blog. Table has fixed header, fixed footer works fine in IE, FF and Chrome. It does not uses separate table for making fixed header instead uses CSS and JavaScript.

I have posted different types of scrollable tables in my blog. Please let me know it solves your problem.

http://s7u.blogspot.com

Regards, Shahib

Shahib