带固定标题的HTML表格?

Che*_*oft 227 javascript css html-table

是否有跨浏览器的CSS/JavaScript技术来显示长HTML表格,使列标题保持固定在屏幕上,不要与表格主体一起滚动.想想Microsoft Excel中的"冻结窗格"效果.

我希望能够滚动表格的内容,但始终能够看到顶部的列标题.

Max*_*ils 177

这可以通过四行代码清晰地解决.

如果您只关心现代浏览器,那么使用CSS转换可以更轻松地实现固定标头.听起来很奇怪,但效果很好:

  • HTML和CSS保持原样.
  • 没有外部JavaScript依赖项.
  • 四行代码.
  • 适用于所有配置(表格布局:固定等).
document.getElementById("wrap").addEventListener("scroll", function(){
   var translate = "translate(0,"+this.scrollTop+"px)";
   this.querySelector("thead").style.transform = translate;
});
Run Code Online (Sandbox Code Playgroud)

除Internet Explorer 8外,广泛支持CSS转换.

以下是完整的参考示例:

document.getElementById("wrap").addEventListener("scroll",function(){
   var translate = "translate(0,"+this.scrollTop+"px)";
   this.querySelector("thead").style.transform = translate;
});
Run Code Online (Sandbox Code Playgroud)
/* Your existing container */
#wrap {
    overflow: auto;
    height: 400px;
}

/* CSS for demo */
td {
    background-color: green;
    width: 200px;
    height: 100px;
}
Run Code Online (Sandbox Code Playgroud)
<div id="wrap">
    <table>
        <thead>
            <tr>
                <th>Foo</th>
                <th>Bar</th>
            </tr>
        </thead>
        <tbody>
            <tr><td></td><td></td></tr>
            <tr><td></td><td></td></tr>
            <tr><td></td><td></td></tr>
            <tr><td></td><td></td></tr>
            <tr><td></td><td></td></tr>
            <tr><td></td><td></td></tr>
            <tr><td></td><td></td></tr>
            <tr><td></td><td></td></tr>
            <tr><td></td><td></td></tr>
            <tr><td></td><td></td></tr>
            <tr><td></td><td></td></tr>
            <tr><td></td><td></td></tr>
        </tbody>
    </table>
</div>
Run Code Online (Sandbox Code Playgroud)

  • 发现,它的工作原理,但必须将变换应用于th/td,而不是thead. (11认同)
  • 我不得不说,我之前的评论尽管如此,这是我见过的最完美解决方案.即使是水平滚动也是完美的(比我自己的解决方案更好).这是一个带边框的例子(你不能使用border-collapse)和一个坚持表而不是容器的滚动条:[jsfiddle](http://jsfiddle.net/doctorDestructo/gfbk73bp/) (7认同)
  • @AlexAlexeev,您的解决方案非常棒.谢谢.我注意到,生成的固定标题没有区分列的边框线.默认的CSS样式丢失.即使我包含这个...`$(this).addClass('border')`更改表格的其余部分,包括我在边框类中传递的字体,大小和颜色.但是,不会在固定标题中添加行.感谢,关于如何解决这个问题的任何意见 (5认同)
  • 这在任何版本的IE或Edge中都不起作用.这是基于@ redhead的评论https://jsfiddle.net/n6o8ocwb/2/的版本 (5认同)
  • @ user5249203我知道你几个月前问过,但我有同样的问题,这是由于边界崩溃:看到这个:http://stackoverflow.com/questions/33777751/combination-of-border-collapsecollapse-and- transformtranslate. (4认同)
  • 惊人!2调整我做了:1)我为表格标题设置了`background-color`,例如`{background-color:#fff; 滚动时去除标题下面的重叠.2)我从`this.scrollTop`中减去3(例如`var translate ="translate(0,"+(this.scrollTop-3)+"px)";`)因为行向上滚动了几个像素在消失之前.我不确定这些是否是基于我的其他标记的警告,但也许它们对其他人有用!(看着你,@ GregVeres!) (4认同)
  • 哇!好的,经过更多的搜索,2018年似乎确实有一个合适的解决方案.忘记所有这些魔法.只需使用以下CSS:`the the thth {position:sticky; 顶部:0; }` (3认同)
  • 不幸的是,它在IE 11中不起作用,有或没有供应商前缀:( (2认同)
  • 我们有什么办法可以“翻译”“thead”和“th”的边界以及 thead 吗? (2认同)

Mah*_*hes 87

我一直在寻找一个解决方案,发现大多数答案都不起作用或不适合我的情况,所以我用jQuery编写了一个简单的解决方案.

这是解决方案大纲:

  1. 克隆需要具有固定标头的表,并将克隆的副本放在原始文件的顶部.
  2. 从顶部桌子上取下桌子主体.
  3. 从底部表中删除表头.
  4. 调整列宽.(我们跟踪原始列宽)

以下是可运行演示中的代码.

function scrolify(tblAsJQueryObject, height) {
  var oTbl = tblAsJQueryObject;

  // for very large tables you can remove the four lines below
  // and wrap the table with <div> in the mark-up and assign
  // height and overflow property  
  var oTblDiv = $("<div/>");
  oTblDiv.css('height', height);
  oTblDiv.css('overflow', 'scroll');
  oTbl.wrap(oTblDiv);

  // save original width
  oTbl.attr("data-item-original-width", oTbl.width());
  oTbl.find('thead tr td').each(function() {
    $(this).attr("data-item-original-width", $(this).width());
  });
  oTbl.find('tbody tr:eq(0) td').each(function() {
    $(this).attr("data-item-original-width", $(this).width());
  });


  // clone the original table
  var newTbl = oTbl.clone();

  // remove table header from original table
  oTbl.find('thead tr').remove();
  // remove table body from new table
  newTbl.find('tbody tr').remove();

  oTbl.parent().parent().prepend(newTbl);
  newTbl.wrap("<div/>");

  // replace ORIGINAL COLUMN width				
  newTbl.width(newTbl.attr('data-item-original-width'));
  newTbl.find('thead tr td').each(function() {
    $(this).width($(this).attr("data-item-original-width"));
  });
  oTbl.width(oTbl.attr('data-item-original-width'));
  oTbl.find('tbody tr:eq(0) td').each(function() {
    $(this).width($(this).attr("data-item-original-width"));
  });
}

$(document).ready(function() {
  scrolify($('#tblNeedsScrolling'), 160); // 160 is height
});
Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>

<div style="width:300px;border:6px green solid;">
  <table border="1" width="100%" id="tblNeedsScrolling">
    <thead>
      <tr><th>Header 1</th><th>Header 2</th></tr>
    </thead>
    <tbody>
      <tr><td>row 1, cell 1</td><td>row 1, cell 2</td></tr>
      <tr><td>row 2, cell 1</td><td>row 2, cell 2</td></tr>
      <tr><td>row 3, cell 1</td><td>row 3, cell 2</td></tr>
      <tr><td>row 4, cell 1</td><td>row 4, cell 2</td></tr>			
      <tr><td>row 5, cell 1</td><td>row 5, cell 2</td></tr>
      <tr><td>row 6, cell 1</td><td>row 6, cell 2</td></tr>
      <tr><td>row 7, cell 1</td><td>row 7, cell 2</td></tr>
      <tr><td>row 8, cell 1</td><td>row 8, cell 2</td></tr>			
    </tbody>
  </table>
</div>
Run Code Online (Sandbox Code Playgroud)

此解决方案适用于Chrome和IE.由于它基于jQuery,因此它也适用于其他支持jQuery的浏览器.

  • 当内容大于宽度时,我们如何解决问题呢? (4认同)
  • 不幸的是,如果你需要列的像素完美对齐,这不起作用:http://jsbin.com/elekiq/1([源代码](http://jsbin.com/elekiq/1/edit) ).你可以看到一些标题偏离它们应该的位置,只是略微偏移.如果您使用背景,效果会更明显:http://jsbin.com/elekiq/2([源代码](http://jsbin.com/elekiq/2/edit)).(我正在按照这些相同的路线工作,在我的代码中遇到这个问题,找到你的并且想到"哦,我想知道他是否为我解决了这个问题!"可悲的是没有.:-))浏览器是一个想要控制它的痛苦细胞宽度...... (4认同)

Mar*_*ark 57

我刚刚完成了一个jQuery插件,它将使用有效的HTML(必须有一个thead和tbody)获取有效的单个表,并将输出一个具有固定标题的表,可选的固定页脚,可以是克隆的标题或任何你选择的内容(分页等).如果您想利用更大的显示器,它还会在调整浏览器大小时调整表的大小.另一个附加功能是,如果表格列不能全部适合视图,则可以侧滚动.

http://fixedheadertable.com/

在github上:http://markmalek.github.com/Fixed-Header-Table/

它非常容易设置,您可以为它创建自己的自定义样式.它还在所有浏览器中使用圆角.请记住,我刚刚发布它,所以它仍然是技术上的测试版,我正在熨平的问题很少.

它适用于Internet Explorer 7,Internet Explorer 8,Safari,Firefox和Chrome.

  • 最新版本在IE6中不起作用.我不再支持IE6了. (4认同)

mko*_*yak 23

我还创建了一个解决此问题的插件.我的项目--jQuery.floatThead已经存在了4年多,而且非常成熟.

它不需要外部样式,也不希望您的表格以任何特定方式设置样式.它支持Internet Explorer9 +和Firefox/Chrome.

目前(2018-05)它有:

GitHub上有405个提交和998个星


这里的许多(不是全部)答案都是快速的黑客攻击,可能已经解决了一个人遇到的问题,但不会对每张桌子都有效.

其他一些插件很旧,可能适用于Internet Explorer,但会在Firefox和Chrome上运行.

  • 大.非常感谢.该插件在Firefox 45.2,Chromium 51和IE 11中运行良好.此外,它不会干扰构建在同一页面上的大量JS和jQuery代码. (2认同)

Jon*_*son 20

TL; DR

如果您瞄准现代浏览器并且没有奢侈的样式需求:http://jsfiddle.net/dPixie/byB9d/3/ ...虽然四大版本非常好,但这个版本处理流体宽度要好得多.

大家好消息!

随着HTML5和CSS3的进步,现在这是可能的,至少对于现代浏览器而言.我想出的稍微讨厌的实现可以在这里找到:http://jsfiddle.net/dPixie/byB9d/3/.我在FX 25,Chrome 31和IE 10中进行了测试......

相关HTML(尽管在文档顶部插入HTML5文档类型):

html,
body {
  margin: 0;
  padding: 0;
  height: 100%;
}

section {
  position: relative;
  border: 1px solid #000;
  padding-top: 37px;
  background: #500;
}

section.positioned {
  position: absolute;
  top: 100px;
  left: 100px;
  width: 800px;
  box-shadow: 0 0 15px #333;
}

.container {
  overflow-y: auto;
  height: 200px;
}

table {
  border-spacing: 0;
  width: 100%;
}

td+td {
  border-left: 1px solid #eee;
}

td,
th {
  border-bottom: 1px solid #eee;
  background: #ddd;
  color: #000;
  padding: 10px 25px;
}

th {
  height: 0;
  line-height: 0;
  padding-top: 0;
  padding-bottom: 0;
  color: transparent;
  border: none;
  white-space: nowrap;
}

th div {
  position: absolute;
  background: transparent;
  color: #fff;
  padding: 9px 25px;
  top: 0;
  margin-left: -25px;
  line-height: normal;
  border-left: 1px solid #800;
}

th:first-child div {
  border: none;
}
Run Code Online (Sandbox Code Playgroud)

有了这个CSS:

<section class="positioned">
  <div class="container">
    <table>
      <thead>
        <tr class="header">
          <th>
            Table attribute name
            <div>Table attribute name</div>
          </th>
          <th>
            Value
            <div>Value</div>
          </th>
          <th>
            Description
            <div>Description</div>
          </th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>align</td>
          <td>left, center, right</td>
          <td>Not supported in HTML5. Deprecated in HTML 4.01. Specifies the alignment of a table according to surrounding text</td>
        </tr>
        <tr>
          <td>bgcolor</td>
          <td>rgb(x,x,x), #xxxxxx, colorname</td>
          <td>Not supported in HTML5. Deprecated in HTML 4.01. Specifies the background color for a table</td>
        </tr>
        <tr>
          <td>border</td>
          <td>1,""</td>
          <td>Specifies whether the table cells should have borders or not</td>
        </tr>
        <tr>
          <td>cellpadding</td>
          <td>pixels</td>
          <td>Not supported in HTML5. Specifies the space between the cell wall and the cell content</td>
        </tr>
        <tr>
          <td>cellspacing</td>
          <td>pixels</td>
          <td>Not supported in HTML5. Specifies the space between cells</td>
        </tr>
        <tr>
          <td>frame</td>
          <td>void, above, below, hsides, lhs, rhs, vsides, box, border</td>
          <td>Not supported in HTML5. Specifies which parts of the outside borders that should be visible</td>
        </tr>
        <tr>
          <td>rules</td>
          <td>none, groups, rows, cols, all</td>
          <td>Not supported in HTML5. Specifies which parts of the inside borders that should be visible</td>
        </tr>
        <tr>
          <td>summary</td>
          <td>text</td>
          <td>Not supported in HTML5. Specifies a summary of the content of a table</td>
        </tr>
        <tr>
          <td>width</td>
          <td>pixels, %</td>
          <td>Not supported in HTML5. Specifies the width of a table</td>
        </tr>
      </tbody>
    </table>
  </div>
</section>
Run Code Online (Sandbox Code Playgroud)

但是如何?!

简单地说,你有一个表头,你可以通过使其高度为0px来隐藏它,它还包含用作固定头的div.桌子的容器在顶部留出足够的空间以允许绝对定位的标题,并且带有滚动条的表格如您所期望的那样出现.

上面的代码使用定位的类来绝对定位表(我在弹出样式对话框中使用它),但是您可以在文档流中使用它,也可以positioned从容器中删除类.

但......

这不完美.Firefox拒绝将标题行设为0px(至少我没有找到任何方法)但是固执地将它保持在最低4px ...这不是一个大问题,但根据你的造型它会弄乱你的边界等.

该表还使用了一种虚拟列方法,其中容器本身的背景颜色用作标题div的背景,这是透明的.

摘要

总而言之,根据您的要求,可能存在造型问题,尤其是边框或复杂背景.可计算性也可能存在问题,我还没有在各种各样的浏览器中检查过它(如果你尝试的话请用你的经验评论),但我没有找到类似的东西,所以我觉得值得发帖无论如何......


djs*_*off 19

从CSS规范之外解决这个问题的所有尝试都是我们真正想要的阴影:交付THEAD的隐含承诺.

这个用于表格的冻结标题长期以来一直是HTML/CSS中的一个开放性创伤.

在一个完美的世界中,会有一个纯CSS解决方案来解决这个问题.不幸的是,似乎没有一个好的.

相关标准 - 关于该主题的讨论包括:

更新:Firefox position:sticky在版本32中发布.每个人都赢了!

  • 回覆.Firefox和位置:粘性,它不适用于表头:https://bugzilla.mozilla.org/show_bug.cgi?id = 925259 #c8 ...该错误的补丁明确指出:"我们不目前支持内部表元素的相对定位,因此我们也将其排除在粘性定位之外." (4认同)
  • 这现在适用于所有浏览器:`thead th { position: sticky; 顶部:0;}`。我们可以更新此答案以明确说明这一点吗? (3认同)

oma*_*oma 14

这是一个用于固定表头的jQuery插件.它允许整个页面滚动,当标题到达顶部时冻结标题.它适用于Twitter Bootstrap表.

GitHub存储库:https://github.com/oma/table-fixed-header

它并没有滚动只表的内容.看看其他工具,作为其他答案之一.你决定什么最适合你的情况.


小智 9

这里发布的大多数解决方案都需要jQuery.如果您正在寻找独立于框架的解决方案,请尝试使用Grid:http://www.matts411.com/post/grid/

它在Github上托管:https://github.com/mmurph211/Grid

它不仅支持固定标题,还支持固定的左列和页脚等.


Doc*_*cto 6

一个更精致的纯CSS滚动表

到目前为止我见过的所有纯CSS解决方案 - 虽然可能很聪明 - 缺乏一定程度的润色,或者在某些情况下不能正常工作.所以,我决定创建自己的......

特征:

  • 这是纯CSS,所以不需要jQuery(或任何JavaScript代码,就此而言)
  • 您可以将表格宽度设置为百分比(也称为"流体")或固定值,或让内容确定其宽度(也称为"自动")
  • 列宽也可以是流体,固定或自动.
  • 由于水平滚动,列永远不会与标题不对齐(在我看到的其他基于CSS的解决方案中出现的问题不需要固定宽度).
  • 兼容所有流行的桌面浏览器,包括Internet Explorer返回版本8
  • 清洁,抛光外观; 看上去没有看上去像素的1像素间隙或未对齐的边框; 在所有浏览器中看起来都一样

以下是一些显示流体和自动宽度选项的小提琴:

  • 流体宽度和高度(适应屏幕尺寸):jsFiddle(请注意,滚动条仅在此配置中需要时显示,因此您可能需要缩小框架才能看到它)

  • 自动宽度,固定高度(更容易与其他内容集成):jsFiddle

自动宽度,固定高度配置可能有更多的用例,所以我将发布下面的代码.

/* The following 'html' and 'body' rule sets are required only
   if using a % width or height*/

/*html {
  width: 100%;
  height: 100%;
}*/

body {
  box-sizing: border-box;
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0 20px 0 20px;
  text-align: center;
}
.scrollingtable {
  box-sizing: border-box;
  display: inline-block;
  vertical-align: middle;
  overflow: hidden;
  width: auto; /* If you want a fixed width, set it here, else set to auto */
  min-width: 0/*100%*/; /* If you want a % width, set it here, else set to 0 */
  height: 188px/*100%*/; /* Set table height here; can be fixed value or % */
  min-height: 0/*104px*/; /* If using % height, make this large enough to fit scrollbar arrows + caption + thead */
  font-family: Verdana, Tahoma, sans-serif;
  font-size: 16px;
  line-height: 20px;
  padding: 20px 0 20px 0; /* Need enough padding to make room for caption */
  text-align: left;
  color: black;
}
.scrollingtable * {box-sizing: border-box;}
.scrollingtable > div {
  position: relative;
  border-top: 1px solid black;
  height: 100%;
  padding-top: 20px; /* This determines column header height */
}
.scrollingtable > div:before {
  top: 0;
  background: cornflowerblue; /* Header row background color */
}
.scrollingtable > div:before,
.scrollingtable > div > div:after {
  content: "";
  position: absolute;
  z-index: -1;
  width: 100%;
  height: 100%;
  left: 0;
}
.scrollingtable > div > div {
  min-height: 0/*43px*/; /* If using % height, make this large
                            enough to fit scrollbar arrows */
  max-height: 100%;
  overflow: scroll/*auto*/; /* Set to auto if using fixed
                               or % width; else scroll */
  overflow-x: hidden;
  border: 1px solid black; /* Border around table body */
}
.scrollingtable > div > div:after {background: white;} /* Match page background color */
.scrollingtable > div > div > table {
  width: 100%;
  border-spacing: 0;
  margin-top: -20px; /* Inverse of column header height */
  /*margin-right: 17px;*/ /* Uncomment if using % width */
}
.scrollingtable > div > div > table > caption {
  position: absolute;
  top: -20px; /*inverse of caption height*/
  margin-top: -1px; /*inverse of border-width*/
  width: 100%;
  font-weight: bold;
  text-align: center;
}
.scrollingtable > div > div > table > * > tr > * {padding: 0;}
.scrollingtable > div > div > table > thead {
  vertical-align: bottom;
  white-space: nowrap;
  text-align: center;
}
.scrollingtable > div > div > table > thead > tr > * > div {
  display: inline-block;
  padding: 0 6px 0 6px; /*header cell padding*/
}
.scrollingtable > div > div > table > thead > tr > :first-child:before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  height: 20px; /*match column header height*/
  border-left: 1px solid black; /*leftmost header border*/
}
.scrollingtable > div > div > table > thead > tr > * > div[label]:before,
.scrollingtable > div > div > table > thead > tr > * > div > div:first-child,
.scrollingtable > div > div > table > thead > tr > * + :before {
  position: absolute;
  top: 0;
  white-space: pre-wrap;
  color: white; /*header row font color*/
}
.scrollingtable > div > div > table > thead > tr > * > div[label]:before,
.scrollingtable > div > div > table > thead > tr > * > div[label]:after {content: attr(label);}
.scrollingtable > div > div > table > thead > tr > * + :before {
  content: "";
  display: block;
  min-height: 20px; /* Match column header height */
  padding-top: 1px;
  border-left: 1px solid black; /* Borders between header cells */
}
.scrollingtable .scrollbarhead {float: right;}
.scrollingtable .scrollbarhead:before {
  position: absolute;
  width: 100px;
  top: -1px; /* Inverse border-width */
  background: white; /* Match page background color */
}
.scrollingtable > div > div > table > tbody > tr:after {
  content: "";
  display: table-cell;
  position: relative;
  padding: 0;
  border-top: 1px solid black;
  top: -1px; /* Inverse of border width */
}
.scrollingtable > div > div > table > tbody {vertical-align: top;}
.scrollingtable > div > div > table > tbody > tr {background: white;}
.scrollingtable > div > div > table > tbody > tr > * {
  border-bottom: 1px solid black;
  padding: 0 6px 0 6px;
  height: 20px; /* Match column header height */
}
.scrollingtable > div > div > table > tbody:last-of-type > tr:last-child > * {border-bottom: none;}
.scrollingtable > div > div > table > tbody > tr:nth-child(even) {background: gainsboro;} /* Alternate row color */
.scrollingtable > div > div > table > tbody > tr > * + * {border-left: 1px solid black;} /* Borders between body cells */
Run Code Online (Sandbox Code Playgroud)
<div class="scrollingtable">
  <div>
    <div>
      <table>
        <caption>Top Caption</caption>
        <thead>
          <tr>
            <th><div label="Column 1"/></th>
            <th><div label="Column 2"/></th>
            <th><div label="Column 3"/></th>
            <th>
              <!-- More versatile way of doing column label; requires two identical copies of label -->
              <div><div>Column 4</div><div>Column 4</div></div>
            </th>
            <th class="scrollbarhead"/> <!-- ALWAYS ADD THIS EXTRA CELL AT END OF HEADER ROW -->
          </tr>
        </thead>
        <tbody>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
        </tbody>
      </table>
    </div>
    Faux bottom caption
  </div>
</div>

<!--[if lte IE 9]><style>.scrollingtable > div > div > table {margin-right: 17px;}</style><![endif]-->
Run Code Online (Sandbox Code Playgroud)

我用来冻结标题行的方法类似于d-Pixie的,所以请参考他的帖子进行解释.这种技术存在大量的漏洞和限制,只能通过大量额外的CSS和一个或多个div容器来修复.


Dan*_*rip 6

CSS属性position: sticky在大多数现代浏览器中都有很好的支持(Edge出现了问题,请参见下文)。

这使我们可以很轻松地解决固定标头的问题:

thead th { position: sticky; top: 0; }
Run Code Online (Sandbox Code Playgroud)

Safari需要供应商前缀:-webkit-sticky

对于Firefox,我必须将min-height: 0父元素添加到一个。我完全忘记了为什么需要这样做。

最不幸的是,Microsoft Edge实施似乎只是半成品。至少,我在测试中有一些闪烁且未对齐的表格单元。该桌子仍然可用,但存在重大美学问题。

  • 在具有“overflow:scroll;”、“overflow-x:scroll;”或“overflow-y:scroll;”的 div 内使用“position:sticky;”。似乎是现代浏览器中固定表头和列的最佳和最简单的解决方案。这个答案需要投票通过。 (2认同)

Nat*_*ong 5

一个简单的jQuery插件

这是Mahes解决方案的变体.你可以这样称呼它$('table#foo').scrollableTable();

这个想法是:

  • 拆分theadtbody分成单独的table元素
  • 使其单元格宽度再次匹配
  • 包裹第二tablediv.scrollable
  • 使用CSS div.scrollable实际滚动

CSS可以是:

div.scrollable { height: 300px; overflow-y: scroll;}
Run Code Online (Sandbox Code Playgroud)

注意事项

  • 显然,拆分这些表会使标记语义更少.我不确定这对可访问性有什么影响.
  • 此插件不处理页脚,多个标题等.
  • 我只在Chrome 20版中测试过它.

也就是说,它适用于我的目的,你可以随意采取和修改它.

这是插件:

jQuery.fn.scrollableTable = function () {
  var $newTable, $oldTable, $scrollableDiv, originalWidths;
  $oldTable = $(this);

  // Once the tables are split, their cell widths may change. 
  // Grab these so we can make the two tables match again.
  originalWidths = $oldTable.find('tr:first td').map(function() {
    return $(this).width();
  });

  $newTable = $oldTable.clone();
  $oldTable.find('tbody').remove();
  $newTable.find('thead').remove();

  $.each([$oldTable, $newTable], function(index, $table) {
    $table.find('tr:first td').each(function(i) {
      $(this).width(originalWidths[i]);
    });
  });

  $scrollableDiv = $('<div/>').addClass('scrollable');
  $newTable.insertAfter($oldTable).wrap($scrollableDiv);
};
Run Code Online (Sandbox Code Playgroud)


Ant*_*kov 5

:)

不那么干净,但纯粹的 HTML/CSS 解决方案。

table {
    overflow-x:scroll;
}

tbody {
    max-height: /*your desired max height*/
    overflow-y:scroll;
    display:block;
}
Run Code Online (Sandbox Code Playgroud)

更新了 IE8+ JSFiddle 示例

  • 好的解决方案,只是提一下,这些单元格是浮动的,因此根据内容可以有不同的高度,如果您设置它们的边框,它是可见的:http://jsfiddle.net/ZdeEH/15/ (2认同)

Mun*_*yar 5

不知何故,我最终Position:Sticky在我的案子上工作得很好:

table{
  width: 100%;
  border: collapse;
}

th{
    position: sticky;
    top: 0px;
    border: 1px solid black;
    background: #ff5722;
    color: #f5f5f5;
    font-weight: 600;
}
td{
    background: #d3d3d3;
    border: 1px solid black;
    color: #f5f5f5;
    font-weight: 600;
}

div{
  height: 150px
  overflow: auto;
  width: 100%
}
Run Code Online (Sandbox Code Playgroud)
<div>
    <table>
        <thead>
            <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>
                <th>header 7</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>data 1</td>
                <td>data 2</td>
                <td>data 3</td>
                <td>data 4</td>
                <td>data 5</td>
                <td>data 6</td>
                <td>data 7</td>
            </tr>
            <tr>
                <td>data 1</td>
                <td>data 2</td>
                <td>data 3</td>
                <td>data 4</td>
                <td>data 5</td>
                <td>data 6</td>
                <td>data 7</td>
            </tr>
            <tr>
                <td>data 1</td>
                <td>data 2</td>
                <td>data 3</td>
                <td>data 4</td>
                <td>data 5</td>
                <td>data 6</td>
                <td>data 7</td>
            </tr>
            <tr>
                <td>data 1</td>
                <td>data 2</td>
                <td>data 3</td>
                <td>data 4</td>
                <td>data 5</td>
                <td>data 6</td>
                <td>data 7</td>
            </tr>
            <tr>
                <td>data 1</td>
                <td>data 2</td>
                <td>data 3</td>
                <td>data 4</td>
                <td>data 5</td>
                <td>data 6</td>
                <td>data 7</td>
            </tr>
            <tr>
                <td>data 1</td>
                <td>data 2</td>
                <td>data 3</td>
                <td>data 4</td>
                <td>data 5</td>
                <td>data 6</td>
                <td>data 7</td>
            </tr>
            <tr>
                <td>data 1</td>
                <td>data 2</td>
                <td>data 3</td>
                <td>data 4</td>
                <td>data 5</td>
                <td>data 6</td>
                <td>data 7</td>
            </tr>
            <tr>
                <td>data 1</td>
                <td>data 2</td>
                <td>data 3</td>
                <td>data 4</td>
                <td>data 5</td>
                <td>data 6</td>
                <td>data 7</td>
            </tr>
            <tr>
                <td>data 1</td>
                <td>data 2</td>
                <td>data 3</td>
                <td>data 4</td>
                <td>data 5</td>
                <td>data 6</td>
                <td>data 7</td>
            </tr>
            <tr>
                <td>data 1</td>
                <td>data 2</td>
                <td>data 3</td>
                <td>data 4</td>
                <td>data 5</td>
                <td>data 6</td>
                <td>data 7</td>
            </tr>
            <tr>
                <td>data 1</td>
                <td>data 2</td>
                <td>data 3</td>
                <td>data 4</td>
                <td>data 5</td>
                <td>data 6</td>
                <td>data 7</td>
            </tr>
            <tr>
                <td>data 1</td>
                <td>data 2</td>
                <td>data 3</td>
                <td>data 4</td>
                <td>data 5</td>
                <td>data 6</td>
                <td>data 7</td>
            </tr>
            <tr>
                <td>data 1</td>
                <td>data 2</td>
                <td>data 3</td>
                <td>data 4</td>
                <td>data 5</td>
                <td>data 6</td>
                <td>data 7</td>
            </tr>
            <tr>
                <td>data 1</td>
                <td>data 2</td>
                <td>data 3</td>
                <td>data 4</td>
                <td>data 5</td>
                <td>data 6</td>
                <td>data 7</td>
            </tr>
        </tbody>
    </table>
</div>
Run Code Online (Sandbox Code Playgroud)