我怎么能让桌子的身体滚动,但保持其头部固定的位置?

我正在写一个页面,我需要一个HTML表格来维持一个设定的大小。 我需要表格顶部的标题始终保持在那里,但是我也需要滚动表格的主体来滚动,不pipe有多less行添加到表格中。 想一个迷你版本的Excel。 这似乎是一个简单的任务,但几乎我在网上find的每个解决scheme都有一些缺点。 我该如何解决这个问题?

我必须find相同的答案。 我find的最好的例子是http://www.cssplay.co.uk/menu/tablescroll.html – 我发现#2例子对我很好。 您将不得不使用Java脚本来设置内部表的高度,其余部分是CSS。

我发现DataTables非常灵活。 虽然它的默认版本是基于jquery的,但也有一个AngularJs插件 。

我看到肖恩·哈迪(Sean Haddy) 对类似问题的出色解决scheme,并冒昧地做出一些修改 :

  • 使用类而不是ID,所以一个jQuery脚本可以在一个页面上重复使用多个表
  • 增加了对标题,thead,tfoot和tbody等语义HTML表格元素的支持
  • 使滚动条可选,所以它不会出现在比可滚动高度“更短”的表格中
  • 调整滚动div的宽度,使滚动条上升到桌子的右边缘
  • 制造概念可以通过
    • 在注入的静态表头上使用aria-hidden =“true”
    • 并保留原来的地方,只是用jQuery隐藏,并设置aria-hidden="false"
  • 展示了不同大小的多个表格的例子

尽pipe肖恩做了沉重的举动。 感谢Matt Burland也指出需要支持tfoot。

请亲自看看http://jsfiddle.net/jhfrench/eNP2N/

你有没有尝试过使用thead和tbody,并设置一个固定的高度与tbody溢出:滚动?

你的目标浏览器是什么?

编辑:它在Firefox中运行良好(几乎) – 垂直滚动条的添加导致需要水平滚动条以及 – 恶作剧。 IE只是将每个td的高度设置为我所指定的tbody的高度。 这是我能想到的最好的:

 <html> <head> <title>Blah</title> <style type="text/css"> table { width:300px; } tbody { height:10em; overflow:scroll;} td { height:auto; } </style> </head> <body> <table> <thead> <tr> <th>One</th><th>Two</th> </td> </tr> </thead> <tbody> <tr><td>Data</td><td>Data</td></tr> <tr><td>Data</td><td>Data</td></tr> <tr><td>Data</td><td>Data</td></tr> <tr><td>Data</td><td>Data</td></tr> <tr><td>Data</td><td>Data</td></tr> <tr><td>Data</td><td>Data</td></tr> <tr><td>Data</td><td>Data</td></tr> <tr><td>Data</td><td>Data</td></tr> <tr><td>Data</td><td>Data</td></tr> <tr><td>Data</td><td>Data</td></tr> <tr><td>Data</td><td>Data</td></tr> <tr><td>Data</td><td>Data</td></tr> <tr><td>Data</td><td>Data</td></tr> <tr><td>Data</td><td>Data</td></tr> <tr><td>Data</td><td>Data</td></tr> </tbody> </table> </body> </html> 

你需要的是:

1)只有当内容大于滚动窗口时滚动才会有高度有限的表体 。 然而, tbody不能resize,你必须把它显示为一个block来做到这一点:

 tbody { overflow-y: auto; display: block; max-height: 10em; // For example } 

2) 重新同步表头和表体的宽度 ,使后者成为一个block使其成为一个不相关的元素。 唯一的方法是通过对两者强制执行相同的列宽模拟同步。

但是,由于tbody本身就是一个block ,它不能再像table一样行事。 由于您仍需要table行为才能正确显示列,因此解决办法是要求每行都显示为单独的table

 thead { display: table; width: 100%; // Fill the containing table } tbody tr { display: table; width: 100%; // Fill the containing table } 

(请注意,使用这种技术,你将无法跨越行)。

一旦完成,您可以强制列宽在theadtbody具有相同的宽度。 你不能这样做:

  • (通过特定的CSS类或内联样式),每个列都是单独的,这对每个表实例来说都是相当繁琐的;
  • 统一为所有列(通过th, td { width: 20%; }如果你有5列),这是更实际的(不需要设置每个表实例的宽度),但不能为任何列计数
  • 统一为任何列数,通过固定的表格布局。

我更喜欢最后一个选项,它需要添加:

 thead { table-layout: fixed; // Same layout for all cells } tbody tr { table-layout: fixed; // Same layout for all cells } th, td { width: auto; // Same width for all cells, if table has fixed layout } 

在这里看到一个演示,从这个问题的答案分叉。

编辑:这是一个非常古老的答案,并在这里繁荣只是表明,它曾被支持一次早在2000年,但下降,因为2010年的浏览器策略是尊重W3C规格,即使删除了一些function:固定标题的可滚动表/页脚在HTML5之前笨拙地指定。


坏消息

不幸的是,有没有优雅的方式来处理固定thead / tfoot滚动表,因为HTML / CSS规范不是很清楚该function 。

说明

虽然HTML 4.01规范说thead / tfoot / tbody用于(引入?)滚动表体:

表行可以使用THEAD,TFOOT和TBODY元素进行分组[…]。 这个部门使得用户代理可以独立于桌子的头部和脚部来支持桌子的滚动。

但FF 3.6中的可滚动表格function在FF 3.7中已被删除,因为不符合HTML / CSS规范而被视为错误。 看到这个和对FF错误的评论。

Mozilla开发者networking提示

下面是可滚动表格MDN简化版本的有用提示
看到这个存档页面或当前的法文版本

 <style type="text/css"> table { border-spacing: 0; /* workaround */ } tbody { height: 4em; /* define the height */ overflow-x: hidden; /* esthetics */ overflow-y: auto; /* allow scrolling cells */ } td { border-left: 1px solid blue; /* workaround */ border-bottom: 1px solid blue; /* workaround */ } </style> <table> <thead><tr><th>Header <tfoot><tr><th>Footer <tbody> <tr><td>Cell 1 <tr><td>Cell 2 <tr><td>Cell 3 <tr><td>Cell 4 <tr><td>Cell 5 <tr><td>Cell 6 <tr><td>Cell 7 <tr><td>Cell 8 <tr><td>Cell 9 <tr><td>Cell 10 <tr><td>Cell 11 <tr><td>Cell 12 <tr><td>Cell 13 <tr><td>Cell 14 </tbody> </table> 

然而,MDN也表示这在FF上不再起作用 🙁
我也testing了IE8 =>表是不可滚动的: – ((

不知道如果有人仍然看着这个,但他们的方式,我以前做过这个是使用两个表来显示单个原始表 – 第一个只是原来的表标题行和没有表体行(或一个空的主体行它validation)。

第二个是在一个单独的div,没有标题,只是原来的表体行。 然后单独的div可以滚动。

它的div中的第二个表放置在HTML的第一个表的下方,它看起来像一个固定的标题和一个可滚动的下半部分的表。 我只在Safari,Firefox和IE(2010年春季的最新版本)中进行了testing,但在所有这些工具中都能正常工作。

唯一的问题是,第一个表不会validation没有身体(W3.orgvalidation – XHTML 1.0严格),当我添加一个没有内容时,它会导致一个空行。 您可以使用CSS来使这不可见,但它仍然吃在页面上的空间。

此解决scheme适用于Chrome 35,Firefox 30和IE 11(未经testing的其他版本)

它的纯粹的CSS: http : //jsfiddle.net/ffabreti/d4sope1u/

一切都设置为显示:块,表需要一个高度:

  table { overflow: scroll; display: block; /*inline-block*/ height: 120px; } thead > tr { position: absolute; display: block; padding: 0; margin: 0; top: 0; background-color: gray; } tbody > tr:nth-of-type(1) { margin-top: 16px; } tbody tr { display: block; } td, th { width: 70px; border-style:solid; border-width:1px; border-color:black; } 

这让我非常头痛,试图为我们的应用实现这样的网格。 我尝试了所有的各种技术,但他们每个人都有问题。 我最近使用的是一个像Flexigrid这样的jQuery插件(看看http://www.ajaxrain.com的替代品),但是这似乎并不支持我需要的100%宽表。;

我最终做的是滚动自己的; Firefox支持滚动tbody元素,所以我浏览器嗅探,并使用适当的CSS(设置高度,溢出等…问,如果你想要更多的细节),使其滚动,然后对于其他浏览器,我用两个单独的表设置为使用table-layout: fixed使用的尺寸algorithm,保证不会溢出规定的大小(正常表将扩大内容太宽,不适合)。 通过给这两个表相同的宽度,我能够得到他们的列排列。 我把第二个包裹在一个div集里滚动,然后用一些边距等等来达到我想要的外观和感觉。

对不起,如果这个答案听起来有点模糊的地方, 我写得很快,因为我没有太多时间。 如果您想让我进一步扩展,请发表评论!

这里是一个真正适用于IE和FF(至less)的代码:

 <html> <head> <title>Test</title> <style type="text/css"> table{ width: 400px; } tbody { height: 100px; overflow: scroll; } div { height: 100px; width: 400px; position: relative; } tr.alt td { background-color: #EEEEEE; } </style> <!--[if IE]> <style type="text/css"> div { overflow-y: scroll; overflow-x: hidden; } thead tr { position: absolute; top: expression(this.offsetParent.scrollTop); } tbody { height: auto; } </style> <![endif]--> </head> <body> <div > <table border="0" cellspacing="0" cellpadding="0"> <thead> <tr> <th style="background: lightgreen;">user</th> <th style="background: lightgreen;">email</th> <th style="background: lightgreen;">id</th> <th style="background: lightgreen;">Y/N</th> </tr> </thead> <tbody align="center"> <!--[if IE]> <tr> <td colspan="4">on IE it's overridden by the header</td> </tr> <![endif]--> <tr> <td>user 1</td> <td>user@user.com</td> <td>1</td> <td>Y</td> </tr> <tr class="alt"> <td>user 2</td> <td>user@user.com</td> <td>2</td> <td>N</td> </tr> <tr> <td>user 3</td> <td>user@user.com</td> <td>3</td> <td>Y</td> </tr> <tr class="alt"> <td>user 4</td> <td>user@user.com</td> <td>4</td> <td>N</td> </tr> <tr> <td>user 5</td> <td>user@user.com</td> <td>5</td> <td>Y</td> </tr> <tr class="alt"> <td>user 6</td> <td>user@user.com</td> <td>6</td> <td>N</td> </tr> <tr> <td>user 7</td> <td>user@user.com</td> <td>7</td> <td>Y</td> </tr> <tr class="alt"> <td>user 8</td> <td>user@user.com</td> <td>8</td> <td>N</td> </tr> </tbody> </table> </div> </body></html> 

我已经改变了原来的代码,使其更清晰,也使其工作正常在IE和FF ..

原始代码在这里

这是我的select。 它还为标题,正文和页脚使用不同的DIV,但同步窗口大小调整和search,滚动,sorting,过滤和定位:

我的CD列表

点击Jazz,Classical …button查看表格。 它的设置使得即使JavaScript被closures也足够了。

在IE浏览器,FF和WebKit(Chrome,Safari)上似乎确定。

对不起,我没有阅读你的问题的所有答复。

在这里,你想要的东西(我已经完成了)

您可以使用两个表,使用相同的类名称进行类似的样式,一个只使用表头,另一个使用行。 现在把这个表放在一个具有固定高度的div里,用overflow -y:auto或者scroll。

我对上述build议的主要问题是能够插入tablesorter.js,并能够将表头限制为特定的最大大小。 我最终偶然发现了提供浮动头文件的插件jQuery.floatThead ,并允许sorting继续工作。

它也有一个很好的比较页面显示自己与类似的插件 。

现场JsFiddle

只有HTML和CSS是可能的

 table.scrollTable { border: 1px solid #963; width: 718px; } thead.fixedHeader { display: block; } thead.fixedHeader tr { height: 30px; background: #c96; } thead.fixedHeader tr th { border-right: 1px solid black; } tbody.scrollContent { display: block; height: 262px; overflow: auto; } tbody.scrollContent td { background: #eee; border-right: 1px solid black; height: 25px; } tbody.scrollContent tr.alternateRow td { background: #fff; } thead.fixedHeader th { width: 233px; } thead.fixedHeader th:last-child { width: 251px; } tbody.scrollContent td { width: 233px; } 
 <table cellspacing="0" cellpadding="0" class="scrollTable"> <thead class="fixedHeader"> <tr class="alternateRow"> <th>Header 1</th> <th>Header 2</th> <th>Header 3</th> </tr> </thead> <tbody class="scrollContent"> <tr class="normalRow"> <td>Cell Content 1</td> <td>Cell Content 2</td> <td>Cell Content 3</td> </tr> <tr class="alternateRow"> <td>More Cell Content 1</td> <td>More Cell Content 2</td> <td>More Cell Content 3</td> </tr> <tr class="normalRow"> <td>Even More Cell Content 1</td> <td>Even More Cell Content 2</td> <td>Even More Cell Content 3</td> </tr> <tr class="alternateRow"> <td>And Repeat 1</td> <td>And Repeat 2</td> <td>And Repeat 3</td> </tr> <tr class="normalRow"> <td>Cell Content 1</td> <td>Cell Content 2</td> <td>Cell Content 3</td> </tr> <tr class="alternateRow"> <td>More Cell Content 1</td> <td>More Cell Content 2</td> <td>More Cell Content 3</td> </tr> <tr class="normalRow"> <td>Even More Cell Content 1</td> <td>Even More Cell Content 2</td> <td>Even More Cell Content 3</td> </tr> <tr class="alternateRow"> <td>And Repeat 1</td> <td>And Repeat 2</td> <td>And Repeat 3</td> </tr> <tr class="normalRow"> <td>Cell Content 1</td> <td>Cell Content 2</td> <td>Cell Content 3</td> </tr> <tr class="alternateRow"> <td>More Cell Content 1</td> <td>More Cell Content 2</td> <td>More Cell Content 3</td> </tr> <tr class="normalRow"> <td>Even More Cell Content 1</td> <td>Even More Cell Content 2</td> <td>Even More Cell Content 3</td> </tr> <tr class="alternateRow"> <td>And Repeat 1</td> <td>And Repeat 2</td> <td>And Repeat 3</td> </tr> <tr class="normalRow"> <td>Cell Content 1</td> <td>Cell Content 2</td> <td>Cell Content 3</td> </tr> <tr class="alternateRow"> <td>More Cell Content 1</td> <td>More Cell Content 2</td> <td>More Cell Content 3</td> </tr> <tr class="normalRow"> <td>Even More Cell Content 1</td> <td>Even More Cell Content 2</td> <td>Even More Cell Content 3</td> </tr> <tr class="alternateRow"> <td>And Repeat 1</td> <td>And Repeat 2</td> <td>And Repeat 3</td> </tr> <tr class="normalRow"> <td>Cell Content 1</td> <td>Cell Content 2</td> <td>Cell Content 3</td> </tr> <tr class="alternateRow"> <td>More Cell Content 1</td> <td>More Cell Content 2</td> <td>More Cell Content 3</td> </tr> <tr class="normalRow"> <td>Even More Cell Content 1</td> <td>Even More Cell Content 2</td> <td>Even More Cell Content 3</td> </tr> <tr class="alternateRow"> <td>And Repeat 1</td> <td>And Repeat 2</td> <td>And Repeat 3</td> </tr> <tr class="normalRow"> <td>Cell Content 1</td> <td>Cell Content 2</td> <td>Cell Content 3</td> </tr> <tr class="alternateRow"> <td>More Cell Content 1</td> <td>More Cell Content 2</td> <td>More Cell Content 3</td> </tr> <tr class="normalRow"> <td>Even More Cell Content 1</td> <td>Even More Cell Content 2</td> <td>Even More Cell Content 3</td> </tr> <tr class="alternateRow"> <td>And Repeat 1</td> <td>And Repeat 2</td> <td>And Repeat 3</td> </tr> <tr class="normalRow"> <td>Cell Content 1</td> <td>Cell Content 2</td> <td>Cell Content 3</td> </tr> <tr class="alternateRow"> <td>More Cell Content 1</td> <td>More Cell Content 2</td> <td>More Cell Content 3</td> </tr> <tr class="normalRow"> <td>Even More Cell Content 1</td> <td>Even More Cell Content 2</td> <td>Even More Cell Content 3</td> </tr> <tr class="alternateRow"> <td>And Repeat 1</td> <td>And Repeat 2</td> <td>And Repeat 3</td> </tr> <tr class="normalRow"> <td>Cell Content 1</td> <td>Cell Content 2</td> <td>Cell Content 3</td> </tr> <tr class="alternateRow"> <td>More Cell Content 1</td> <td>More Cell Content 2</td> <td>More Cell Content 3</td> </tr> <tr class="normalRow"> <td>Even More Cell Content 1</td> <td>Even More Cell Content 2</td> <td>Even More Cell Content 3</td> </tr> <tr class="alternateRow"> <td>And Repeat 1</td> <td>And Repeat 2</td> <td>And Repeat 3</td> </tr> <tr class="normalRow"> <td>Cell Content 1</td> <td>Cell Content 2</td> <td>Cell Content 3</td> </tr> <tr class="alternateRow"> <td>More Cell Content 1</td> <td>More Cell Content 2</td> <td>More Cell Content 3</td> </tr> <tr class="normalRow"> <td>Even More Cell Content 1</td> <td>Even More Cell Content 2</td> <td>Even More Cell Content 3</td> </tr> <tr class="alternateRow"> <td>And Repeat 1</td> <td>And Repeat 2</td> <td>And Repeat 3</td> </tr> <tr class="normalRow"> <td>Cell Content 1</td> <td>Cell Content 2</td> <td>Cell Content 3</td> </tr> <tr class="alternateRow"> <td>More Cell Content 1</td> <td>More Cell Content 2</td> <td>More Cell Content 3</td> </tr> <tr class="normalRow"> <td>Even More Cell Content 1</td> <td>Even More Cell Content 2</td> <td>Even More Cell Content 3</td> </tr> <tr class="alternateRow"> <td>And Repeat 1</td> <td>And Repeat 2</td> <td>And Repeat 3</td> </tr> <tr class="normalRow"> <td>Cell Content 1</td> <td>Cell Content 2</td> <td>Cell Content 3</td> </tr> <tr class="alternateRow"> <td>More Cell Content 1</td> <td>More Cell Content 2</td> <td>More Cell Content 3</td> </tr> <tr class="normalRow"> <td>Even More Cell Content 1</td> <td>Even More Cell Content 2</td> <td>Even More Cell Content 3</td> </tr> <tr class="alternateRow"> <td>End of Cell Content 1</td> <td>End of Cell Content 2</td> <td>End of Cell Content 3</td> </tr> </tbody> </table> 

如果可以使用JavaScript这里是我的解决scheme创build一个表设置固定宽度的所有列(像素!)添加类Scrollify到表中,并添加此javascript + jQuery的1.4.x设置高度在CSS或样式!

testing:Opera,Chrome,Safari,FF,IE5.5( 史诗脚本失败 ),IE6,IE7,IE8,IE9

 //Usage add Scrollify class to a table where all columns (header and body) have a fixed pixel width $(document).ready(function () { $("table.Scrollify").each(function (index, element) { var header = $(element).children().children().first(); var headerHtml = header.html(); var width = $(element).outerWidth(); var height = parseInt($(element).css("height")) - header.outerHeight(); $(element).height("auto"); header.remove(); var html = "<table style=\"border-collapse: collapse;\" border=\"1\" rules=\"all\" cellspacing=\"0\"><tr>" + headerHtml + "</tr></table><div style=\"overflow: auto;border:0;margin:0;padding:0;height:" + height + "px;width:" + (parseInt(width) + scrollbarWidth()) + "px;\">" + $(element).parent().html() + "</div>"; $(element).parent().html(html); }); }); //Function source: http://www.fleegix.org/articles/2006-05-30-getting-the-scrollbar-width-in-pixels //License: Apache License, version 2 function scrollbarWidth() { var scr = null; var inn = null; var wNoScroll = 0; var wScroll = 0; // Outer scrolling div scr = document.createElement('div'); scr.style.position = 'absolute'; scr.style.top = '-1000px'; scr.style.left = '-1000px'; scr.style.width = '100px'; scr.style.height = '50px'; // Start with no scrollbar scr.style.overflow = 'hidden'; // Inner content div inn = document.createElement('div'); inn.style.width = '100%'; inn.style.height = '200px'; // Put the inner div in the scrolling div scr.appendChild(inn); // Append the scrolling div to the doc document.body.appendChild(scr); // Width of the inner div sans scrollbar wNoScroll = inn.offsetWidth; // Add the scrollbar scr.style.overflow = 'auto'; // Width of the inner div width scrollbar wScroll = inn.offsetWidth; // Remove the scrolling div from the doc document.body.removeChild( document.body.lastChild); // Pixel width of the scroller return (wNoScroll - wScroll); } 

编辑:固定高度。

我用javascript(无库)和CSS来做到这一点 – 表格主体与页面滚动,并且表格不必固定宽度或高度,虽然每列必须有一个宽度。 您还可以保持sortingfunction。

基本上:

  1. 在HTML中,创build容器div来定位表格标题行和表格主体,也创build一个“mask”div来隐藏表格主体,因为它滚动通过标题

  2. 在CSS中,将表格部分转换为块

  3. 在Javascript中,获取表格宽度并匹配蒙版的宽度…获取页面内容的高度…度量滚动位置…操纵CSS设置表格标题行位置和蒙版高度

这里是JavaScript和一个jsFiddle演示。

 // get table width and match the mask width function setMaskWidth() { if (document.getElementById('mask') !==null) { var tableWidth = document.getElementById('theTable').offsetWidth; // match elements to the table width document.getElementById('mask').style.width = tableWidth + "px"; } } function fixTop() { // get height of page content function getScrollY() { var y = 0; if( typeof ( window.pageYOffset ) == 'number' ) { y = window.pageYOffset; } else if ( document.body && ( document.body.scrollTop) ) { y = document.body.scrollTop; } else if ( document.documentElement && ( document.documentElement.scrollTop) ) { y = document.documentElement.scrollTop; } return [y]; } var y = getScrollY(); var y = y[0]; if (document.getElementById('mask') !==null) { document.getElementById('mask').style.height = y + "px" ; if (document.all && document.querySelector && !document.addEventListener) { document.styleSheets[1].rules[0].style.top = y + "px" ; } else { document.styleSheets[1].cssRules[0].style.top = y + "px" ; } } } window.onscroll = function() { setMaskWidth(); fixTop(); } 

对我来说,没有任何相关的滚动真的有效,直到我从表CSS中删除宽度。 最初,表CSS看起来像这样:

 .table-fill { background: white; border-radius:3px; border-collapse: collapse; margin: auto; width: 100%; max-width: 800px; padding:5px; box-shadow: 0 5px 10px rgba(0, 0, 0, 0.1); animation: float 5s infinite; } 

只要我删除了宽度:100%; 所有的滚动function开始工作。