5

I have tried looking all over the place and couldn't find a good solution to my problem. I am looking to create a table with fixed headers that stay while scrolling the rest of the table. The problem is I also want it to be able to be aligned when the page window adjusts. I have been able to get fixed headers and have been able to get columns to align when I adjust the window, just haven't be able to get both to work together. Is there a script out there that can do this? I have tried fixedheadertable jquery, flexigrid, fixed-header-coffee, chromatable and floatyhead. None of these were able to give me the solution I am looking for. Maybe I am doing something wrong but I have a traditional table using theader, tbody, etc. I would like to avoid splitting up the table into two tables, because it seems they never line up properly but if that's the only solution, I'll take it.

Please help!

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
acmeyer9
  • 315
  • 1
  • 2
  • 13

5 Answers5

1

You can use just standard HTML/CSS. Specifically, utilize display/overflow/height in your CSS and thead/tbody in your HTML. Example CSS:

.scrollableTable tbody {
    display: block;
    overflow-y: auto;
    width: 100%;
    height: 50px;
}
.scrollableTable tr {
    display: block;
}
.scrollableTable td, .scrollableTable th {
    width: 50%;
}

Example HTML:

<table class="scrollableTable">
    <thead>
        <tr>
            <th>Fruit</th>
            <th>Color</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>Apples</td>
            <td>Red</td>
        </tr>
        <tr>
            <td>Bananas</td>
            <td>Yellow</td>
        </tr>
        <tr>
            <td>Oranges</td>
            <td>Orange</td>
        </tr>
    </tbody>
</table>
Nate Barr
  • 4,640
  • 2
  • 25
  • 21
  • this does not work. It produces a very small table which is fixed and the columns still dont even line up properly. – acmeyer9 Nov 24 '11 at 14:23
  • Oops - put 'tr' instead of 'td' in there. Fixed that. I can see a better way to do this with jQuery that would not have column widths different from thead and tbody, and would enhance the table when browser compatible. I'll post it as a separate solution. – Nate Barr Nov 25 '11 at 14:29
0

I modified above answer by Nate Barr. In the previous answer column alignment will become congested.

Style sheet

<style type="text/css">
.scrollableTable thead {
 display: block;
    //overflow-y: auto;
    width: 105%;
    height: 25px;
}
.scrollableTable tbody {
 display: block;
    overflow-y: auto;
    width: 105%;
    height: 200px;
}

Table

<table width="439" border="1" align="center" class="scrollableTable">
    <thead>
        <tr>
          <th width="20">No</th>
            <th width="140">Fruit</th>
          <th width="131">test</th>
          <th width="120">Color</th>
        </tr>
    </thead>
    <tbody>
        <tr>
          <td>1</td>
            <td>Apples</td>
            <td>ohyoijmnpkjoijikjm;kl</td>
            <td>Red</td>
        </tr>
        <tr>
          <td>2</td>
            <td>Bananas</td>
            <td>ghjghjghj</td>
            <td>Yellow</td>
        </tr>
        <tr>
          <td>3</td>
            <td>Oranges</td>
            <td>hfkjhkjhkhjkl</td>
            <td>Orange</td>
        </tr>
        <tr>
          <td>4</td>
          <td>fghgfmjhgjhgjhg</td>
          <td>hjkhjkgk</td>
          <td>fghfg</td>
        </tr>
        <tr>
          <td>5</td>
          <td>fghfg</td>
          <td>fgjfjfd</td>
          <td>gfh</td>
        </tr>
        <tr>
          <td>6</td>
          <td>fghfhj</td>
          <td>gjdfhgkgfk</td>
          <td>ghjgfk</td>
        </tr>
        <tr>
          <td>7</td>
          <td>jkgfk</td>
          <td>hjfkgfk</td>
          <td>hjlklh</td>
        </tr>
        <tr>
          <td>8</td>
          <td>hgjfgghjghj</td>
          <td>fgjkjhljk</td>
          <td>hjkj</td>
        </tr>
        <tr>
          <td>9</td>
          <td>jhkjkf</td>
          <td>fgjghj</td>
          <td>gkhkfjghhgjgh</td>
        </tr>
        <tr>
          <td>10</td>
          <td>fkjfhk</td>
          <td>hjg</td>
          <td>fjkhgk</td>
        </tr>
        <tr>
          <td>11</td>
          <td>ghkkh</td>
          <td>fghd</td>
          <td>ghkgh</td>
        </tr>
        <tr>
          <td>12</td>
          <td>kjhjklhgkjgljghjh</td>
          <td>hlg</td>
          <td>kjghkjhgkj</td>
        </tr>
        <tr>
          <td>13</td>
          <td>kgk</td>
          <td>d</td>
          <td>kkjhgklh</td>
        </tr>
        <tr>
          <td>14</td>
          <td>hkjhgkjhklj</td>
          <td>hjgk</td>
          <td>lhjljhgygyh</td>
        </tr>
        <tr>
          <td>15</td>
          <td>ijihgjil</td>
          <td>fg</td>
          <td>lhjoklh</td>
        </tr>
        <tr>
          <td>16</td>
          <td>lohkjl</td>
          <td>ghj</td>
          <td>lholhuhity</td>
        </tr>
        <tr>
          <td>17</td>
          <td>kgjhgikghiu</td>
          <td>ghjk</td>
          <td>ljhljkyhklj</td>
        </tr>
        <tr>
          <td>18</td>
          <td>kgihgik</td>
          <td>ghjg</td>
          <td>iuhgouygih8</td>
        </tr>
        <tr>
          <td>19</td>
          <td>uoiughuiohou</td>
          <td>ghkkj</td>
          <td>oijhoiyhigouohu</td>
        </tr>
        <tr>
          <td>20</td>
          <td>ihnohnjoikjnm</td>
          <td>fghfg</td>
          <td>ioojhjphiuhiuhohouh</td>
        </tr>            
    </tbody>
</table>
Sarin Jacob Sunny
  • 2,138
  • 3
  • 29
  • 61
  • But this uses a fixed width, I am looking for a solution that works with a table that moves with the adjusting of the window page. – acmeyer9 Nov 24 '11 at 14:15
  • @user1054494 use some Dreamweaver, you can change the dimensions from fixed pixels to some percentage as you wish.. Take the css, table you have to modify as per your needs.. – Sarin Jacob Sunny Nov 24 '11 at 16:18
  • I did try this with fixed pixels and percentages and even with fixed percentages it doesn't line up the columns properly. – acmeyer9 Nov 24 '11 at 17:13
  • This code works differently in Firefox n chrome. and not at all working in ie – Sarin Jacob Sunny Nov 24 '11 at 17:44
0

jQuery DataTables may not be quite what you're looking for, but have you looked into it? The datatables documentation includes a special section for "FixedHeader", so you have a number of implementations you can review.

http://datatables.net/examples/

Some relevant DataTables Fixed header examples from the documentation:

  1. http://datatables.net/release-datatables/extras/FixedHeader/two_tables.html

    "The following example shows two ... tables both with FixedHeader enabled on them. The footer is also fixed..."

  2. http://datatables.net/release-datatables/extras/FixedHeader/top_bottom_left_right.html

    "This example shows how FixedHeader can be made to look more like a spreadsheet application."

mg1075
  • 17,985
  • 8
  • 59
  • 100
  • Yea, this provides a sticky header when you scroll down an entire page. I was looking for one where it was in a fixed part of a page and just the rows themselves scrolled. Kind of like iTunes. – acmeyer9 Nov 24 '11 at 14:56
  • 1
    Have you also looked into jqGrid? http://www.trirand.com/blog/jqgrid/jqgrid.html – mg1075 Nov 24 '11 at 18:27
  • Yea I was just trying to avoid using an entire system to do this but thanks. – acmeyer9 Nov 25 '11 at 14:54
0

Try this answer, It is working in IE8, Firefox and Chrome..

Style

    .Container { margin-left: 200px; background-color: green; overflow: scroll; overflow-x: hidden; height: 200px; }

    .BigTable { width: 100%; }

    .BigTable td { width: 40%; }

    .BigTable td + td { width: 30%; }

    .BigTable td + td + td { width: 30%; }

    .Header { margin-left: 200px; height: 30px; background-color: blue; }

    .Header .Heading { width: 40%; float: left; height: 30px; }

    .Header .Heading + .Heading  { width: 30%; }

    .Header .Heading + .Heading + .Heading { width: 30%; }

Table

<div class="Header">
    <div class="Heading">Heading 1</div>
    <div class="Heading">Heading 2</div>
    <div class="Heading">Heading 3</div>
</div>
<div class="Container">
    <table class="BigTable">
        <tbody class="scrollContent">
            <tr class="normalRow">
                <td>Cell Content 1</td>
                <td>Cell Content 2</td>
                <td>Sep 16, 2007 01:54 AM</td>
            </tr>
            <tr class="alternateRow">
                <td>More Cell Content 1</td>
                <td>More Cell Content 2</td>
                <td>Sep 16, 2007 01:54 AM</td>
            </tr>
            <tr class="normalRow">
                <td>Even More Cell Content 1</td>
                <td>Even More Cell Content 2</td>
                <td>Sep 16, 2007 01:54 AM</td>
            </tr>
        <tr class="alternateRow">
                <td>And Repeat 1</td>
                <td>And Repeat 2</td>
                <td>Sep 16, 2007 01:54 AM</td>
            </tr>

                    <tr class="alternateRow">
                <td>And Repeat 1</td>
                <td>And Repeat 2</td>
                <td>Sep 16, 2007 01:54 AM</td>
            </tr>
                    <tr class="alternateRow">
                <td>And Repeat 1</td>
                <td>And Repeat 2</td>
                <td>Sep 16, 2007 01:54 AM</td>
            </tr>
                    <tr class="alternateRow">
                <td>And Repeat 1</td>
                <td>And Repeat 2</td>
                <td>Sep 16, 2007 01:54 AM</td>
            </tr>
                    <tr class="alternateRow">
                <td>And Repeat 1</td>
                <td>And Repeat 2</td>
                <td>Sep 16, 2007 01:54 AM</td>
            </tr>
                    <tr class="alternateRow">
                <td>And Repeat 1</td>
                <td>And Repeat 2</td>
                <td>Sep 16, 2007 01:54 AM</td>
            </tr>
                    <tr class="alternateRow">
                <td>And Repeat 1</td>
                <td>And Repeat 2</td>
                <td>Sep 16, 2007 01:54 AM</td>
            </tr>
                    <tr class="alternateRow">
                <td>And Repeat 1</td>
                <td>And Repeat 2</td>
                <td>Sep 16, 2007 01:54 AM</td>
            </tr>
                    <tr class="alternateRow">
                <td>And Repeat 1</td>
                <td>And Repeat 2</td>
                <td>Sep 16, 2007 01:54 AM</td>
            </tr>
                    <tr class="alternateRow">
                <td>And Repeat 1</td>
                <td>And Repeat 2</td>
                <td>Sep 16, 2007 01:54 AM</td>
            </tr>
                    <tr class="alternateRow">
                <td>And Repeat 1</td>
                <td>And Repeat 2</td>
                <td>Sep 16, 2007 01:54 AM</td>
            </tr>
                    <tr class="alternateRow">
                <td>And Repeat 1</td>
                <td>And Repeat 2</td>
                <td>Sep 16, 2007 01:54 AM</td>
            </tr>
                    <tr class="alternateRow">
                <td>And Repeat 1</td>
                <td>And Repeat 2</td>
                <td>Sep 16, 2007 01:54 AM</td>
            </tr>
                    <tr class="alternateRow">
                <td>And Repeat 1</td>
                <td>And Repeat 2</td>
                <td>Sep 16, 2007 01:54 AM</td>
            </tr>
                    <tr class="alternateRow">
                <td>And Repeat 1</td>
                <td>And Repeat 2</td>
                <td>Sep 16, 2007 01:54 AM</td>
            </tr>
                    <tr class="alternateRow">
                <td>And Repeat 1</td>
                <td>And Repeat 2</td>
                <td>Sep 16, 2007 01:54 AM</td>
            </tr>
                    <tr class="alternateRow">
                <td>And Repeat 1</td>
                <td>And Repeat 2</td>
                <td>Sep 16, 2007 01:54 AM</td>
            </tr>
                    <tr class="alternateRow">
                <td>And Repeat 1</td>
                <td>And Repeat 2</td>
                <td>Sep 16, 2007 01:54 AM</td>
            </tr>
        </tbody>
    </table>
</div>  

or try this

#listBevel, #listTable {
    position: absolute;
    z-index: 2;
    border: 1px solid #989898;
    top: 85px;
    left: 227px;
    right: 37px;
    height: 270px;
    min-width: 654px;
}

/* @group List Table Headers */

#listTableHeaders {
    position: absolute;
    z-index: 3;
    top: 67px;
    left: 39px;
    right: 37px;
    height: 500px;
    min-width: 654px;
    border: 1px solid #989898;
    overflow: hidden;
    overflow-y: scroll;
}

.tableHeaderShadow {
    background: url(/images/interface/bevel_shadow.png) repeat-x;
    position: fixed;
    height: 5px;
    top: 105px;
    right: 53px;
    left: 228px;
    min-width: 639px;
}

#scrollBarCoverContainer {
    position: fixed;
    z-index: 5;
    top: 86px;
    left: 228px;
    right: 38px;
    height: 0;
    min-width: 654px;
    font-size: 11px;
    border: 1px none #989898;
    text-align: right;
}

#scrollBarCoverUp {
    background: url(/images/interface/list_header_bg.png) repeat-x;
    width: 14px;
    height: 18px;
    border-left: 1px solid #e5e5e5;
    float: right;
}

table#entryListHeaders th img.sortArrow {
    float: right;
}

table#entryListHeaders th a {
    color: #000;
    text-decoration: none;
    display: block;
    height: 18px;
}

table#entryListHeaders th:hover {
    background-position: 0 -18px;
    cursor: default;
}

table#entryListHeaders th {
    background: url(/images/interface/list_header_bg.png) repeat-x;
    border-left: 1px solid #e5e5e5;
    border-right: 1px solid #a5a5a5;
    text-align: left;
    padding: 0 5px;
    margin: 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    height: 18px;
    width: 42%;
    font-size: 11px;
    line-height: 1.6em;
    text-shadow: #fff 0 1px 0;
}
table#entryListHeaders th + th {
    width: 32%;
}

table#entryListHeaders th.selectedHeader {
    text-shadow: #d8e6ff 0 1px 0;
    background-image: url(/images/interface/list_header_selected.png);
    border-left-color: #c2d4f2;
}

#listTable {
    background-color: #fefefe;
    top: 104px;
    height: 251px;
    overflow: auto;
    overflow-x: hidden;
    overflow-y: scroll;
    font-size: 11px;
    border-collapse: collapse;
}

table#entryList {
}

table#entryList td {
    width: 42%;
}

span.truncateText {
    display: block;
    height: 18px;
    overflow: hidden;
}




tbody.scrollContent td, tbody.scrollContent tr.normalRow td {
    border-right: 1px hidden #cbd1d8;
    padding: 1px 5px;
    height: 18px;
    line-height: 1.6em;
    margin: 0;
    border-left-style: hidden;
    border-left-width: 1px;
}

tbody.scrollContent tr.alternateRow {
    background: #eaf2ff;
}

tbody.scrollContent tr.selectedRow td {
    background: url(/images/interface/selected_row.png) repeat-x;
    color: #fff;
    border-right-style: hidden;
}

table#entryList td + td {
    width: 32%;
}

tbody.scrollContent tr:hover, tbody.scrollContent tr.alternateRow:hover {
    background-color: #d8e7ff;
    cursor: default;
}




<div id="scrollBarCoverContainer">

        <div id="scrollBarCoverUp"></div>

        <div class="tableHeaderShadow"></div>


    </div>

    <div id="listTableHeaders">

        <table id="entryListHeaders" border="0" cellpadding="0" cellspacing="0" width="100%">

        <thead class="fixedHeader">
            <tr>
                <th id="selectedHeader">Name</th>
                <th>Domain</th>

                <th>>Modified</th>
            </tr>
        </thead>
        <tbody class="scrollContent">
            <tr class="normalRow">
                <td>Cell Content 1</td>
                <td>Cell Content 2</td>

                <td>Sep 16, 2007 01:54 AM</td>
            </tr>
            <tr class="alternateRow">
                <td>More Cell Content 1</td>
                <td>More Cell Content 2</td>
                <td>Sep 16, 2007 01:54 AM</td>
            </tr>

            <tr class="normalRow">
                <td>Even More Cell Content 1</td>
                <td>Even More Cell Content 2</td>
                <td>Sep 16, 2007 01:54 AM</td>
            </tr>



            <tr class="alternateRow">

                <td>And Repeat 1</td>
                <td>And Repeat 2</td>
                <td>Sep 16, 2007 01:54 AM</td>
            </tr>

                    <tr class="alternateRow">
                <td>And Repeat 1</td>
                <td>And Repeat 2</td>

                <td>Sep 16, 2007 01:54 AM</td>
            </tr>
                    <tr class="alternateRow">
                <td>And Repeat 1</td>
                <td>And Repeat 2</td>
                <td>Sep 16, 2007 01:54 AM</td>
            </tr>

                    <tr class="alternateRow">
                <td>And Repeat 1</td>
                <td>And Repeat 2</td>
                <td>Sep 16, 2007 01:54 AM</td>
            </tr>
                    <tr class="alternateRow">
                <td>And Repeat 1</td>

                <td>And Repeat 2</td>
                <td>Sep 16, 2007 01:54 AM</td>
            </tr>
                    <tr class="alternateRow">
                <td>And Repeat 1</td>
                <td>And Repeat 2</td>
                <td>Sep 16, 2007 01:54 AM</td>

            </tr>
                    <tr class="alternateRow">
                <td>And Repeat 1</td>
                <td>And Repeat 2</td>
                <td>Sep 16, 2007 01:54 AM</td>
            </tr>
                    <tr class="alternateRow">

                <td>And Repeat 1</td>
                <td>And Repeat 2</td>
                <td>Sep 16, 2007 01:54 AM</td>
            </tr>
                    <tr class="alternateRow">
                <td>And Repeat 1</td>
                <td>And Repeat 2</td>

                <td>Sep 16, 2007 01:54 AM</td>
            </tr>
                    <tr class="alternateRow">
                <td>And Repeat 1</td>
                <td>And Repeat 2</td>
                <td>Sep 16, 2007 01:54 AM</td>
            </tr>

                    <tr class="alternateRow">
                <td>And Repeat 1</td>
                <td>And Repeat 2</td>
                <td>Sep 16, 2007 01:54 AM</td>
            </tr>
                    <tr class="alternateRow">
                <td>And Repeat 1</td>

                <td>And Repeat 2</td>
                <td>Sep 16, 2007 01:54 AM</td>
            </tr>
                    <tr class="alternateRow">
                <td>And Repeat 1</td>
                <td>And Repeat 2</td>
                <td>Sep 16, 2007 01:54 AM</td>

            </tr>
                    <tr class="alternateRow">
                <td>And Repeat 1</td>
                <td>And Repeat 2</td>
                <td>Sep 16, 2007 01:54 AM</td>
            </tr>
                    <tr class="alternateRow">

                <td>And Repeat 1</td>
                <td>And Repeat 2</td>
                <td>Sep 16, 2007 01:54 AM</td>
            </tr>
                    <tr class="alternateRow">
                <td>And Repeat 1</td>
                <td>And Repeat 2</td>

                <td>Sep 16, 2007 01:54 AM</td>
            </tr>
                    <tr class="alternateRow">
                <td>And Repeat 1</td>
                <td>And Repeat 2</td>
                <td>Sep 16, 2007 01:54 AM</td>
            </tr>

                    <tr class="alternateRow">
                <td>And Repeat 1</td>
                <td>And Repeat 2</td>
                <td>Sep 16, 2007 01:54 AM</td>
            </tr>
        </tbody>
    </table>

</div>  
Sarin Jacob Sunny
  • 2,138
  • 3
  • 29
  • 61
  • Again, this is a fixed table. It does work for a fixed height table. If the tables height and width are specified I can get a fixed table header. Another issue is that my table uses a jquery sort and it requires the headers to be part of the table. I am willing to change this if there is a good solution for the fixed headers out there. Thanks – acmeyer9 Nov 25 '11 at 15:22
  • @user1054494 specify you needs first.. instead of putting them in your comments edit your question and explain it u7sing what you want what you are trying.. Which code you are currently using etc.. – Sarin Jacob Sunny Nov 28 '11 at 05:22
0

This is a progressive-enhancement solution that should be cross-browser compatible, thanks to jQuery.

    <!DOCTYPE html>
<html>
<head>
    <title></title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <script src="http://code.jquery.com/jquery-latest.min.js"></script>
    <script type="text/javascript">
        var sizeColWidths = function() {
            // reset column widths (in case previously set)
            $('#fruitTable td, #fruitTable th').css('width', 'auto');
            $('#fruitTable').removeClass('scrollableTable');
            $('#fruitTable tbody').css('width', 'auto');
            // record current column widths
            var i=0, colWidth=new Array();
            $('#fruitTable th').each(function() {
                colWidth[i++] = $(this).outerWidth();
            });
            // freeze the current column widths
            $('#fruitTable tr').each(function() {
                var i=0;
                $('th, td', this).each(function() {
                    $(this).css('width', colWidth[i++] + 'px');
                })
            });
            // make the table body scroll (add tbody width for scroll bar)
            $('#fruitTable').addClass('scrollableTable');
            $('#fruitTable tbody').css('width', ($('#fruitTable thead').width() + 20) +'px');
        };
        $(document).ready(function() {sizeColWidths()});
        $(window).resize(function() {sizeColWidths()});
    </script>
    <style type="text/css">
        .scrollableTable tbody {
            display: block;
            height:50px;
            overflow-y:auto;
        }
        .scrollableTable tr {
            display: block;
        }
    </style>
</head>
<body>
    <table id="fruitTable">
        <thead>
            <tr>
                <th>Fruit</th>
                <th>Color</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>Apples</td>
                <td>Red</td>
            </tr>
            <tr>
                <td>Bananas</td>
                <td>Yellow</td>
            </tr>
            <tr>
                <td>Grapes</td>
                <td>Purple</td>
            </tr>     
            <tr>
                <td>Limes</td>
                <td>Green</td>
            </tr>
            <tr>
                <td>Oranges</td>
                <td>Orange</td>
            </tr>
        </tbody>
    </table>
</body>
</html>
Nate Barr
  • 4,640
  • 2
  • 25
  • 21
  • Unfortunately this fixed the height of the table to be very small and only adjusted the header columns with the page, not the table body columns as well. – acmeyer9 Nov 25 '11 at 15:18
  • Then change the height to suit your needs! I chose a small height to force a scrollbar in the short example. And it should change widths of both thead and tbody...they work for me. What browser are you using? – Nate Barr Nov 25 '11 at 17:36