HTML table with fixed headers?

2018-12-31 02:14发布

Is there a cross-browser CSS/JavaScript technique to display a long HTML table such that the column headers stay fixed on-screen and do not scroll with the table body. Think of the "freeze panes" effect in Microsoft Excel.

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.

28条回答
零度萤火
2楼-- · 2018-12-31 02:40

Most of the solutions posted here require jQuery. If you are looking for a framework independent solution try Grid: http://www.matts411.com/post/grid/

It's hosted on Github here: https://github.com/mmurph211/Grid

Not only does it support fixed headers, it also supports fixed left columns and footers, among other things.

查看更多
笑指拈花
3楼-- · 2018-12-31 02:42

For those who tried the nice solution given by Maximilian Hils, and did not succeed to get it to work with Internet Explorer, I had the same problem (Internet Explorer 11) and found out what was the problem.

In Internet Explorer 11 the style transform (at least with translate) does not work on <THEAD>. I solved this by instead applying the style to all the <TH> in a loop. That worked. My JavaScript code looks like this:

document.getElementById('pnlGridWrap').addEventListener("scroll", function () {
  var translate = "translate(0," + this.scrollTop + "px)";
  var myElements = this.querySelectorAll("th");
  for (var i = 0; i < myElements.length; i++) {
    myElements[i].style.transform=translate;
  }
});

In my case the table was a GridView in ASP.NET. First I thought it was because it had no <THEAD>, but even when I forced it to have one, it did not work. Then I found out what I wrote above.

It is a very nice and simple solution. On Chrome it is perfect, on Firefox a bit jerky, and on Internet Explorer even more jerky. But all in all a good solution.

查看更多
无与为乐者.
4楼-- · 2018-12-31 02:42

I developed a simple light-weight jQuery plug-in for converting a well formatted HTML table to a scrollable table with fixed table header and columns.

The plugin works well to match pixel-to-pixel positioning the fixed section with the scrollable section. Additionally, you could also freeze the number of columns that will be always in view when scrolling horizontally.

Demo & Documentation: http://meetselva.github.io/fixed-table-rows-cols/

GitHub repository: https://github.com/meetselva/fixed-table-rows-cols

Below is the usage for a simple table with a fixed header,

$(<table selector>).fxdHdrCol({
    width:     "100%",
    height:    200,
    colModal: [{width: 30, align: 'center'},
               {width: 70, align: 'center'}, 
               {width: 200, align: 'left'}, 
               {width: 100, align: 'center'}, 
               {width: 70, align: 'center'}, 
               {width: 250, align: 'center'}
              ]
});
查看更多
美炸的是我
5楼-- · 2018-12-31 02:43

This can be cleanly solved in four lines of code.

If you only care about modern browsers, a fixed header can be achieved much easier by using CSS transforms. Sounds odd, but works great:

  • HTML and CSS stay as-is.
  • No external JavaScript dependencies.
  • Four lines of code.
  • Works for all configurations (table-layout: fixed, etc.).
document.getElementById("wrap").addEventListener("scroll", function(){
   var translate = "translate(0,"+this.scrollTop+"px)";
   this.querySelector("thead").style.transform = translate;
});

Support for CSS transforms is widely available except for Internet Explorer 8-.

Here is the full example for reference:

document.getElementById("wrap").addEventListener("scroll",function(){
   var translate = "translate(0,"+this.scrollTop+"px)";
   this.querySelector("thead").style.transform = translate;
});
/* Your existing container */
#wrap {
    overflow: auto;
    height: 400px;
}

/* CSS for demo */
td {
    background-color: green;
    width: 200px;
    height: 100px;
}
<div id="wrap">
    <table>
        <thead>
            <tr>
                <th>Foo</th>
                <th>Bar</th>
            </tr>
        </thead>
        <tbody>
            <tr><td></td><td></td></tr>
            <tr><td></td><td></td></tr>
            <tr><td></td><td></td></tr>
            <tr><td></td><td></td></tr>
            <tr><td></td><td></td></tr>
            <tr><td></td><td></td></tr>
            <tr><td></td><td></td></tr>
            <tr><td></td><td></td></tr>
            <tr><td></td><td></td></tr>
            <tr><td></td><td></td></tr>
            <tr><td></td><td></td></tr>
            <tr><td></td><td></td></tr>
        </tbody>
    </table>
</div>

查看更多
皆成旧梦
6楼-- · 2018-12-31 02:43

All of the attempts to solve this from outside the CSS specification are pale shadows of what we really want: Delivery on the implied promise of THEAD.

This frozen-headers-for-a-table issue has been an open wound in HTML/CSS for a long time.

In a perfect world, there would be a pure-CSS solution for this problem. Unfortunately, there doesn't seem to be a good one in place.

Relevant standards-discussions on this topic include:

UPDATE: Firefox shipped position:sticky in version 32. Everyone wins!

查看更多
呛了眼睛熬了心
7楼-- · 2018-12-31 02:43

Two divs, one for header, one for data. Make the data div scrollable, and use JavaScript to set the width of the columns in the header to be the same as the widths in the data. I think the data columns widths need to be fixed rather than dynamic.

查看更多
登录 后发表回答