CSS-只有滚动表固定头(CSS-Only Scrollable Table with fixed

2019-06-17 16:42发布

我有我可以创建滚动表W¯¯使用jQuery的未成年人/固定页眉/页脚和CSS的解决方案 - 但我正在寻找一种方法,使这个只有CSS的解决方案,是跨浏览器兼容。

需要明确的是,我所追求做的是使用一个table标签(和它是有效的子标签, colgroupcoltheadtbodytfoottrthtd ),而是采用一组CSS规则,这将符合下列条件:

  1. 必须保持页眉/页脚/内容行之间列对齐
  2. 必须允许页眉/页脚保持固定,而内容垂直滚动
  3. 不能要求任何的jQuery或其他JavaScript才能提供的功能
  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来提供水平滚动。 我不在乎水平滚动无论如何,所以如果解决方案不这样做,它的罚款。

Answer 1:

用惊奇的解决方案实现Flexbox尚未公布。

下面是使用我的解决方案display: flex和基本使用:after (感谢行李 ),甚至用滚动条填充的保持对齐tbody一点。 这已经在Chrome 45,Firefox的39,和MS边缘得到了验证。 它可以与前缀属性进行修改IE11工作,并在IE10进一步与CSS黑客和2012 Flexbox的语法 。

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

唯一需要注意的是,所有的表格单元格必须具有相同的宽度。 下面是一个明确人为的例子,但是,当单元格的内容而变化(表格单元格都具有相同的宽度和字包装上,迫使Flexbox的,让他们具有相同的宽度与内容无关)能正常工作。 这里是其中细胞内容是不同的一个例子。

就在申请.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> 



Answer 2:

这个答案将作为一个占位符不完全支持position: sticky ,并会随着时间的推移被更新。 这是目前建议不要使用本机实现的这个在生产环境中。

当前支持看到这一点: https://caniuse.com/#feat=css-sticky


使用position: sticky

另一种答案将是利用position: sticky 。 如所描述的由W3C :

甲粘粘定位的盒类似地定位到一个相对定位的盒子,但计算参考与滚动框,或者如果没有祖先具有滚动框视口中的最近的祖先的偏移。

这恰好描述的相对静态的报头的行为。 这将是容易此分配给<thead>或第一<tr> HTML标签,因为这应该支持根据W3C 。 然而,这两种浏览器 , IE浏览器和边缘都分配一个粘位置属性,这些标签的问题。 此外,还似乎是在目前解决这个没有优先级。

是什么似乎为表单元工作进行分配的粘性属性为表单元格。 在这种情况下<th>细胞。

由于表是不尊重你分配给它的静态大小的块元素,最好是使用包装元素定义滚动溢出。

代码

 div { display: inline-block; height: 150px; overflow: auto } table th { position: -webkit-sticky; position: sticky; top: 0; } /* == Just general styling, not relevant :) == */ table { border-collapse: collapse; } th { background-color: #1976D2; color: #fff; } th, td { padding: 1em .5em; } table tr { color: #212121; } table tr:nth-child(odd) { background-color: #BBDEFB; } 
 <div> <table border="0"> <thead> <tr> <th>head1</th> <th>head2</th> <th>head3</th> <th>head4</th> </tr> </thead> <tr> <td>row 1, cell 1</td> <td>row 1, cell 2</td> <td>row 1, cell 2</td> <td>row 1, cell 2</td> </tr> <tr> <td>row 2, cell 1</td> <td>row 2, cell 2</td> <td>row 1, cell 2</td> <td>row 1, cell 2</td> </tr> <tr> <td>row 2, cell 1</td> <td>row 2, cell 2</td> <td>row 1, cell 2</td> <td>row 1, cell 2</td> </tr> <tr> <td>row 2, cell 1</td> <td>row 2, cell 2</td> <td>row 1, cell 2</td> <td>row 1, cell 2</td> </tr> <tr> <td>row 2, cell 1</td> <td>row 2, cell 2</td> <td>row 1, cell 2</td> <td>row 1, cell 2</td> </tr> </table> </div> 

在这个例子中我用一个简单<div>包装器定义的涡旋溢流用的静态高度完成150px 。 这当然可以是任意大小。 现在,滚动框已被定义,则粘<th>元素将corespondent“与滚动框最近的祖先”,这是div-包装。


一个使用position: sticky 填充工具

非支持的设备可以使用填充工具,它实现了通过代码的行为。 一个例子是stickybits ,它类似于相同的行为作为浏览器实现的position: sticky

与填充工具例如: http://jsfiddle.net/7UZA4/6957/



Answer 3:

据我所知,目前还仅适用于CSS来实现这个没有标准的方式,但我认为应该有。 Mozilla浏览器用于支持固定头部与身体滚动,但他们已经在过去的几年中删除它。

这个研究了一下,包括找到这个帖子,经过朋友刚刚研发该解决方案对我来说; 它使用JavaScript,但没有罐装库和HTML标记的唯一要求是,该表有一个ID名称。 然后,在在window.onload,呼吁每个表给ID,高度和宽度的一个JavaScript函数。 如果JavaScript在浏览器中禁用,整个表是根据原来的标记显示。 如果在启用了JavaScript,该表是配合到指定的高度和宽度,TBODY卷轴,并且如果THEAD和TFOOT存在,它们被固定在顶部和底部。



Answer 4:

通过@ Purag的回答启发,这里的另一个Flexbox的解决方案:

 /* 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> 



Answer 5:

香港专业教育学院取得了这一点很容易使用此代码:

所以,你有这样的结构:

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

只是在样式与THEAD:

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

考虑三件事情:

首先,这个属性是新的。 这不是在所有的支持,除了beta版本的基于WebKit的浏览器。 所以告诫formator。 同样,如果你真的想为你的用户从粘头受益,去一个JavaScript实现。

其次,如果你使用它,你需要整合供应商前缀。 也许位置:将粘有一天上班。 现在,虽然,你需要使用的位置是:-webkit-粘(和其他人;进一步检查CSS的堵在这个岗位)。

第三,没有在任何时刻定位默认值,所以你需要至少包括顶部:0; 在相同的CSS声明的位置:-webkit-粘。 否则,它只会滚动在屏幕之外。



Answer 6:

如果你有赋予一个固定的宽度表中的细胞(和固定高度的报头)的选项,则可以使用的position: fixed选项:

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

你只需要坚持在一个iframe 。 你也可以通过给有水平滚动iframe滚动条(我认为)。


2015年编辑

如果你可以用一个预先定义的表格单元格(按百分比)的宽度,那么这里有点更优雅(CSS-只)解决方案住:

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



Answer 7:

只有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



Answer 8:

我看到这个线程已经停用一段时间,但这个话题感兴趣,我现在用一些CSS3选择器,这只是变得更容易(且仅CSS相当的可操作性)。

该解决方案依赖于具有表容器的最大高度。 但只要你可以使用支持的:first-child选择。

小提琴这里 。

如果任何人都可以在这个答案改善,请不要! 我计划很快在商业应用程序使用此解决方案!

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


Answer 9:

我有同样的问题,并花2个几天时间对后,我发现从Ksesocss该解决方案适合我,也许是对你有好处太。 它允许固定报头和动态宽度,并只使用CSS。 唯一的问题是,来源是西班牙语,但你能在那里找到的HTML和CSS代码。

这是链接:

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

我希望这有帮助



Answer 10:

如果它变得坚硬的岩石,其中所有提到的解决方案不起作用(因为它得到了我),尝试两提交固溶,因为我在这个答案解释

https://stackoverflow.com/a/47722456/6488361



Answer 11:

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

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

必须指出的childTbl必须25px比短parentTbl的滚轮能够正确显示。

这是源,在那里我得到的想法而来。 我做了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> 

这是在不同的浏览器可靠,缺点是有硬编码表的宽度。



Answer 12:

我想最近这出自己,我想出了在我的浏览器(Chrome 51)完美的作品,并支持动态列宽一个很好的解决方案。 我要指出,我后独立衍生我的答案我还发现在网络上其他地方所描述的类似的技术...

关键是使用定位在彼此的顶部上的两个相同的表。 下表是可见的,上表是期待的头看不见的。 上表还具有pointer-events: none在TBODY设置成鼠标交互打到下面的表。 这样,上表的标题下下表滚动。

对于一切设计,能正确调整(当用户调节屏幕宽度为实例),这两个表必须具有相同的滚动条的行为。 然而,上表的滚动条被忽略感谢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> 

注意事项:更多的工作来证明这部作品在其他浏览器。 此外,我是混合内联和样式表的样式,而宽松。 不过,我相信一般的概念是因为如果目标浏览器支持它这样做的最佳方式。 唯一的功能/显示问题是,如果你想有一个水平滚动条,垂直滚动条可以得到滚出视 (如图所示片段)。 您仍然可以使用鼠标滚轮滚动浏览。 此外,您不能对报头 (否则下表将显示通过) 透明背景 。 最后,你需要一种方法来产生两个相同的表。 就个人而言,我使用react.js,很容易与反应做到这一点,但是PHP或其他服务器端生成或JavaScript也可以工作。



Answer 13:

另一种实现,但没有任何溢出tbody和动态列。 需要JavaScript虽然。 容器div用于容纳列标题。 当表滚动过去视口,一个固定报头出现在顶部。 如果表被水平滚动,所述固定报头滚动以及。

列标题是使用创建的span元件与display: inline-block和负余量是用来水平滚动报头。 使用也进行了优化RequestAnimationFrame以避免任何JANK。

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

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



文章来源: CSS-Only Scrollable Table with fixed headers