带固定标题的仅CSS滚动表

我有一个解决scheme,我可以使用小jQuery和CSS创build带有固定页眉/页脚的可滚动表格 – 但是我正在寻找一种方法,使其成为一个跨浏览器兼容的CSS解决scheme。

要清楚的是,我正在试图做的只是使用一个table标记(它是有效的子标记, colgroupcoltheadtbodytfoottrthtd ),但是采用一组CSS规则符合以下条件:

  1. 必须保持页眉/页脚/内容行之间的列alignment
  2. 当内容垂直滚动时,必须允许页眉/页脚保持固定
  3. 不能要求任何jQuery或其他JavaScript来提供function
  4. 只能使用上面提供的标签

这个代码示例: http : //jsfiddle.net/TroyAlford/SNKfd/显示我目前的做法。 大多数的JS只是随机的值填充表,但最后一部分驱动左/右滚动性。

 $tbody.bind('scroll', function(ev) { var $css = { 'left': -ev.target.scrollLeft }; $thead.css($css); $tfoot.css($css); }); 

注:所提供的示例在IE中不能正确呈现,并要求jQuery提供水平滚动。 无论如何,我并不关心水平滚动,所以如果一个解决scheme不这样做就没关系。

惊讶的使用flexbox的解决scheme尚未公布。

这是我的解决scheme:使用display: flex和基本用法:after (感谢Luggage )保持alignment,即使滚动条填充了tbody一点。 这已经在Chrome 45,Firefox 39和MS Edge中得到validation。 可以修改前缀属性以在IE11中工作,在IE10中使用CSS hack和2012 flexbox语法进行修改 。

注意表格的宽度可以修改; 这甚至在100%宽度工作。

唯一需要注意的是所有的表格单元必须具有相同的宽度。 下面是一个清晰的例子,但是当单元格内容不一样时(表格单元格都具有相同的宽度和单词换行,迫使flexbox保持它们不pipe内容的相同宽度),这可以很好地工作。 这是一个单元格内容不同的例子。

只需将.scroll类应用于要滚动的表格,并确保它具有一个thead

 .scroll { border: 0; border-collapse: collapse; } .scroll tr { display: flex; } .scroll td { padding: 3px; flex: 1 auto; border: 1px solid #aaa; width: 1px; word-wrap: break; } .scroll thead tr:after { content: ''; overflow-y: scroll; visibility: hidden; height: 0; } .scroll thead th { flex: 1 auto; display: block; border: 1px solid #000; } .scroll tbody { display: block; width: 100%; overflow-y: auto; height: 200px; } 
 <table class="scroll" width="400px"> <thead> <tr> <th>Header</th> <th>Header</th> <th>Header</th> <th>Header</th> <th>Header</th> <th>Header</th> </tr> </thead> <tr> <td>Data</td> <td>Data</td> <td>Data</td> <td>Data</td> <td>Data</td> <td>Data</td> </tr> <tr> <td>Data</td> <td>Data</td> <td>Data</td> <td>Data</td> <td>Data</td> <td>Data</td> </tr> <tr> <td>Data</td> <td>Data</td> <td>Data</td> <td>Data</td> <td>Data</td> <td>Data</td> </tr> <tr> <td>Data</td> <td>Data</td> <td>Data</td> <td>Data</td> <td>Data</td> <td>Data</td> </tr> <tr> <td>Data</td> <td>Data</td> <td>Data</td> <td>Data</td> <td>Data</td> <td>Data</td> </tr> <tr> <td>Data</td> <td>Data</td> <td>Data</td> <td>Data</td> <td>Data</td> <td>Data</td> </tr> <tr> <td>Data</td> <td>Data</td> <td>Data</td> <td>Data</td> <td>Data</td> <td>Data</td> </tr> <tr> <td>Data</td> <td>Data</td> <td>Data</td> <td>Data</td> <td>Data</td> <td>Data</td> </tr> <tr> <td>Data</td> <td>Data</td> <td>Data</td> <td>Data</td> <td>Data</td> <td>Data</td> </tr> <tr> <td>Data</td> <td>Data</td> <td>Data</td> <td>Data</td> <td>Data</td> <td>Data</td> </tr> <tr> <td>Data</td> <td>Data</td> <td>Data</td> <td>Data</td> <td>Data</td> <td>Data</td> </tr> <tr> <td>Data</td> <td>Data</td> <td>Data</td> <td>Data</td> <td>Data</td> <td>Data</td> </tr> <tr> <td>Data</td> <td>Data</td> <td>Data</td> <td>Data</td> <td>Data</td> <td>Data</td> </tr> <tr> <td>Data</td> <td>Data</td> <td>Data</td> <td>Data</td> <td>Data</td> <td>Data</td> </tr> <tr> <td>Data</td> <td>Data</td> <td>Data</td> <td>Data</td> <td>Data</td> <td>Data</td> </tr> <tr> <td>Data</td> <td>Data</td> <td>Data</td> <td>Data</td> <td>Data</td> <td>Data</td> </tr> <tr> <td>Data</td> <td>Data</td> <td>Data</td> <td>Data</td> <td>Data</td> <td>Data</td> </tr> <tr> <td>Data</td> <td>Data</td> <td>Data</td> <td>Data</td> <td>Data</td> <td>Data</td> </tr> </table> 

据我所知,没有标准的方法来实现这个只有CSS,但我认为应该有。 Mozilla浏览器曾经支持带有滚动主体的固定标题,但在过去的几年中它们已经将其删除。

经过一番研究,包括find这个post,朋友刚刚为我开发了这个解决scheme ; 它使用Javascript,但没有jar头库,并且HTML标记的唯一要求是该表具有一个id名称。 然后,在window.onload中,为每个给出id,height和width的表调用一个Javascript函数。 如果在浏览器中禁用Javascript,整个表将按照其原始标记显示。 如果启用Javascript,表格适合指定的高度和宽度,tbody滚动,如果存在,则它们固定在顶部和底部。

受@ Purag的回答启发,这是另一个flexbox解决scheme:

 /* basic settings */ table { display: flex; flex-direction: column; width: 200px; } tr { display: flex; } th:nth-child(1), td:nth-child(1) { flex-basis: 35%; } th:nth-child(2), td:nth-child(2) { flex-basis: 65%; } thead, tbody { overflow-y: scroll; } tbody { height: 100px; } /* color settings*/ table, th, td { border: 1px solid black; } tr:nth-child(odd) { background: #EEE; } tr:nth-child(even) { background: #AAA; } thead tr:first-child { background: #333; } th:first-child, td:first-child { background: rgba(200,200,0,0.7); } th:last-child, td:last-child { background: rgba(255,200,0,0.7); } 
 <table> <thead> <tr> <th>a <th>bbbb <tbody> <tr> <td>fooo vsync dynamic <td>bar <tr> <td>a <td>b <tr> <td>a <td>b <tr> <td>a <td>b <tr> <td>a <td>b <tr> <td>a <td>b <tr> <td>a <td>b </table> 

我很容易使用这个代码实现了这一点:

所以你有这样的结构:

 <table> <thead><tr></tr></thead> <tbody><tr></tr></tbody> </table> 

只是用以下方式来devise风格:

 <style> thead{ position: -webkit-sticky; position: -moz-sticky; position: -ms-sticky; position: -o-sticky; position: sticky; top: 0px; } </style> 

需要考虑的三件事:

首先,这个属性是新的。 除了基于Webkit的浏览器的testing版外,它完全不受支持。 所以警告格式。 再一次,如果你真的想让你的用户从粘性头文件中获益,那就去一个javascript实现。

其次,如果您使用它,则需要包含供应商前缀。 也许立场:粘一天会有用。 现在,你需要使用位置:-webkit-sticky(和其他人;在这篇文章中进一步检查CSS的块)。

第三,目前没有任何定位缺省,所以你至less需要包含top:0; 在与之相同的css声明中:-webkit-sticky。 否则,它只会滚动屏幕。

如果您可以select给表格单元格固定的宽度(以及固定的标题高度),则可以使用position: fixed选项:

http://jsfiddle.net/thundercracker/ZxPeh/23/

你只需要把它放在一个iframe 。 你也可以通过给iframe一个滚动条(我认为)进行水平滚动。


编辑2015年

如果你可以生活在一个预定义的表格单元格的宽度(按百分比),那么这里有一个更优雅的(纯CSS)解决scheme:

http://jsfiddle.net/7UBMD/77/

我看到这个线程已经暂停一段时间了,但是这个话题让我感兴趣,现在有了一些CSS3select器,这变得更简单了(只用CSS就可以实现)。

该解决scheme依赖于表容器的最大高度。 但只要您可以使用:first-childselect器,它就被支持。

在这里拨弄。

如果有人可以改善这个答案,请做! 我计划很快在商业应用中使用这个解决scheme!

HTML

 <div id="con"> <table> <thead> <tr> <th>Header 1</th> <th>Header 2</th> <th>Header 3</th> </tr> </thead> <tbody> </tbody> </table> </div> 

CSS

 #con{ max-height:300px; overflow-y:auto; } thead tr:first-child { background-color:#00f; color:#fff; position:absolute; } tbody tr:first-child td{ padding-top:28px; } 

正如我最近需要这个,我会分享一个使用3表的解决scheme,但不需要JavaScript。

表1(父)包含两行。 第一行包含列标题的表2(子1)。 第二行包含滚动内容的表3(子2)。

必须注意的是, childTbl必须比parentTbl缩短25px才能正确显示滚动条。

这是我从中获得灵感的来源。 我使HTML5友好,没有弃用标签和内联CSS。

 .parentTbl table { border-spacing: 0; border-collapse: collapse; border: 0; width: 690px; } .childTbl table { border-spacing: 0; border-collapse: collapse; border: 1px solid #d7d7d7; width: 665px; } .childTbl th, .childTbl td { border: 1px solid #d7d7d7; } .scrollData { width: 690; height: 150px; overflow-x: hidden; } 
 <div class="parentTbl"> <table> <tr> <td> <div class="childTbl"> <table class="childTbl"> <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> </tr> </table> </div> </td> </tr> <tr> <td> <div class="scrollData childTbl"> <table> <tr> <td>Table Data 1</td> <td>Table Data 2</td> <td>Table Data 3</td> <td>Table Data 4</td> <td>Table Data 5</td> <td>Table Data 6</td> </tr> <tr> <td>Table Data 1</td> <td>Table Data 2</td> <td>Table Data 3</td> <td>Table Data 4</td> <td>Table Data 5</td> <td>Table Data 6</td> </tr> <tr> <td>Table Data 1</td> <td>Table Data 2</td> <td>Table Data 3</td> <td>Table Data 4</td> <td>Table Data 5</td> <td>Table Data 6</td> </tr> <tr> <td>Table Data 1</td> <td>Table Data 2</td> <td>Table Data 3</td> <td>Table Data 4</td> <td>Table Data 5</td> <td>Table Data 6</td> </tr> <tr> <td>Table Data 1</td> <td>Table Data 2</td> <td>Table Data 3</td> <td>Table Data 4</td> <td>Table Data 5</td> <td>Table Data 6</td> </tr> <tr> <td>Table Data 1</td> <td>Table Data 2</td> <td>Table Data 3</td> <td>Table Data 4</td> <td>Table Data 5</td> <td>Table Data 6</td> </tr> <tr> <td>Table Data 1</td> <td>Table Data 2</td> <td>Table Data 3</td> <td>Table Data 4</td> <td>Table Data 5</td> <td>Table Data 6</td> </tr> <tr> <td>Table Data 1</td> <td>Table Data 2</td> <td>Table Data 3</td> <td>Table Data 4</td> <td>Table Data 5</td> <td>Table Data 6</td> </tr> <tr> <td>Table Data 1</td> <td>Table Data 2</td> <td>Table Data 3</td> <td>Table Data 4</td> <td>Table Data 5</td> <td>Table Data 6</td> </tr> <tr> <td>Table Data 1</td> <td>Table Data 2</td> <td>Table Data 3</td> <td>Table Data 4</td> <td>Table Data 5</td> <td>Table Data 6</td> </tr> </table> </div> </td> </tr> </table> </div> 

我有同样的问题,经过2天的研究后,我发现Ksesocss的这个解决scheme适合我,也许对你也有好处。 它允许固定的标题和dynamic宽度,只使用CSS。 唯一的问题是,源文件是西class牙文,但你可以在那里findHTML和CSS代码。

这是链接:

http://ksesocss.blogspot.com/2014/10/responsive-table-encabezado-fijo-scroll.html

我希望这有帮助

我最近想自己弄清楚这个问题,并且提出了一个在我的浏览器(Chrome 51)中完美的解决scheme,并支持dynamic列宽 。 我应该提到,在我独立推导出我的答案之后,我也发现了在networking上其他地方描述的类似技术。

诀窍是使用两个相互重叠的相同表格。 下表是可见的,而上表对于表头是不可见的。 上表也有pointer-events: none在tbody上设置,所以鼠标交互命中下面的表。 这样下层表格在上表格的标题下滚动。

对于所有布局和正确resize(例如当用户调整屏幕宽度时),两个表都需要具有相同的滚动条行为。 但是,由于pointer-events: none ,所以上表的滚动条被忽略,可以通过以下方式隐藏:

 <style> .hiddenScrollbar::-webkit-scrollbar { background-color: transparent; } </style> 

这里是完整的代码:

 <html> <head> <style> td { border: 1px solid black; white-space: nowrap; } th { background-color: gray; border: 1px solid black; white-space: nowrap; } .hiddenScrollbar::-webkit-scrollbar { background-color: transparent; } </style> </head> <body> Table test. Use mouse wheel to scroll or scroll to the right to see vertical scroll bar. You can also remove the outermost div if you don't want a horizontal scroll bar. <br/> <div style="display: inline-block; height: 10em; width: 15em; overflow-x: scroll; overflow-y: hidden"> <div style="position: relative;"> <div style="display: inline-block; position: absolute; left: 0px; top: 0px; height: 10em; overflow-y: scroll"> <table style="border-collapse: collapse;"> <thead> <tr> <th>Column 1</th> <th>Another Column</th> </tr> </thead> <tbody> <tr> <td>Data 1</td> <td>123409213750213</td> </tr> <tr> <td>Data 2</td> <td>123409213750213</td> </tr> <tr> <td>Data 3</td> <td>123409213750213</td> </tr> <tr> <td>Data 4</td> <td>123409213750213</td> </tr> <tr> <td>Data 5</td> <td>123409213750213</td> </tr> <tr> <td>Data 6</td> <td>12340921375021342354235 very long...</td> </tr> <tr> <td>Data 7</td> <td>123409213750213</td> </tr> <tr> <td>Data 8</td> <td>123409213750213</td> </tr> <tr> <td>Data 9</td> <td>123409213750213</td> </tr> <tr> <td>Data 10</td> <td>123409213750213</td> </tr> <tr> <td>Data 11</td> <td>123409213750213</td> </tr> <tr> <td>Data 12</td> <td>123409213750213</td> </tr> </tbody> </table> </div> <div class="hiddenScrollbar" style="display: inline-block; pointer-events: none; position: relative; left: 0px; top: 0px; height: 10em; overflow-y: scroll"> <table style="border-collapse: collapse;"> <thead style="pointer-events: auto"> <tr> <th>Column 1</th> <th>Another Column</th> </tr> </thead> <tbody style="visibility: hidden"> <tr> <tr> <td>Data 1</td> <td>123409213750213</td> </tr> <tr> <td>Data 2</td> <td>123409213750213</td> </tr> <tr> <td>Data 3</td> <td>123409213750213</td> </tr> <tr> <td>Data 4</td> <td>123409213750213</td> </tr> <tr> <td>Data 5</td> <td>123409213750213</td> </tr> <tr> <td>Data 6</td> <td>12340921375021342354235 very long...</td> </tr> <tr> <td>Data 7</td> <td>123409213750213</td> </tr> <tr> <td>Data 8</td> <td>123409213750213</td> </tr> <tr> <td>Data 9</td> <td>123409213750213</td> </tr> <tr> <td>Data 10</td> <td>123409213750213</td> </tr> <tr> <td>Data 11</td> <td>123409213750213</td> </tr> <tr> <td>Data 12</td> <td>123409213750213</td> </tr> </tr> </tbody> </table> </div> </div> </div><br/> Stuff after table. </body> </html> 

另一个实现,但在tbody和dynamic列上没有任何溢出。 需要JavaScript,但。 容器div用于容纳列标题。 当表格滚动通过查看端口时,固定标题出现在顶部。 如果表格水平滚动,则固定标题也会滚动。

列标题是使用带display: inline-block span元素创build的display: inline-block和负边距用于水平滚动标题。 也使用RequestAnimationFrame优化,以避免任何结果。

 function rAF(scrollLeft) { var offsetLeft = 0 - scrollLeft; $('.hdr__inner span:first-child').css('margin-left', offsetLeft); } 

https://codepen.io/lloydleo/pen/NRpqEE

只有使用CSS:

CSS

 tr { width: 100%; display: inline-table; table-layout: fixed; } table{ height:300px; // <-- Select the height of the table display: -moz-groupbox; // Firefox Bad Effect } tbody{ overflow-y: scroll; height: 200px; // <-- Select the height of the body width: 100%; position: absolute; } 

Bootply : http : //www.bootply.com/AgI8LpDugl