当查看大型表时,HTML 表头总是可见于窗口的顶部

我希望能够“调整”一个 HTML 表格的演示文稿,以添加一个单一的功能: 当向下滚动通过页面,使表格在屏幕上,但标题行是离开屏幕,我希望标题保持可见的顶部的查看区域。

这在概念上类似于 Excel 中的“冻结窗格”特性。但是,一个 HTML 页面可能包含几个表,我只希望当前在视图中的表发生这种情况,只有当它在视图中时才会发生。

注意: 我见过一种解决方案,表数据区域可以滚动,而标题不能滚动。这不是我想要的解决办法。

208018 次浏览

如果您使用全屏表,您可能有兴趣将 th 设置为 display: fix; and top: 0; 或者通过 css 尝试一种非常类似的方法。

更新

只需用 iframe (html4.0)快速构建一个工作解决方案。这个例子是不符合标准的,但是你可以很容易地修复它:

外景

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Outer</title>
<body>
<iframe src="test.html" width="200" height="100"></iframe>
</body>
</html>

Test.html

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Floating</title>
<style type="text/css">
.content{
position:relative;
}


thead{
background-color:red;
position:fixed;
top:0;
}
</style>
<body>
<div class="content">
<table>
<thead>
<tr class="top"><td>Title</td></tr>
</head>
<tbody>
<tr><td>a</td></tr>
<tr><td>b</td></tr>
<tr><td>c</td></tr>
<tr><td>d</td></tr>
<tr><td>e</td></tr>
<tr><td>e</td></tr>
<tr><td>e</td></tr>
<tr><td>e</td></tr>
<tr><td>e</td></tr>
<tr><td>e</td></tr>
</tbody>
</table>
</div>
</body>
</html>

thead部分使用 display: fixed应该可以,但是因为它只能在视图中的当前表上工作,所以需要 JavaScript 的帮助。而且这将是棘手的,因为它将需要找出滚动的位置和元素的位置相对于视口,这是浏览器不兼容的主要领域之一。

看看流行的 JavaScript 框架(jQuery、 MooTools、 YUI 等等) ,看看它们是否可以做你想做的事情,或者让你更容易做你想做的事情。

我最近遇到过这个问题。不幸的是,我必须处理两个表,一个用于头部,一个用于主体。这可能不是有史以来最好的方法,但这里有:

<html>
<head>
<title>oh hai</title>
</head>
<body>
<table id="tableHeader">
<tr>
<th style="width:100px; background-color:#CCCCCC">col header</th>
<th style="width:100px; background-color:#CCCCCC">col header</th>
</tr>
</table>
<div style="height:50px; overflow:auto; width:250px">
<table>
<tr>
<td style="height:50px; width:100px; background-color:#DDDDDD">data1</td>
<td style="height:50px; width:100px; background-color:#DDDDDD">data1</td>
</tr>
<tr>
<td style="height:50px; width:100px; background-color:#DDDDDD">data2</td>
<td style="height:50px; width:100px; background-color:#DDDDDD">data2</td>
</tr>
</table>
</div>
</body>
</html>

这招对我很管用,可能不够优雅,但确实管用。我将进行调查,看看是否可以做得更好,但它允许多个表。

去阅读 溢出的适当性,看看它是否适合你的需要

可能的选择

浮动表头

Js-float-table-header (Google Code)

在 Drupal

我有一个 Drupal 6站点。我在管理“模块”页面,并注意到表具有这个确切的功能!

看看代码,它似乎是由一个名为 tableheader.js的文件实现的。它对类 sticky-enabled的所有表应用该特性。

对于 Drupal 站点,我希望能够按原样使用 tableheader.js模块来处理用户内容。在 Drupal 的用户内容页面上似乎没有 tableheader.js。我发布了一个 论坛留言询问如何修改 Drupal 主题,使其可用。根据回应,tableheader.js可以在主题的 template.php中使用 drupal_add_js()添加到 Drupal 主题中,如下所示:

drupal_add_js('misc/tableheader.js', 'core');

Craig,我对你的代码进行了一些改进(除了其他一些东西之外,它现在使用 position: fix) ,并把它包装成了一个 jQuery 插件。

试试这个: http://jsfiddle.net/jmosbech/stFcx/

然后找到来源: https://github.com/jmosbech/StickyTableHeaders

令人沮丧的是,在一个浏览器中运行良好的东西在另一个浏览器中却不起作用。以下内容适用于火狐浏览器,但不适用于 Chrome 或 IE 浏览器:

<table width="80%">


<thead>


<tr>
<th>Column 1</th>
<th>Column 2</th>
<th>Column 3</th>
</tr>


</thead>


<tbody style="height:50px; overflow:auto">


<tr>
<td>Cell A1</td>
<td>Cell B1</td>
<td>Cell C1</td>
</tr>


<tr>
<td>Cell A2</td>
<td>Cell B2</td>
<td>Cell C2</td>
</tr>


<tr>
<td>Cell A3</td>
<td>Cell B3</td>
<td>Cell C3</td>
</tr>


</tbody>


</table>

要在表上设置一个粘贴的头部,这确实是一件棘手的事情。我有相同的要求,但与 Asp: GridView,然后我发现它真的认为有粘性的网格视图头。有许多可用的解决方案,它花了我3天尝试所有的解决方案,但没有一个可以满足。

我面对的这些解决方案中大多数的主要问题是校准问题。当您尝试让标题浮动时,标题单元格和主体单元格的对齐会偏离轨道。

通过一些解决方案,我还遇到了头部与主体的前几行重叠的问题,这会导致主体行隐藏在浮动头部后面。

所以现在我必须实现我自己的逻辑来达到这个目的,虽然我也不认为这是完美的解决方案,但是这对某些人也是有帮助的,

下面是示例表。

<div class="table-holder">
<table id="MyTable" cellpadding="4" cellspacing="0" border="1px" class="customerTable">
<thead>
<tr><th>ID</th><th>First Name</th><th>Last Name</th><th>DOB</th><th>Place</th></tr>
</thead>
<tbody>
<tr><td>1</td><td>Customer1</td><td>LastName</td><td>1-1-1</td><td>SUN</td></tr>
<tr><td>2</td><td>Customer2</td><td>LastName</td><td>2-2-2</td><td>Earth</td></tr>
<tr><td>3</td><td>Customer3</td><td>LastName</td><td>3-3-3</td><td>Mars</td></tr>
<tr><td>4</td><td>Customer4</td><td>LastName</td><td>4-4-4</td><td>Venus</td></tr>
<tr><td>5</td><td>Customer5</td><td>LastName</td><td>5-5-5</td><td>Saturn</td></tr>
<tr><td>6</td><td>Customer6</td><td>LastName</td><td>6-6-6</td><td>Jupitor</td></tr>
<tr><td>7</td><td>Customer7</td><td>LastName</td><td>7-7-7</td><td>Mercury</td></tr>
<tr><td>8</td><td>Customer8</td><td>LastName</td><td>8-8-8</td><td>Moon</td></tr>
<tr><td>9</td><td>Customer9</td><td>LastName</td><td>9-9-9</td><td>Uranus</td></tr>
<tr><td>10</td><td>Customer10</td><td>LastName</td><td>10-10-10</td><td>Neptune</td></tr>
</tbody>
</table>
</div>

注意 : 该表被包装成一个 DIV,其 class 属性等于“ table-holder”。

下面是我在 html 页面标题中添加的 JQuery 脚本。

<script src="../Scripts/jquery-1.7.2.min.js" type="text/javascript"></script>
<script src="../Scripts/jquery-ui.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function () {
//create var for table holder
var originalTableHolder = $(".table-holder");
// set the table holder's with
originalTableHolder.width($('table', originalTableHolder).width() + 17);
// Create a clone of table holder DIV
var clonedtableHolder = originalTableHolder.clone();


// Calculate height of all header rows.
var headerHeight = 0;
$('thead', originalTableHolder).each(function (index, element) {
headerHeight = headerHeight + $(element).height();
});


// Set the position of cloned table so that cloned table overlapped the original
clonedtableHolder.css('position', 'relative');
clonedtableHolder.css('top', headerHeight + 'px');


// Set the height of cloned header equal to header height only so that body is not visible of cloned header
clonedtableHolder.height(headerHeight);
clonedtableHolder.css('overflow', 'hidden');


// reset the ID attribute of each element in cloned table
$('*', clonedtableHolder).each(function (index, element) {
if ($(element).attr('id')) {
$(element).attr('id', $(element).attr('id') + '_Cloned');
}
});


originalTableHolder.css('border-bottom', '1px solid #aaa');


// Place the cloned table holder before original one
originalTableHolder.before(clonedtableHolder);
});
</script>

最后是下面的 CSS 类,用于着色。

.table-holder
{
height:200px;
overflow:auto;
border-width:0px;
}


.customerTable thead
{
background: #4b6c9e;
color:White;
}

因此,这个逻辑的整体思想是将表放入一个表持有者 div 中,并在加载页面时在客户端创建该持有者的克隆。现在将表格的主体隐藏在克隆支架中,并将剩余的头部部分定位到原始头部。

同样的解决方案也适用于 asp: gridview,您需要在 gridview 中添加两个步骤来实现这一点,

  1. 在网页中栅格视图对象的 OnPreender 事件中,将标题行的表部分设置为 TableHeader。

    if (this.HeaderRow != null)
    {
    this.HeaderRow.TableSection = TableRowSection.TableHeader;
    }
    
  2. And wrap your grid into <div class="table-holder"></div>.

Note: if your header has clickable controls then you may need to add some more jQuery script to pass the events raised in cloned header to original header. This code is already available in jQuery sticky-header plugin create by jmosbech

看看 JQuery.floatThead (演示可用) ,这是非常酷的,也可以与 数据表一起工作,甚至可以在一个 overflow: auto容器内工作。

如果你的目标是现代的符合 css3标准的浏览器(浏览器支持: https://caniuse.com/#feat=css-sticky) ,你可以使用 position:sticky,它不需要 JS,也不会破坏表格布局,因为它没有对齐同一列的 th 和 td。它也不需要固定的列宽才能正常工作。

单个标题行的示例:

thead th
{
position: sticky;
top: 0px;
}

对于具有1或2行的头,您可以使用如下内容:

thead > :last-child th
{
position: sticky;
top: 30px; /* This is for all the the "th" elements in the second row, (in this casa is the last child element into the thead) */
}


thead > :first-child th
{
position: sticky;
top: 0px; /* This is for all the the "th" elements in the first child row */
}

您可能需要使用最后一个子元素的 头儿属性来更改像素数,以匹配第一行的高度(+ 边距 + 边框 + 填充,如果有的话) ,因此第二行刚好位于第一行的下方。

此外,即使在同一页面中有多个表,这两种解决方案都可以工作: 每个元素的 th元素开始变粘,当它的顶部位置是 css 定义中指示的那个时,当所有表向下滚动时,它就消失了。因此,如果有更多的桌子,所有的工作都完美相同的方式。

为什么要在 css 中使用最后一个子 之前和第一个子 之后

因为 css 规则是由浏览器按照写入 css 文件的顺序呈现的,因此如果你在 head 元素中只有1行,那么第一行同时也是最后一行,第一个子规则需要覆盖最后一个子规则。如果没有,你将有一个偏移行30像素从顶部边距,我想你不想。

一个已知的位置问题: 粘性是,它不工作的标题元素或表行: 您必须针对的元素。希望这个问题能在未来的浏览器版本中得到解决。

最简单的答案只使用 CSS: D! ! !

table {
/* Not required only for visualizing */
border-collapse: collapse;
width: 100%;
}


table thead tr th {
/* you could also change td instead th depending your html code */
background-color: green;
position: sticky;
z-index: 100;
top: 0;
}


td {
/* Not required only for visualizing */
padding: 1em;
}
<table>
<thead>
<tr>
<th>Col1</th>
<th>Col2</th>
<th>Col3</th>
</tr>
</thead>
<tbody>
<tr>
<td>data</td>
<td>data</td>
<td>data</td>
</tr>
<tr>
<td>data</td>
<td>data</td>
<td>data</td>
</tr>
<tr>
<td>data</td>
<td>data</td>
<td>data</td>
</tr>
<tr>
<td>data</td>
<td>data</td>
<td>data</td>
</tr>
<tr>
<td>data</td>
<td>data</td>
<td>data</td>
</tr>
<tr>
<td>data</td>
<td>data</td>
<td>data</td>
</tr>
<tr>
<td>data</td>
<td>data</td>
<td>data</td>
</tr>
<tr>
<td>data</td>
<td>data</td>
<td>data</td>
</tr>
<tr>
<td>data</td>
<td>data</td>
<td>data</td>
</tr>
<tr>
<td>data</td>
<td>data</td>
<td>data</td>
</tr>
<tr>
<td>data</td>
<td>data</td>
<td>data</td>
</tr>
<tr>
<td>data</td>
<td>data</td>
<td>data</td>
</tr>
<tr>
<td>data</td>
<td>data</td>
<td>data</td>
</tr>
<tr>
<td>data</td>
<td>data</td>
<td>data</td>
</tr>
<tr>
<td>david</td>
<td>castro</td>
<td>rocks!</td>
</tr>
</tbody>
</table>