是否有跨浏览器的CSS/JavaScript技术来显示一个长HTML表,使列标题保持固定在屏幕上,而不随表体滚动。想想微软Excel中的“冻结窗格”效果。
我希望能够滚动表的内容,但总是能够在顶部看到列标题。
是否有跨浏览器的CSS/JavaScript技术来显示一个长HTML表,使列标题保持固定在屏幕上,而不随表体滚动。想想微软Excel中的“冻结窗格”效果。
我希望能够滚动表的内容,但总是能够在顶部看到列标题。
当前回答
几乎所有的现代浏览器都支持它!
// '.tbl-content' consumed little space for vertical scrollbar, scrollbar width depend on browser/os/platfrom. Here calculate the scollbar width . $(window).on("load resize ", function() { var scrollWidth = $('.tbl-content').width() - $('.tbl-content table').width(); $('.tbl-header').css({ 'padding-right': scrollWidth }); }).resize(); h1 { font-size: 30px; color: #fff; text-transform: uppercase; font-weight: 300; text-align: center; margin-bottom: 15px; } table { width: 100%; table-layout: fixed; } .tbl-header { background-color: rgba(255, 255, 255, 0.3); } .tbl-content { height: 300px; overflow-x: auto; margin-top: 0px; border: 1px solid rgba(255, 255, 255, 0.3); } th { padding: 20px 15px; text-align: left; font-weight: 500; font-size: 12px; color: #fff; text-transform: uppercase; } td { padding: 15px; text-align: left; vertical-align: middle; font-weight: 300; font-size: 12px; color: #fff; border-bottom: solid 1px rgba(255, 255, 255, 0.1); } /* demo styles */ @import url(https://fonts.googleapis.com/css?family=Roboto:400,500,300,700); body { background: -webkit-linear-gradient(left, #25c481, #25b7c4); background: linear-gradient(to right, #25c481, #25b7c4); font-family: 'Roboto', sans-serif; } section { margin: 50px; } /* follow me template */ .made-with-love { margin-top: 40px; padding: 10px; clear: left; text-align: center; font-size: 10px; font-family: arial; color: #fff; } .made-with-love i { font-style: normal; color: #F50057; font-size: 14px; position: relative; top: 2px; } .made-with-love a { color: #fff; text-decoration: none; } .made-with-love a:hover { text-decoration: underline; } /* for custom scrollbar for webkit browser*/ ::-webkit-scrollbar { width: 6px; } ::-webkit-scrollbar-track { -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3); } ::-webkit-scrollbar-thumb { -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3); } <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script> <section> <!--for demo wrap--> <h1>Fixed Table header</h1> <div class="tbl-header"> <table cellpadding="0" cellspacing="0" border="0"> <thead> <tr> <th>Code</th> <th>Company</th> <th>Price</th> <th>Change</th> <th>Change %</th> </tr> </thead> </table> </div> <div class="tbl-content"> <table cellpadding="0" cellspacing="0" border="0"> <tbody> <tr> <td>AAC</td> <td>AUSTRALIAN COMPANY </td> <td>$1.38</td> <td>+2.01</td> <td>-0.36%</td> </tr> <tr> <td>AAD</td> <td>AUSENCO</td> <td>$2.38</td> <td>-0.01</td> <td>-1.36%</td> </tr> <tr> <td>AAX</td> <td>ADELAIDE</td> <td>$3.22</td> <td>+0.01</td> <td>+1.36%</td> </tr> <tr> <td>XXD</td> <td>ADITYA BIRLA</td> <td>$1.02</td> <td>-1.01</td> <td>+2.36%</td> </tr> <tr> <td>AAC</td> <td>AUSTRALIAN COMPANY </td> <td>$1.38</td> <td>+2.01</td> <td>-0.36%</td> </tr> <tr> <td>AAD</td> <td>AUSENCO</td> <td>$2.38</td> <td>-0.01</td> <td>-1.36%</td> </tr> <tr> <td>AAX</td> <td>ADELAIDE</td> <td>$3.22</td> <td>+0.01</td> <td>+1.36%</td> </tr> <tr> <td>XXD</td> <td>ADITYA BIRLA</td> <td>$1.02</td> <td>-1.01</td> <td>+2.36%</td> </tr> <tr> <td>AAC</td> <td>AUSTRALIAN COMPANY </td> <td>$1.38</td> <td>+2.01</td> <td>-0.36%</td> </tr> <tr> <td>AAD</td> <td>AUSENCO</td> <td>$2.38</td> <td>-0.01</td> <td>-1.36%</td> </tr> <tr> <td>AAX</td> <td>ADELAIDE</td> <td>$3.22</td> <td>+0.01</td> <td>+1.36%</td> </tr> <tr> <td>XXD</td> <td>ADITYA BIRLA</td> <td>$1.02</td> <td>-1.01</td> <td>+2.36%</td> </tr> <tr> <td>AAC</td> <td>AUSTRALIAN COMPANY </td> <td>$1.38</td> <td>+2.01</td> <td>-0.36%</td> </tr> <tr> <td>AAD</td> <td>AUSENCO</td> <td>$2.38</td> <td>-0.01</td> <td>-1.36%</td> </tr> <tr> <td>AAX</td> <td>ADELAIDE</td> <td>$3.22</td> <td>+0.01</td> <td>+1.36%</td> </tr> <tr> <td>XXD</td> <td>ADITYA BIRLA</td> <td>$1.02</td> <td>-1.01</td> <td>+2.36%</td> </tr> <tr> <td>AAC</td> <td>AUSTRALIAN COMPANY </td> <td>$1.38</td> <td>+2.01</td> <td>-0.36%</td> </tr> <tr> <td>AAD</td> <td>AUSENCO</td> <td>$2.38</td> <td>-0.01</td> <td>-1.36%</td> </tr> <tr> <td>AAX</td> <td>ADELAIDE</td> <td>$3.22</td> <td>+0.01</td> <td>+1.36%</td> </tr> <tr> <td>XXD</td> <td>ADITYA BIRLA</td> <td>$1.02</td> <td>-1.01</td> <td>+2.36%</td> </tr> <tr> <td>AAC</td> <td>AUSTRALIAN COMPANY </td> <td>$1.38</td> <td>+2.01</td> <td>-0.36%</td> </tr> <tr> <td>AAD</td> <td>AUSENCO</td> <td>$2.38</td> <td>-0.01</td> <td>-1.36%</td> </tr> <tr> <td>AAX</td> <td>ADELAIDE</td> <td>$3.22</td> <td>+0.01</td> <td>+1.36%</td> </tr> <tr> <td>XXD</td> <td>ADITYA BIRLA</td> <td>$1.02</td> <td>-1.01</td> <td>+2.36%</td> </tr> <tr> <td>AAC</td> <td>AUSTRALIAN COMPANY </td> <td>$1.38</td> <td>+2.01</td> <td>-0.36%</td> </tr> <tr> <td>AAD</td> <td>AUSENCO</td> <td>$2.38</td> <td>-0.01</td> <td>-1.36%</td> </tr> <tr> <td>AAX</td> <td>ADELAIDE</td> <td>$3.22</td> <td>+0.01</td> <td>+1.36%</td> </tr> <tr> <td>XXD</td> <td>ADITYA BIRLA</td> <td>$1.02</td> <td>-1.01</td> <td>+2.36%</td> </tr> <tr> <td>AAC</td> <td>AUSTRALIAN COMPANY </td> <td>$1.38</td> <td>+2.01</td> <td>-0.36%</td> </tr> <tr> <td>AAD</td> <td>AUSENCO</td> <td>$2.38</td> <td>-0.01</td> <td>-1.36%</td> </tr> <tr> <td>AAX</td> <td>ADELAIDE</td> <td>$3.22</td> <td>+0.01</td> <td>+1.36%</td> </tr> <tr> <td>XXD</td> <td>ADITYA BIRLA</td> <td>$1.02</td> <td>-1.01</td> <td>+2.36%</td> </tr> </tbody> </table> </div> </section>
其他回答
几乎所有的现代浏览器都支持它!
// '.tbl-content' consumed little space for vertical scrollbar, scrollbar width depend on browser/os/platfrom. Here calculate the scollbar width . $(window).on("load resize ", function() { var scrollWidth = $('.tbl-content').width() - $('.tbl-content table').width(); $('.tbl-header').css({ 'padding-right': scrollWidth }); }).resize(); h1 { font-size: 30px; color: #fff; text-transform: uppercase; font-weight: 300; text-align: center; margin-bottom: 15px; } table { width: 100%; table-layout: fixed; } .tbl-header { background-color: rgba(255, 255, 255, 0.3); } .tbl-content { height: 300px; overflow-x: auto; margin-top: 0px; border: 1px solid rgba(255, 255, 255, 0.3); } th { padding: 20px 15px; text-align: left; font-weight: 500; font-size: 12px; color: #fff; text-transform: uppercase; } td { padding: 15px; text-align: left; vertical-align: middle; font-weight: 300; font-size: 12px; color: #fff; border-bottom: solid 1px rgba(255, 255, 255, 0.1); } /* demo styles */ @import url(https://fonts.googleapis.com/css?family=Roboto:400,500,300,700); body { background: -webkit-linear-gradient(left, #25c481, #25b7c4); background: linear-gradient(to right, #25c481, #25b7c4); font-family: 'Roboto', sans-serif; } section { margin: 50px; } /* follow me template */ .made-with-love { margin-top: 40px; padding: 10px; clear: left; text-align: center; font-size: 10px; font-family: arial; color: #fff; } .made-with-love i { font-style: normal; color: #F50057; font-size: 14px; position: relative; top: 2px; } .made-with-love a { color: #fff; text-decoration: none; } .made-with-love a:hover { text-decoration: underline; } /* for custom scrollbar for webkit browser*/ ::-webkit-scrollbar { width: 6px; } ::-webkit-scrollbar-track { -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3); } ::-webkit-scrollbar-thumb { -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3); } <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script> <section> <!--for demo wrap--> <h1>Fixed Table header</h1> <div class="tbl-header"> <table cellpadding="0" cellspacing="0" border="0"> <thead> <tr> <th>Code</th> <th>Company</th> <th>Price</th> <th>Change</th> <th>Change %</th> </tr> </thead> </table> </div> <div class="tbl-content"> <table cellpadding="0" cellspacing="0" border="0"> <tbody> <tr> <td>AAC</td> <td>AUSTRALIAN COMPANY </td> <td>$1.38</td> <td>+2.01</td> <td>-0.36%</td> </tr> <tr> <td>AAD</td> <td>AUSENCO</td> <td>$2.38</td> <td>-0.01</td> <td>-1.36%</td> </tr> <tr> <td>AAX</td> <td>ADELAIDE</td> <td>$3.22</td> <td>+0.01</td> <td>+1.36%</td> </tr> <tr> <td>XXD</td> <td>ADITYA BIRLA</td> <td>$1.02</td> <td>-1.01</td> <td>+2.36%</td> </tr> <tr> <td>AAC</td> <td>AUSTRALIAN COMPANY </td> <td>$1.38</td> <td>+2.01</td> <td>-0.36%</td> </tr> <tr> <td>AAD</td> <td>AUSENCO</td> <td>$2.38</td> <td>-0.01</td> <td>-1.36%</td> </tr> <tr> <td>AAX</td> <td>ADELAIDE</td> <td>$3.22</td> <td>+0.01</td> <td>+1.36%</td> </tr> <tr> <td>XXD</td> <td>ADITYA BIRLA</td> <td>$1.02</td> <td>-1.01</td> <td>+2.36%</td> </tr> <tr> <td>AAC</td> <td>AUSTRALIAN COMPANY </td> <td>$1.38</td> <td>+2.01</td> <td>-0.36%</td> </tr> <tr> <td>AAD</td> <td>AUSENCO</td> <td>$2.38</td> <td>-0.01</td> <td>-1.36%</td> </tr> <tr> <td>AAX</td> <td>ADELAIDE</td> <td>$3.22</td> <td>+0.01</td> <td>+1.36%</td> </tr> <tr> <td>XXD</td> <td>ADITYA BIRLA</td> <td>$1.02</td> <td>-1.01</td> <td>+2.36%</td> </tr> <tr> <td>AAC</td> <td>AUSTRALIAN COMPANY </td> <td>$1.38</td> <td>+2.01</td> <td>-0.36%</td> </tr> <tr> <td>AAD</td> <td>AUSENCO</td> <td>$2.38</td> <td>-0.01</td> <td>-1.36%</td> </tr> <tr> <td>AAX</td> <td>ADELAIDE</td> <td>$3.22</td> <td>+0.01</td> <td>+1.36%</td> </tr> <tr> <td>XXD</td> <td>ADITYA BIRLA</td> <td>$1.02</td> <td>-1.01</td> <td>+2.36%</td> </tr> <tr> <td>AAC</td> <td>AUSTRALIAN COMPANY </td> <td>$1.38</td> <td>+2.01</td> <td>-0.36%</td> </tr> <tr> <td>AAD</td> <td>AUSENCO</td> <td>$2.38</td> <td>-0.01</td> <td>-1.36%</td> </tr> <tr> <td>AAX</td> <td>ADELAIDE</td> <td>$3.22</td> <td>+0.01</td> <td>+1.36%</td> </tr> <tr> <td>XXD</td> <td>ADITYA BIRLA</td> <td>$1.02</td> <td>-1.01</td> <td>+2.36%</td> </tr> <tr> <td>AAC</td> <td>AUSTRALIAN COMPANY </td> <td>$1.38</td> <td>+2.01</td> <td>-0.36%</td> </tr> <tr> <td>AAD</td> <td>AUSENCO</td> <td>$2.38</td> <td>-0.01</td> <td>-1.36%</td> </tr> <tr> <td>AAX</td> <td>ADELAIDE</td> <td>$3.22</td> <td>+0.01</td> <td>+1.36%</td> </tr> <tr> <td>XXD</td> <td>ADITYA BIRLA</td> <td>$1.02</td> <td>-1.01</td> <td>+2.36%</td> </tr> <tr> <td>AAC</td> <td>AUSTRALIAN COMPANY </td> <td>$1.38</td> <td>+2.01</td> <td>-0.36%</td> </tr> <tr> <td>AAD</td> <td>AUSENCO</td> <td>$2.38</td> <td>-0.01</td> <td>-1.36%</td> </tr> <tr> <td>AAX</td> <td>ADELAIDE</td> <td>$3.22</td> <td>+0.01</td> <td>+1.36%</td> </tr> <tr> <td>XXD</td> <td>ADITYA BIRLA</td> <td>$1.02</td> <td>-1.01</td> <td>+2.36%</td> </tr> <tr> <td>AAC</td> <td>AUSTRALIAN COMPANY </td> <td>$1.38</td> <td>+2.01</td> <td>-0.36%</td> </tr> <tr> <td>AAD</td> <td>AUSENCO</td> <td>$2.38</td> <td>-0.01</td> <td>-1.36%</td> </tr> <tr> <td>AAX</td> <td>ADELAIDE</td> <td>$3.22</td> <td>+0.01</td> <td>+1.36%</td> </tr> <tr> <td>XXD</td> <td>ADITYA BIRLA</td> <td>$1.02</td> <td>-1.01</td> <td>+2.36%</td> </tr> </tbody> </table> </div> </section>
:)
不太干净,但纯粹的HTML/CSS解决方案。
table {
overflow-x:scroll;
}
tbody {
max-height: /*your desired max height*/
overflow-y:scroll;
display:block;
}
针对IE8+更新 JSFiddle例子
这是我们最终使用的解决方案(为了处理一些边缘情况和旧版本的Internet Explorer,我们最终也会在滚动时淡出标题栏,然后在滚动结束时重新淡出,但在Firefox和WebKit浏览器中,这个解决方案是有效的。它假设边界崩溃:崩溃。
此解决方案的关键在于,一旦应用了边界折叠,CSS转换就可以在头部上工作,因此只需拦截滚动事件并正确设置转换即可。你不需要复制任何东西。除非在浏览器中正确地实现这种行为,否则很难想象还有更轻量级的解决方案。
JSFiddle: http://jsfiddle.net/podperson/tH9VU/2/
它被实现为一个简单的jQuery插件。你只需要调用像$('thead').sticky()这样的调用来让你的head's sticky,它们就会一直存在。它适用于一个页面上的多个表和大表中间的头部部分。
$.fn.sticky = function(){
$(this).each( function(){
var thead = $(this),
tbody = thead.next('tbody');
updateHeaderPosition();
function updateHeaderPosition(){
if(
thead.offset().top < $(document).scrollTop()
&& tbody.offset().top + tbody.height() > $(document).scrollTop()
){
var tr = tbody.find('tr').last(),
y = tr.offset().top - thead.height() < $(document).scrollTop()
? tr.offset().top - thead.height() - thead.offset().top
: $(document).scrollTop() - thead.offset().top;
thead.find('th').css({
'z-index': 100,
'transform': 'translateY(' + y + 'px)',
'-webkit-transform': 'translateY(' + y + 'px)'
});
} else {
thead.find('th').css({
'transform': 'none',
'-webkit-transform': 'none'
});
}
}
// See http://www.quirksmode.org/dom/events/scroll.html
$(window).on('scroll', updateHeaderPosition);
});
}
$('thead').sticky();
这不是固定标题行的精确解决方案,但我创建了一种相当巧妙的方法,在整个长表中重复标题行,但仍然保持排序能力。
这个简洁的小选项需要jQuery tablesorter插件。下面是它的工作原理:
HTML
<table class="tablesorter boxlist" id="pmtable">
<thead class="fixedheader">
<tr class="boxheadrow">
<th width="70px" class="header">Job Number</th>
<th width="10px" class="header">Pri</th>
<th width="70px" class="header">CLLI</th>
<th width="35px" class="header">Market</th>
<th width="35px" class="header">Job Status</th>
<th width="65px" class="header">Technology</th>
<th width="95px;" class="header headerSortDown">MEI</th>
<th width="95px" class="header">TEO Writer</th>
<th width="75px" class="header">Quote Due</th>
<th width="100px" class="header">Engineer</th>
<th width="75px" class="header">ML Due</th>
<th width="75px" class="header">ML Complete</th>
<th width="75px" class="header">SPEC Due</th>
<th width="75px" class="header">SPEC Complete</th>
<th width="100px" class="header">Install Supervisor</th>
<th width="75px" class="header">MasTec OJD</th>
<th width="75px" class="header">Install Start</th>
<th width="30px" class="header">Install Hours</th>
<th width="75px" class="header">Revised CRCD</th>
<th width="75px" class="header">Latest Ship-To-Site</th>
<th width="30px" class="header">Total Parts</th>
<th width="30px" class="header">OEM Rcvd</th>
<th width="30px" class="header">Minor Rcvd</th>
<th width="30px" class="header">Total Received</th>
<th width="30px" class="header">% On Site</th>
<th width="60px" class="header">Actions</th>
</tr>
</thead>
<tbody class="scrollable">
<tr data-job_id="3548" data-ml_id="" class="odd">
<td class="c black">FL-8-RG9UP</td>
<td data-pri="2" class="priority c yellow">M</td>
<td class="c">FTLDFLOV</td>
<td class="c">SFL</td>
<td class="c">NOI</td>
<td class="c">TRANSPORT</td>
<td class="c"></td>
<td class="c">Chris Byrd</td>
<td class="c">Apr 13, 2013</td>
<td class="c">Kris Hall</td>
<td class="c">May 20, 2013</td>
<td class="c">May 20, 2013</td>
<td class="c">Jun 5, 2013</td>
<td class="c">Jun 7, 2013</td>
<td class="c">Joseph Fitz</td>
<td class="c">Jun 10, 2013</td>
<td class="c">TBD</td>
<td class="c">123</td>
<td class="c revised_crcd"><input readonly="true" name="revised_crcd" value="Jul 26, 2013" type="text" size="12" class="smInput r_crcd c hasDatepicker" id="dp1377194058616"></td>
<td class="c">TBD</td>
<td class="c">N/A</td>
<td class="c">N/A</td>
<td class="c">N/A</td>
<td class="c">N/A</td>
<td class="c">N/A</td>
<td class="actions"><span style="float:left;" class="ui-icon ui-icon-folder-open editJob" title="View this job" s="" details'=""></span></td>
</tr>
<tr data-job_id="4264" data-ml_id="2959" class="even">
<td class="c black">MTS13009SF</td>
<td data-pri="2" class="priority c yellow">M</td>
<td class="c">OJUSFLTL</td>
<td class="c">SFL</td>
<td class="c">NOI</td>
<td class="c">TRANSPORT</td>
<td class="c"></td>
<td class="c">DeMarcus Stewart</td>
<td class="c">May 22, 2013</td>
<td class="c">Ryan Alsobrook</td>
<td class="c">Jun 19, 2013</td>
<td class="c">Jun 27, 2013</td>
<td class="c">Jun 19, 2013</td>
<td class="c">Jul 4, 2013</td>
<td class="c">Randy Williams</td>
<td class="c">Jun 21, 2013</td>
<td class="c">TBD</td>
<td class="c">95</td>
<td class="c revised_crcd"><input readonly="true" name="revised_crcd" value="Aug 9, 2013" type="text" size="12" class="smInput r_crcd c hasDatepicker" id="dp1377194058632"></td><td class="c">TBD</td>
<td class="c">0</td>
<td class="c">0.00%</td>
<td class="c">0.00%</td>
<td class="c">0.00%</td>
<td class="c">0.00%</td>
<td class="actions"><span style="float:left;" class="ui-icon ui-icon-folder-open editJob" title="View this job" s="" details'=""></span><input style="float:left;" type="hidden" name="req_ship" class="reqShip hasDatepicker" id="dp1377194058464"><span style="float:left;" class="ui-icon ui-icon-calendar requestShip" title="Schedule this job for shipping"></span><span class="ui-icon ui-icon-info viewOrderInfo" style="float:left;" title="Show material details for this order"></span></td>
</tr>
.
.
.
.
<tr class="boxheadrow repeated-header">
<th width="70px" class="header">Job Number</th>
<th width="10px" class="header">Pri</th>
<th width="70px" class="header">CLLI</th>
<th width="35px" class="header">Market</th>
<th width="35px" class="header">Job Status</th>
<th width="65px" class="header">Technology</th>
<th width="95px;" class="header">MEI</th>
<th width="95px" class="header">TEO Writer</th>
<th width="75px" class="header">Quote Due</th>
<th width="100px" class="header">Engineer</th>
<th width="75px" class="header">ML Due</th>
<th width="75px" class="header">ML Complete</th>
<th width="75px" class="header">SPEC Due</th>
<th width="75px" class="header">SPEC Complete</th>
<th width="100px" class="header">Install Supervisor</th>
<th width="75px" class="header">MasTec OJD</th>
<th width="75px" class="header">Install Start</th>
<th width="30px" class="header">Install Hours</th>
<th width="75px" class="header">Revised CRCD</th>
<th width="75px" class="header">Latest Ship-To-Site</th>
<th width="30px" class="header">Total Parts</th>
<th width="30px" class="header">OEM Rcvd</th>
<th width="30px" class="header">Minor Rcvd</th>
<th width="30px" class="header">Total Received</th>
<th width="30px" class="header">% On Site</th>
<th width="60px" class="header">Actions</th>
</tr>
显然,我的表的行要比这个多很多。确切地说是193,但是你可以看到标题行重复的地方。重复的标题行是由这个函数建立的:
jQuery
// Clone the original header row and add the "repeated-header" class
var tblHeader = $('tr.boxheadrow').clone().addClass('repeated-header');
// Add the cloned header with the new class every 34th row (or as you see fit)
$('tbody tr:odd:nth-of-type(17n)').after(tblHeader);
// On the 'sortStart' routine, remove all the inserted header rows
$('#pmtable').bind('sortStart', function() {
$('.repeated-header').remove();
// On the 'sortEnd' routine, add back all the header row lines.
}).bind('sortEnd', function() {
$('tbody tr:odd:nth-of-type(17n)').after(tblHeader);
});
这是一个用于固定表头的jQuery插件。它允许整个页面滚动,当它到达顶部时冻结标题。它与Twitter Bootstrap表一起工作得很好。
GitHub存储库:https://github.com/oma/table-fixed-header
它不只是滚动表内容。看看其他的工具,就像这些答案中的一个。你来决定最适合你的情况。