是否有跨浏览器的CSS/JavaScript技术来显示一个长HTML表,使列标题保持固定在屏幕上,而不随表体滚动。想想微软Excel中的“冻结窗格”效果。

我希望能够滚动表的内容,但总是能够在顶部看到列标题。


当前回答

对于那些尝试了Maximilian Hils给出的很好的解决方案,但没有成功地让它在Internet Explorer上工作的人,我遇到了同样的问题(Internet Explorer 11),并找到了问题所在。

在Internet Explorer 11中,样式转换(至少使用translate)在<THEAD>上不起作用。我通过将样式应用到循环中的所有<TH>来解决这个问题。这工作。我的JavaScript代码是这样的:

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;
  }
});

在我的例子中,表格是ASP.NET中的GridView。起初我认为这是因为它没有<THEAD>,但即使我强迫它有一个,它也不工作。然后我发现了我上面写的东西。

这是一个非常好的简单的解决方案。在Chrome浏览器上它是完美的,在Firefox上有点不稳定,在ie浏览器上就更不稳定了。但总的来说,这是个好办法。

其他回答

补充@Daniel Waltrip的回答。表需附以div位置:相对,以便与工作位置:粘。所以我想在这里发布我的示例代码。

CSS

/* Set table width/height as you want.*/
div.freeze-header {
  position: relative;
  max-height: 150px;
  max-width: 400px;
  overflow:auto;
}

/* Use position:sticky to freeze header on top*/
div.freeze-header > table > thead > tr > th {
  position: sticky;
  top: 0;
  background-color:yellow;
}

/* below is just table style decoration.*/
div.freeze-header > table {
  border-collapse: collapse;
}

div.freeze-header > table td {
  border: 1px solid black;
}

HTML

<html>
<body>
  <div>
   other contents ...
  </div>
  <div>
   other contents ...
  </div>
  <div>
   other contents ...
  </div>

  <div class="freeze-header">
    <table>
       <thead>
         <tr>
           <th> header 1 </th>
           <th> header 2 </th>
           <th> header 3 </th>
           <th> header 4 </th>
           <th> header 5 </th>
           <th> header 6 </th>
           <th> header 7 </th>
           <th> header 8 </th>
           <th> header 9 </th>
           <th> header 10 </th>
           <th> header 11 </th>
           <th> header 12 </th>
           <th> header 13 </th>
           <th> header 14 </th>
           <th> header 15 </th>
          </tr>
       </thead>
       <tbody>
         <tr>
           <td> data 1 </td>
           <td> data 2 </td>
           <td> data 3 </td>
           <td> data 4 </td>
           <td> data 5 </td>
           <td> data 6 </td>
           <td> data 7 </td>
           <td> data 8 </td>
           <td> data 9 </td>
           <td> data 10 </td>
           <td> data 11 </td>
           <td> data 12 </td>
           <td> data 13 </td>
           <td> data 14 </td>
           <td> data 15 </td>
          </tr>         
         <tr>
           <td> data 1 </td>
           <td> data 2 </td>
           <td> data 3 </td>
           <td> data 4 </td>
           <td> data 5 </td>
           <td> data 6 </td>
           <td> data 7 </td>
           <td> data 8 </td>
           <td> data 9 </td>
           <td> data 10 </td>
           <td> data 11 </td>
           <td> data 12 </td>
           <td> data 13 </td>
           <td> data 14 </td>
           <td> data 15 </td>
          </tr>         
         <tr>
           <td> data 1 </td>
           <td> data 2 </td>
           <td> data 3 </td>
           <td> data 4 </td>
           <td> data 5 </td>
           <td> data 6 </td>
           <td> data 7 </td>
           <td> data 8 </td>
           <td> data 9 </td>
           <td> data 10 </td>
           <td> data 11 </td>
           <td> data 12 </td>
           <td> data 13 </td>
           <td> data 14 </td>
           <td> data 15 </td>
          </tr>         
         <tr>
           <td> data 1 </td>
           <td> data 2 </td>
           <td> data 3 </td>
           <td> data 4 </td>
           <td> data 5 </td>
           <td> data 6 </td>
           <td> data 7 </td>
           <td> data 8 </td>
           <td> data 9 </td>
           <td> data 10 </td>
           <td> data 11 </td>
           <td> data 12 </td>
           <td> data 13 </td>
           <td> data 14 </td>
           <td> data 15 </td>
          </tr>         
         <tr>
           <td> data 1 </td>
           <td> data 2 </td>
           <td> data 3 </td>
           <td> data 4 </td>
           <td> data 5 </td>
           <td> data 6 </td>
           <td> data 7 </td>
           <td> data 8 </td>
           <td> data 9 </td>
           <td> data 10 </td>
           <td> data 11 </td>
           <td> data 12 </td>
           <td> data 13 </td>
           <td> data 14 </td>
           <td> data 15 </td>
          </tr>         
         <tr>
           <td> data 1 </td>
           <td> data 2 </td>
           <td> data 3 </td>
           <td> data 4 </td>
           <td> data 5 </td>
           <td> data 6 </td>
           <td> data 7 </td>
           <td> data 8 </td>
           <td> data 9 </td>
           <td> data 10 </td>
           <td> data 11 </td>
           <td> data 12 </td>
           <td> data 13 </td>
           <td> data 14 </td>
           <td> data 15 </td>
          </tr>         
         <tr>
           <td> data 1 </td>
           <td> data 2 </td>
           <td> data 3 </td>
           <td> data 4 </td>
           <td> data 5 </td>
           <td> data 6 </td>
           <td> data 7 </td>
           <td> data 8 </td>
           <td> data 9 </td>
           <td> data 10 </td>
           <td> data 11 </td>
           <td> data 12 </td>
           <td> data 13 </td>
           <td> data 14 </td>
           <td> data 15 </td>
          </tr>         
         <tr>
           <td> data 1 </td>
           <td> data 2 </td>
           <td> data 3 </td>
           <td> data 4 </td>
           <td> data 5 </td>
           <td> data 6 </td>
           <td> data 7 </td>
           <td> data 8 </td>
           <td> data 9 </td>
           <td> data 10 </td>
           <td> data 11 </td>
           <td> data 12 </td>
           <td> data 13 </td>
           <td> data 14 </td>
           <td> data 15 </td>
          </tr>         
       </tbody>
    </table>
  </div>
</body>
</html>

Demo

所有从CSS规范之外解决这个问题的尝试都是我们真正想要的:按照THEAD的隐含承诺交付。

这个冻结表头的问题长期以来一直是HTML/CSS中的一个开放性问题。

在理想的情况下,应该有一个纯css解决方案来解决这个问题。不幸的是,似乎没有一个合适的。

相关标准-关于此主题的讨论包括:

粘性定位提案网址:http://lists.w3.org/Archives/Public/www-style/2012Jun/0627.html 请在阿特金斯提出的“位置-根”、“位置-包含”或“位置-限制”的建议中打上标签:http://www.xanthir.com/blog/b48H0

更新:Firefox的发货位置:粘在版本32。每个人都会赢!

我开发了一个简单的轻量级jQuery插件,用于将格式良好的HTML表转换为具有固定表头和列的可滚动表。

该插件可以很好地匹配固定部分与可滚动部分的像素到像素的定位。此外,您还可以冻结水平滚动时始终显示在视图中的列数。

演示和文档:http://meetselva.github.io/fixed-table-rows-cols/

GitHub存储库:https://github.com/meetselva/fixed-table-rows-cols

下面是带有固定表头的简单表的用法,

$(<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'}
              ]
});

这是一个用于固定表头的jQuery插件。它允许整个页面滚动,当它到达顶部时冻结标题。它与Twitter Bootstrap表一起工作得很好。

GitHub存储库:https://github.com/oma/table-fixed-header

它不只是滚动表内容。看看其他的工具,就像这些答案中的一个。你来决定最适合你的情况。

<html>
<head>
    <script src="//cdn.jsdelivr.net/npm/jquery@3.2.1/dist/jquery.min.js"></script>
    <script>
        function stickyTableHead (tableID) {
            var $tmain = $(tableID);
            var $tScroll = $tmain.children("thead")
                .clone()
                .wrapAll('<table id="tScroll" />')
                .parent()
                .addClass($(tableID).attr("class"))
                .css("position", "fixed")
                .css("top", "0")
                .css("display", "none")
                .prependTo("#tMain");

            var pos = $tmain.offset().top + $tmain.find(">thead").height();


            $(document).scroll(function () {
                var dataScroll = $tScroll.data("scroll");
                dataScroll = dataScroll || false;
                if ($(this).scrollTop() >= pos) {
                    if (!dataScroll) {
                        $tScroll
                            .data("scroll", true)
                            .show()
                            .find("th").each(function () {
                                $(this).width($tmain.find(">thead>tr>th").eq($(this).index()).width());
                            });
                    }
                } else {
                    if (dataScroll) {
                        $tScroll
                            .data("scroll", false)
                            .hide()
                        ;
                    }
                }
            });
        }

        $(document).ready(function () {
            stickyTableHead('#tMain');
        });
    </script>
</head>

<body>
    gfgfdgsfgfdgfds<br/>
    gfgfdgsfgfdgfds<br/>
    gfgfdgsfgfdgfds<br/>
    gfgfdgsfgfdgfds<br/>
    gfgfdgsfgfdgfds<br/>
    gfgfdgsfgfdgfds<br/>

    <table id="tMain" >
        <thead>
        <tr>
            <th>1</th> <th>2</th><th>3</th> <th>4</th><th>5</th> <th>6</th><th>7</th> <th>8</th>

        </tr>
        </thead>
        <tbody>
            <tr><td>11111111111111111111111111111111111111111111111111111111</td><td>2</td><td>3</td><td>4</td><td>5555555</td><td>66666666666</td><td>77777777777</td><td>8888888888888888</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5555555</td><td>66666666666</td><td>77777777777</td><td>8888888888888888</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5555555</td><td>66666666666</td><td>77777777777</td><td>8888888888888888</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5555555</td><td>66666666666</td><td>77777777777</td><td>8888888888888888</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5555555</td><td>66666666666</td><td>77777777777</td><td>8888888888888888</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5555555</td><td>66666666666</td><td>77777777777</td><td>8888888888888888</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5555555</td><td>66666666666</td><td>77777777777</td><td>8888888888888888</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5555555</td><td>66666666666</td><td>77777777777</td><td>8888888888888888</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5555555</td><td>66666666666</td><td>77777777777</td><td>8888888888888888</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5555555</td><td>66666666666</td><td>77777777777</td><td>8888888888888888</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5555555</td><td>66666666666</td><td>77777777777</td><td>8888888888888888</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5555555</td><td>66666666666</td><td>77777777777</td><td>8888888888888888</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5555555</td><td>66666666666</td><td>77777777777</td><td>8888888888888888</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5555555</td><td>66666666666</td><td>77777777777</td><td>8888888888888888</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5555555</td><td>66666666666</td><td>77777777777</td><td>8888888888888888</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5555555</td><td>66666666666</td><td>77777777777</td><td>8888888888888888</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5555555</td><td>66666666666</td><td>77777777777</td><td>8888888888888888</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5555555</td><td>66666666666</td><td>77777777777</td><td>8888888888888888</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5555555</td><td>66666666666</td><td>77777777777</td><td>8888888888888888</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5555555</td><td>66666666666</td><td>77777777777</td><td>8888888888888888</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5555555</td><td>66666666666</td><td>77777777777</td><td>8888888888888888</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5555555</td><td>66666666666</td><td>77777777777</td><td>8888888888888888</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5555555</td><td>66666666666</td><td>77777777777</td><td>8888888888888888</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5555555</td><td>66666666666</td><td>77777777777</td><td>8888888888888888</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5555555</td><td>66666666666</td><td>77777777777</td><td>8888888888888888</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5555555</td><td>66666666666</td><td>77777777777</td><td>8888888888888888</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5555555</td><td>66666666666</td><td>77777777777</td><td>8888888888888888</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5555555</td><td>66666666666</td><td>77777777777</td><td>8888888888888888</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5555555</td><td>66666666666</td><td>77777777777</td><td>8888888888888888</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5555555</td><td>66666666666</td><td>77777777777</td><td>8888888888888888</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5555555</td><td>66666666666</td><td>77777777777</td><td>8888888888888888</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5555555</td><td>66666666666</td><td>77777777777</td><td>8888888888888888</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5555555</td><td>66666666666</td><td>77777777777</td><td>8888888888888888</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5555555</td><td>66666666666</td><td>77777777777</td><td>8888888888888888</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5555555</td><td>66666666666</td><td>77777777777</td><td>8888888888888888</td></tr>
            <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5555555</td><td>66666666666</td><td>77777777777</td><td>8888888888888888</td></tr>
        </tbody>
    </table>
</body>
</html>