我正在写一个页面,我需要一个HTML表来保持设置的大小。我需要表顶部的标题始终保持在该位置,但是无论表中添加了多少行,我都需要表的主体进行滚动。想一个迷你版的Excel。这似乎是一项简单的任务,但是我在网络上发现的几乎每个解决方案都有一些缺点。我该如何解决?
我必须找到相同的答案。我发现的最好的示例是http://www.cssplay.co.uk/menu/tablescroll.html-我发现示例2对我来说效果很好。您将必须使用Java Script设置内部表的高度,其余为CSS。
我发现DataTables非常灵活。虽然其默认版本基于jquery,但也有一个AngularJs插件。
我看到了肖恩·哈迪(Sean Haddy)对类似问题的出色解决方案,并自由地进行了一些编辑:
- 使用类而不是ID,因此一个jQuery脚本可在一页上重用于多个表
- 添加了对语义HTML表元素(如标题,thead,tfoot和tbody)的支持
- 将滚动条设置为可选,以便它不会出现在比可滚动高度“短”的表中
- 调整滚动div的宽度,使滚动条向上到表格的右边缘
- 使概念可由
- 在注入的静态表头上使用aria-hidden =“ true”
- 并保留原始thead到位,只是用jQuery和set隐藏
aria-hidden="false"
- 显示了具有不同大小的多个表的示例
肖恩做了繁重的工作。还要感谢马特·伯兰德(Matt Burland)指出需要支撑脚。
请访问http://jsfiddle.net/jhfrench/eNP2N/
您是否尝试过使用thead和tbody,并使用overflow:scroll在tbody上设置了固定高度?
您的目标浏览器是什么?
编辑:在Firefox中效果很好(几乎)-垂直滚动条的添加也导致需要水平滚动条-uck。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
无法调整大小,因此必须将其显示为block
:
tbody {
overflow-y: auto;
display: block;
max-height: 10em; // For example
}
2)重新同步表标题和表主体列的宽度,以使后者block
成为不相关的元素。这样做的唯一方法是通过对两者都强制使用相同的列宽来模拟同步。
但是,由于tbody
它本身是block
现在,所以它的行为不再像table
。由于仍然需要某种table
行为才能正确显示列,因此解决方案是要求将每一行显示为table
s:
thead {
display: table;
width: 100%; // Fill the containing table
}
tbody tr {
display: table;
width: 100%; // Fill the containing table
}
(请注意,使用这种技术,您将无法再跨越行)。
完成此操作后,您可以在thead
和中将列宽设置为具有相同的宽度tbody
。您不能这样:
- 为每个列单独设置(通过特定的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规范,即使删除了某些功能也放弃了: / footer在HTML5之前笨拙地指定。
坏消息
不幸的是处理与固定的滚动表中没有优雅的方式thead
/tfoot
因为HTML / CSS规范都不是很清楚有关该功能的。
说明
尽管HTML 4.01规范说thead
/ tfoot
/tbody
用于(引入?)滚动表主体:
可以使用THEAD,TFOOT和TBODY元素对表行进行分组。这种划分使用户代理能够独立于桌子的头和脚来支持桌子主体的滚动。
但是FF 3.6上已删除了FF 3.6上的可滚动表格功能,因为它不符合HTML / CSS规范,因此被认为是错误,因此已被删除。看到这个和那个关于FF错误的评论。
Mozilla开发人员网络提示
以下是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上不再起作用:-(
我也在IE8上进行过测试=>表也不能滚动:-((
不知道是否有人还在看这个,但是他们以前我做过的方式是使用两个表来显示单个原始表-第一个只是原始表标题行而没有表主体行(或要制作的空主体行)它验证)。
第二个位于单独的div中,没有标题,只有原始表主体行。然后使单独的div可滚动。
div中的第二个表位于HTML中的第一个表的正下方,它看起来像是具有固定标题和可滚动下部的单个表。我仅在Safari,Firefox和IE(2010年春季发布的最新版本)中对此进行了测试,但它在所有这些工具中均有效。
它唯一的问题是,没有主体(W3.org验证器-XHTML 1.0严格),第一个表将无法验证,当我添加不带内容的表时,它将导致空白行。您可以使用CSS使其不可见,但仍会占用页面空间。
此解决方案可在Chrome 35,Firefox 30和IE 11(未经测试的其他版本)中使用
其纯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;
}
这让我非常头疼,试图为我们的应用程序实现这样的网格。我尝试了所有各种技术,但是它们都有问题。我最接近的使用的是jQuery插件,例如Flexigrid(有关替代方案,请参见http://www.ajaxrain.com),但这似乎并不支持我所需要的100%宽表。
我最终要做的是自己动手做;Firefox支持滚动tbody
元素,因此我浏览器嗅探到并使用适当的CSS(设置高度,溢出等...询问是否需要更多详细信息)进行滚动,然后对于其他浏览器,我使用了两个单独的表来设置table-layout: fixed
大小确保不会溢出指定大小的算法(当内容太宽而无法容纳时,普通表将扩展)。通过给两个表相同的宽度,我能够使它们的列对齐。我将第二个包裹在一个div集合中以进行滚动,并使用了一些带有边缘的锯齿状扑克等来设法获得所需的外观和感觉。
很抱歉,如果这个答案在某些地方听起来有点含糊;我没有太多时间,所以写得很快。如果您希望我进一步扩展,请发表评论!
这是一个真正适用于IE和FF的代码(至少):
<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中都能正常工作。
原始代码在这里
这是我的选择。它还为页眉,正文和页脚使用了不同的DIV,但为调整窗口大小以及搜索,滚动,排序,过滤和定位而同步:
单击Jazz,Classical ...按钮以查看表格。设置为即使关闭JavaScript也足够了。
在IE,FF和WebKit(Chrome,Safari)上似乎还可以。
抱歉,我尚未阅读您问题的所有答复。
是的,这里是您想要的东西(我已经做过)
您可以将两个具有相同类名的表用于相似的样式,一个仅用于表头,另一个用于您的行。现在,将该表放入具有固定高度的div中,并使用overflow-y:auto或scroll。
我对上述建议的主要问题是能够插入tablesorter.js并能够将表的标头浮动到特定的最大大小。我最终偶然发现了jQuery.floatThead插件,该插件提供了浮动标头并允许排序继续进行。
它还有一个不错的比较页面,显示了自己与类似插件的对比。
现场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是我的解决方案,请在所有列上创建一个表集固定宽度(像素!),然后将Scrollify类添加到表中,并以CSS或样式将javascript + jquery 1.4.x设置为高度!
经过测试:Opera,Chrome,Safari,FF,IE5.5(Epic脚本失败),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来做到这一点-表格主体随页面滚动,并且表格不必固定为宽度或高度,尽管每一列必须具有宽度。您还可以保留排序功能。
基本上:
-
在HTML中,创建容器div以放置表标题行和表主体,还创建一个“ mask” div以隐藏表主体,因为它滚动经过标题
-
在CSS中,将表格部分转换为块
-
在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%;所有滚动功能都开始起作用。
如果您的标准不够低;),可以将仅包含标题的表放在仅包含主体的表的正上方。它不会水平滚动,但是如果不需要的话...
文章标签:css , html , html-table , javascript
版权声明:本文为原创文章,版权归 javascript 所有,欢迎分享本文,转载请保留出处!
评论已关闭!