在纯 CSS 上具有固定标题和固定列的表

     2023-03-05     297

关键词:

【中文标题】在纯 CSS 上具有固定标题和固定列的表【英文标题】:Table with fixed header and fixed column on pure css 【发布时间】:2013-03-26 13:17:18 【问题描述】:

我需要创建一个带有固定标题和固定第一列的 html 表格(或类似的外观)。

目前我看到的每个解决方案都使用 Javascript 或 jQuery 来设置 scrollTop/scrollLeft,但它在移动浏览器上运行不顺畅,所以我正在寻找一个纯 CSS 解决方案。

我在这里找到了固定列的解决方案:jsfiddle.net/C8Dtf/20/,但我不知道如何增强它以使标题也固定。

我希望它在 webkit 浏览器上工作或使用一些 css3 功能,但我再说一遍,我不想使用 Javascript 进行滚动。

编辑:这是我想要实现的行为示例:https://web.archive.org/web/20130829032141/http://datatables.net/release-datatables/extras/FixedColumns/css_size.html

【问题讨论】:

我暂时没有看到带有固定标题 的 与 css-level-3 有什么关系。你还有什么?到目前为止你尝试过什么? 我尝试将复杂的position 行为应用于行和单元格,但我不太明白它在哪里适用。这个答案可能对你有帮助***.com/questions/14834198/…
【参考方案1】:

具有固定标题行和第一列的纯 CSS 解决方案

position: sticky 属性在 Chrome、Firefox 和 Edge 的现代版本中支持顶部和侧面。这可以与具有overflow: scroll 属性的div 结合使用,为您提供一个带有固定标题的表格,可以放置在页面的任何位置。

将您的桌子放入容器中:

<div class="container">
  <table></table>
</div>

在您的容器上使用overflow: scroll 来启用滚动:

div.container 
  overflow: scroll;

正如 Dagmar 在 cmets 中指出的那样,容器还需要 max-widthmax-height

使用position: sticky 让表格单元格贴在边缘,使用toprightleft 选择贴在哪个边缘:

thead th 
  position: -webkit-sticky; /* for Safari */
  position: sticky;
  top: 0;


tbody th 
  position: -webkit-sticky; /* for Safari */
  position: sticky;
  left: 0;

正如 cmets 中提到的MarredCheese,如果您的第一列包含&lt;td&gt; 元素而不是&lt;th&gt; 元素,您可以在CSS 中使用tbody td:first-child 而不是tbody th

要将第一列中的标题固定在左侧,请使用:

thead th:first-child 
  left: 0;
  z-index: 1;

/* Use overflow:scroll on your container to enable scrolling: */

div 
  max-width: 400px;
  max-height: 150px;
  overflow: scroll;



/* Use position: sticky to have it stick to the edge
 * and top, right, or left to choose which edge to stick to: */

thead th 
  position: -webkit-sticky; /* for Safari */
  position: sticky;
  top: 0;


tbody th 
  position: -webkit-sticky; /* for Safari */
  position: sticky;
  left: 0;



/* To have the header in the first column stick to the left: */

thead th:first-child 
  left: 0;
  z-index: 2;



/* Just to display it nicely: */

thead th 
  background: #000;
  color: #FFF;
  /* Ensure this stays above the emulated border right in tbody th : */
  z-index: 1;


tbody th 
  background: #FFF;
  border-right: 1px solid #CCC;
  /* Browsers tend to drop borders on sticky elements, so we emulate the border-right using a box-shadow to ensure it stays: */
  box-shadow: 1px 0 0 0 #ccc;


table 
  border-collapse: collapse;


td,
th 
  padding: 0.5em;
<div>
  <table>
    <thead>
      <tr>
        <th></th>
        <th>headheadhead</th>
        <th>headheadhead</th>
        <th>headheadhead</th>
        <th>headheadhead</th>
        <th>headheadhead</th>
        <th>headheadhead</th>
        <th>headheadhead</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <th>head</th>
        <td>body</td>
        <td>body</td>
        <td>body</td>
        <td>body</td>
        <td>body</td>
        <td>body</td>
        <td>body</td>
      </tr>
      <tr>
        <th>head</th>
        <td>body</td>
        <td>body</td>
        <td>body</td>
        <td>body</td>
        <td>body</td>
        <td>body</td>
        <td>body</td>
      </tr>
      <tr>
        <th>head</th>
        <td>body</td>
        <td>body</td>
        <td>body</td>
        <td>body</td>
        <td>body</td>
        <td>body</td>
        <td>body</td>
      </tr>
      <tr>
        <th>head</th>
        <td>body</td>
        <td>body</td>
        <td>body</td>
        <td>body</td>
        <td>body</td>
        <td>body</td>
        <td>body</td>
      </tr>
      <tr>
        <th>head</th>
        <td>body</td>
        <td>body</td>
        <td>body</td>
        <td>body</td>
        <td>body</td>
        <td>body</td>
        <td>body</td>
      </tr>
      <tr>
        <th>head</th>
        <td>body</td>
        <td>body</td>
        <td>body</td>
        <td>body</td>
        <td>body</td>
        <td>body</td>
        <td>body</td>
      </tr>
    </tbody>
  </table>
</div>

https://jsfiddle.net/qwubvg9m/1/

【讨论】:

这似乎是最好的答案。 @PirateApp 如果您知道第一列的width,您可以在第二列的单元格上使用position: sticky,其left 值等于第一列的width: jsfiddle.net/wvypo83c/794 这个答案证明,一直读到底是值得的! 如果没有在容器上设置最大宽度和最大高度,这将不起作用。 这个答案是一座灯塔,指引我们通过无休止的故障海洋、过于复杂、浪费时间的答案,这些答案来自 SO 和网络上令人惊讶的自信、令人费解的高票。请注意,如果您的第一列包含 &lt;td&gt; 元素而不是 &lt;th&gt; 元素,则可以在 CSS 中使用 tbody td:first-child 而不是 tbody th【参考方案2】:

现在,这有可能使用 CSS onlyposition: sticky 属性来实现。

这里有一个sn-p:

(jsFiddle:https://jsfiddle.net/hbqzdzdt/5/)

.grid-container 
  display: grid; /* This is a (hacky) way to make the .grid element size to fit its content */
  overflow: auto;
  height: 300px;
  width: 600px;

.grid 
  display: flex;
  flex-wrap: nowrap;

.grid-col 
  width: 150px;
  min-width: 150px;


.grid-item--header 
  height: 100px;
  min-height: 100px;
  position: sticky;
  position: -webkit-sticky;
  background: white;
  top: 0;


.grid-col--fixed-left 
  position: sticky;
  left: 0;
  z-index: 9998;
  background: white;

.grid-col--fixed-right 
  position: sticky;
  right: 0;
  z-index: 9998;
  background: white;


.grid-item 
  height: 50px;
  border: 1px solid gray;
<div class="grid-container">
  <div class="grid">
    <div class="grid-col grid-col--fixed-left">
      <div class="grid-item grid-item--header">
        <p>HEAD</p>
      </div>
      <div class="grid-item">
        <p>Hello</p>
      </div>
      <div class="grid-item">
        <p>Hello</p>
      </div>
      <div class="grid-item">
        <p>Hello</p>
      </div>
      <div class="grid-item">
        <p>Hello</p>
      </div>
      <div class="grid-item">
        <p>Hello</p>
      </div>
      <div class="grid-item">
        <p>Hello</p>
      </div>
      <div class="grid-item">
        <p>Hello</p>
      </div>
      <div class="grid-item">
        <p>Hello</p>
      </div>
      <div class="grid-item">
        <p>Hello</p>
      </div>
      <div class="grid-item">
        <p>Hello</p>
      </div>
    </div>

    <div class="grid-col">
      <div class="grid-item grid-item--header">
        <p>HEAD</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
    </div>

    <div class="grid-col">
      <div class="grid-item grid-item--header">
        <p>HEAD</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
    </div>

    <div class="grid-col">
      <div class="grid-item grid-item--header">
        <p>HEAD</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
    </div>

    <div class="grid-col">
      <div class="grid-item grid-item--header">
        <p>HEAD</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
    </div>

    <div class="grid-col">
      <div class="grid-item grid-item--header">
        <p>HEAD</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
    </div>

    <div class="grid-col">
      <div class="grid-item grid-item--header">
        <p>HEAD</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
    </div>

    <div class="grid-col">
      <div class="grid-item grid-item--header">
        <p>HEAD</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
    </div>

    <div class="grid-col">
      <div class="grid-item grid-item--header">
        <p>HEAD</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
    </div>

    <div class="grid-col">
      <div class="grid-item grid-item--header">
        <p>HEAD</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
    </div>

    <div class="grid-col">
      <div class="grid-item grid-item--header">
        <p>HEAD</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
    </div>

    <div class="grid-col grid-col--fixed-right">
      <div class="grid-item grid-item--header">
        <p>HEAD</p>
      </div>
      <div class="grid-item">
        <p>9</p>
      </div>
      <div class="grid-item">
        <p>9</p>
      </div>
      <div class="grid-item">
        <p>9</p>
      </div>
      <div class="grid-item">
        <p>9</p>
      </div>
      <div class="grid-item">
        <p>9</p>
      </div>
      <div class="grid-item">
        <p>9</p>
      </div>
      <div class="grid-item">
        <p>9</p>
      </div>
      <div class="grid-item">
        <p>9</p>
      </div>
      <div class="grid-item">
        <p>9</p>
      </div>
      <div class="grid-item">
        <p>9</p>
      </div>
    </div>

  </div>
</div>

关于兼容性。它适用于所有主流浏览器,但不适用于 IE。 position: sticky 有一个 polyfill,但我从未尝试过。

【讨论】:

这很棒,喜欢它! 使用 -tags 而不是 的任何方法 我认为如果您正在开发应用程序并且需要遍历记录以打印此表,这不会有很好的性能,因为对于表中的每一列,您必须遍历整个记录大批。此 HTML 逐列工作。@igasparetto 您实际上可以以相反的方式排列行/列,并且该解决方案仍然有效。如果以后有时间,我可以使用网格有序行 -> 列创建一个 sn-p。我建议不要在不使用
和相关标签的情况下显示表格数据。以这种方式破坏 HTML 的预期用途存在几个问题,包括可访问性。另见:w3.org/WAI/tutorials/tables
【参考方案3】:

所有这些建议都很棒,但它们要么只修复标题或列,而不是两者,要么它们使用的是 javascript。原因 - 它不相信它可以在纯 CSS 中完成。原因:

如果可以的话,您需要将多个可滚动的 div 嵌套在一个内部,每个 div 的滚动方向不同。然后你需要把你的表分成三部分——固定的标题、固定的列和其余的数据。

很好。但是现在的问题 - 你可以让其中一个在滚动时保持原样,但另一个嵌套在 first 的滚动区域内,因此会被滚动到视线之外,因此无法固定在屏幕。 '啊哈'你说'但我可以以某种方式使用绝对或固定位置来做到这一点' - 不,你不能。一旦您这样做,您将失去滚动该容器的能力。这是先有鸡还是先有蛋的情况 - 你不能两者兼得,它们会相互抵消。

我相信唯一的解决方案是通过 javascript。您需要完全分离出三个元素并通过 javascript 保持它们的位置同步。此页面上的其他帖子中有很好的示例。这个也值得一看:

http://tympanus.net/codrops/2014/01/09/sticky-table-headers-columns/

【讨论】:

这应该被接受为这个问题的答案,除非并且直到未来版本的 CSS 覆盖此行为。【参考方案4】:

这绝非易事。

以下链接是一个工作演示:

链接已根据 lanoxx 的评论更新

http://jsfiddle.net/C8Dtf/366/

记得添加这些:

<script type="text/javascript" charset="utf-8" src="http://datatables.net/release-datatables/media/js/jquery.js"></script>
<script type="text/javascript" charset="utf-8" src="http://datatables.net/release-datatables/media/js/jquery.dataTables.js"></script>
<script type="text/javascript" charset="utf-8" src="http://datatables.net/release-datatables/extras/FixedColumns/media/js/FixedColumns.js"></script>

我没有看到任何其他方式来实现这一点。 尤其不能只使用 css。

要经历很多事情。 希望这会有所帮助:)

【讨论】:

过滤器的切换使用:"bFilter": false 可能只用 css 来实现。不容易,但可能。 从大约 10 个解决方案中,这是唯一一个有效的解决方案。顺便说一句,要删除“显示 57 个条目中的 1 到 57 个”,请将 "bInfo" : false 添加到 .dataTable() 调用中 数据表 == "真棒" 不赞成这个解决方案,因为它很糟糕。 thead 在它自己的表格中,它不会绑定到 td 元素的变化,所以如果单元格文本很长,th 宽度将不会相应调整。【参考方案5】:

我在 jsfiddle 中做了一些更改。这可能是你想要做的。

http://jsfiddle.net/C8Dtf/81/

我对标题进行了硬编码,如下所示:

<table id="left_table" class="freeze_table">
    <tr class='tblTitle'>
         <th>Title 1</th>
         <th>Title 2</th>
    </tr>
</table>

我还添加了一些样式。

.tblTitle
   position:absolute;
    top:0px;
    margin-bottom:30px;
    background:lightblue;

td, th
    padding:5px;
    height:40px;
    width:40px;
    font-size:14px;

希望这是你想要的 :)

【讨论】:

我需要右表的表头连同其内容一起滚动。 这里是网址:jsfiddle.net/C8Dtf/84。您只需要调整右侧表格的样式即可对齐两个表格。 没有。你不太明白。我需要将右表的标题固定在顶部,以便在表格上下滚动时仍然可见,但是当表格向右或向左滚动时,标题必须向右或向左滚动,但仍固定在顶部。对不起,我的英语不好。 那么希望右侧表格的标题在垂直滚动时固定,在水平滚动时滚动? 这是我想要实现的行为示例:datatables.net/release-datatables/extras/FixedColumns/…【参考方案6】:

仅使用 CSS 的示例:

.table 
  table-layout: fixed;
  width: 500px;
  border-collapse: collapse;


.header th 
  font-family: Calibri;
  font-size: small;
  font-weight: lighter;
  border-left: 1px solid #000;
  background: #d0d0d0;


.body_panel 
  display: inline-block;
  width: 520px;
  height: 300px;
  overflow-y: scroll;


.body tr 
  border-bottom: 1px solid #d0d0d0;


.body td 
  border-left: 1px solid #d0d0d0;
  padding-left: 3px;
  font-family: Calibri;
  font-size: small;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
<body>

  <table class="table">

    <thead class="header">

      <tr>
        <th style="width:20%;">teste</th>
        <th style="width:30%;">teste 2</th>
        <th style="width:50%;">teste 3</th>
      </tr>

    </thead>
  </table>

  <div class="body_panel">

    <table class="table">
      <tbody class="body">

        <tr>
          <td style="width:20%;">asbkj k kajsb ksb kabkb</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

      </tbody>
    </table>

  </div>

</body>

【讨论】:

我不仅需要修复 heder,还需要第一列。 这个例子展示了一种在 html 中有两个表的方法:一个表只呈现标题;第二个表只呈现行,但在div 中这样做。是 div 允许行滚动,而标题保持在同一个位置。这种方法可以满足我的需求。 如果也有横向滚动,需要一些JS来同步表格的滚动位置。【参考方案7】:

我找到了 Paul O'Brien 为该问题提供的出色解决方案,并希望分享以下链接: https://codepen.io/paulobrien/pen/LBrMxa

我删除了页脚的样式:

html 
  box-sizing: border-box;

*,
*:before,
*:after 
  box-sizing: inherit;

.intro 
  max-width: 1280px;
  margin: 1em auto;

.table-scroll 
  position: relative;
  width:100%;
  z-index: 1;
  margin: auto;
  overflow: auto;
  height: 350px;

.table-scroll table 
  width: 100%;
  min-width: 1280px;
  margin: auto;
  border-collapse: separate;
  border-spacing: 0;

.table-wrap 
  position: relative;

.table-scroll th,
.table-scroll td 
  padding: 5px 10px;
  border: 1px solid #000;

.table-scroll thead th 
  position: -webkit-sticky;
  position: sticky;
  top: 0;


th:first-child 
  position: -webkit-sticky;
  position: sticky;
  left: 0;
  z-index: 2;
  background: #ccc;

thead th:first-child 
  z-index: 5;

【讨论】:

【参考方案8】:

要修复标题和列,您可以使用以下插件:

http://www.fixedheadertable.com/

2019 年 7 月更新

最近还出现了a pure CSS solution,它基于 CSS 属性 position: sticky;(here 了解更多详细信息)应用于每个 TH 项目(而不是它们的父容器)

【讨论】:

第一个链接已损坏。第二个使用jQuery。 更新了删除死链接的答案【参考方案9】:

我最近不得不创建一个具有固定标题组和固定第一列的解决方案。我将表拆分为 div 并使用 jquery 来捕获窗口滚动。

http://jsfiddle.net/TinT/EzXub/2346/

var prevTop = 0;
var prevLeft = 0;

$(window).scroll(function(event)
  var currentTop = $(this).scrollTop();
  var currentLeft = $(this).scrollLeft();

  if(prevLeft !== currentLeft) 
    prevLeft = currentLeft;
    $('.header').css('left': -$(this).scrollLeft())
  
  if(prevTop !== currentTop) 
    prevTop = currentTop;
    $('.leftCol').css('top': -$(this).scrollTop() + 40)
  
);

【讨论】:

【参考方案10】:

我和一位同事刚刚发布了一个新的 GitHub 项目,该项目提供了一个 Angular 指令,您可以使用它来用固定的标题装饰您的表格:https://github.com/objectcomputing/FixedHeader

它仅依赖于 css 和 angular,并带有添加一些 div 的指令。不需要 jQuery。

此实现不像其他一些实现那样功能齐全,但如果您只是需要添加固定表,我们认为这可能是一个不错的选择。

【讨论】:

【参考方案11】:

经过两天与 Internet Explorer 9 + Chrome + Firefox (Windows) 和 Safari (Mac) 的斗争,我找到了一个系统

兼容所有这些浏览器 不使用javascript 只使用一个 div 和一个表 固定页眉和页脚(IE 除外),正文可滚动。具有相同列宽的标题和正文

结果:

HTML:

  <thead>
    <tr>
      <th class="nombre"><%= f.label :cost_center %></th>
      <th class="cabecera cc">Personal</th>
      <th class="cabecera cc">Dpto</th>
    </tr>
  </thead>
  <tbody>
    <% @cost_centers.each do |cc| %>
    <tr>
      <td class="nombre"><%= cc.nombre_corto %></td>
      <td class="cc"><%= cc.cacentrocoste %></td>
      <td class="cc"><%= cc.cacentrocoste_dpto %></td>
    </tr>
    <% end %>
  </tbody>
  <tfoot>
    <tr>
      <td colspan="3"><a href="#">Mostrar mas usuarios</a></td>
    </tr>
  </tfoot>
</table>

CSS:

div.cost_center
  width:320px;
  font-size:75%;
  margin-left:5px;
  margin-top:5px;
  margin-bottom: 2px;
  float: right;
  display: inline-block;
  overflow-y: auto;
  overflow-x: hidden;
  max-height:300px;  


div.cost_center label  
  float:none;
  font-size:14px;


div.cost_center table
  width:300px;
  border-collapse: collapse; 
  float:right;
  table-layout:fixed;


div.cost_center table tr
  height:16px;

div.cost_center th
  font-weight:normal;


div.cost_center table tbody
  display: block;
  overflow: auto;
  max-height:240px;


div.cost_center table thead
  display:block;


div.cost_center table tfoot
  display:block;

div.cost_center table tfoot td
  width:280px;

div.cost_center .cc
  width:60px;
  text-align: center; 
  border: 1px solid #999;


div.cost_center .nombre
  width:150px;

div.cost_center tbody .nombre
  border: 1px solid #999;


div.cost_center table tfoot td
 text-align:center;  
 border: 1px solid #999; 
 

div.cost_center table th, 
div.cost_center table td  
  padding: 2px;
  vertical-align: middle; 


div.cost_center table tbody td 
  white-space: normal;
  font:  .8em/1.4em Verdana, sans-serif;
  color: #000;
  background-color: white;

div.cost_center table th.cabecera  
  font:  0.8em/1.4em Verdana, sans-serif;
  color: #000;
  background-color: #FFEAB5;

【讨论】:

不错的尝试,但对我来说效果不太好。在此示例 (jsfiddle.net/5ka6e) 中,标头未正确调整大小。这种错误最终可能导致数据和标头不匹配。 您忘记添加 div.cost_center tableborder-collapse: collapse; 并且第三个标题必须在 60px 以内(在本例中)【参考方案12】:

现有答案将适合大多数人,但对于那些希望在固定标题下和第一(固定)列右侧添加 阴影 的人,这里有一个工作示例(纯 css ):

http://jsbin.com/nayifepaxo/1/edit?html,output

让它工作的主要技巧是使用::after 在每个tr 中的第一个td 的右侧添加阴影:

tr td:first-child:after 
  box-shadow: 15px 0 15px -15px rgba(0, 0, 0, 0.05) inset;
  content: "";
  position:absolute;
  top:0;
  bottom:0;
  right:-15px;
  width:15px;

我花了一段时间(太长了......)才让这一切正常工作,所以我想我会分享给那些处于类似情况的人。

【讨论】:

您是根据其他人的回答来添加阴影的吗?【参考方案13】:

/* Use overflow:scroll on your container to enable scrolling: */

div 
  max-width: 400px;
  max-height: 150px;
  overflow: scroll;



/* Use position: sticky to have it stick to the edge
 * and top, right, or left to choose which edge to stick to: */

thead th 
  position: -webkit-sticky; /* for Safari */
  position: sticky;
  top: 0;


tbody th 
  position: -webkit-sticky; /* for Safari */
  position: sticky;
  left: 0;



/* To have the header in the first column stick to the left: */

thead th:first-child 
  left: 0;
  z-index: 1;



/* Just to display it nicely: */

thead th 
  background: #000;
  color: #FFF;


tbody th 
  background: #FFF;
  border-right: 1px solid #CCC;


table 
  border-collapse: collapse;


td,
th 
  padding: 0.5em;
<div>
  <table>
    <thead>
      <tr>
        <th></th>
        <th>headheadhead</th>
        <th>headheadhead</th>
        <th>headheadhead</th>
        <th>headheadhead</th>
        <th>headheadhead</th>
        <th>headheadhead</th>
        <th>headheadhead</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <th>head</th>
        <td>body</td>
        <td>body</td>
        <td>body</td>
        <td>body</td>
        <td>body</td>
        <td>body</td>
        <td>body</td>
      </tr>
      <tr>
        <th>head</th>
        <td>body</td>
        <td>body</td>
        <td>body</td>
        <td>body</td>
        <td>body</td>
        <td>body</td>
        <td>body</td>
      </tr>
      <tr>
        <th>head</th>
        <td>body</td>
        <td>body</td>
        <td>body</td>
        <td>body</td>
        <td>body</td>
        <td>body</td>
        <td>body</td>
      </tr>
      <tr>
        <th>head</th>
        <td>body</td>
        <td>body</td>
        <td>body</td>
        <td>body</td>
        <td>body</td>
        <td>body</td>
        <td>body</td>
      </tr>
      <tr>
        <th>head</th>
        <td>body</td>
        <td>body</td>
        <td>body</td>
        <td>body</td>
        <td>body</td>
        <td>body</td>
        <td>body</td>
      </tr>
      <tr>
        <th>head</th>
        <td>body</td>
        <td>body</td>
        <td>body</td>
        <td>body</td>
        <td>body</td>
        <td>body</td>
        <td>body</td>
      </tr>
    </tbody>
  </table>
</div>

需要修复页眉页脚

【讨论】:

【参考方案14】:

这样的事情可能对您有用...它可能需要您为标题行设置列宽。

thead  
    position: fixed;

http://jsfiddle.net/vkhNC/

更新:

我不相信您给出的示例仅使用 CSS 是可行的。我希望有人能证明我错了。 Here is what I have so far。它不是成品,但它可能是您的开始。我希望这能为您指明一个有用的方向,无论它在哪里。

【讨论】:

我不仅需要标题,还需要固定第一列。 问题是标题松散了它们的宽度。不同的标题列大小和数据列大小看起来很难看。【参考方案15】:

另一个解决方案是使用 AngularJS。 AngularUI 模块有一个名为ng-grid 的指令,它支持一种称为列固定的功能。它不是 100% 纯 CSS,但也不是其他解决方案。

http://angular-ui.github.io/ng-grid/#columnPinning

【讨论】:

【参考方案16】:

纯 CSS 示例:

<div id="cntnr">
    <div class="tableHeader">
        <table class="table-header table table-striped table-bordered">
            <thead>
                <tr>
                    <th>this</th>
                    <th>transmission</th>
                    <th>is</th>
                    <th>coming</th>
                    <th>to</th>
                    <th>you</th>
                </tr>
            </thead>
            <tbody>
                <tr>
                    <td>we've got it...</td>
                    <td>alright you are go</td>
                    <td>uh, we see the Earth now</td>
                    <td>we've got it...</td>
                    <td>alright you are go</td>
                    <td>uh, we see the Earth now</td>
                </tr>
            </tbody>
        </table>
    </div>


    <div class="tableBody">
        <table class="table-body table table-striped table-bordered">
            <thead>
                <tr>
                    <th>this</th>
                    <th>transmission</th>
                    <th>is</th>
                    <th>coming</th>
                    <th>to</th>
                    <th>you</th>
                </tr>
            </thead>
            <tbody>
                <tr>
                    <td>we've got it...</td>
                    <td>alright you are go</td>
                    <td>uh, we see the Earth now</td>
                    <td>we've got it...</td>
                    <td>alright you are go</td>
                    <td>uh, we see the Earth now</td>
                </tr>
            </tbody>
        </table>
    </div>

</div>

#cntnr 
    width: auto;
    height: 200px;
    border: solid 1px #444;
    overflow: auto;


.tableHeader 
    position: fixed;
    height: 40px;
    overflow: hidden;
    margin-right: 18px;
    background: white;


.table-header tbody 
    height: 0;
    visibility: hidden;


.table-body thead 
    height: 0;
    visibility: hidden;

http://jsfiddle.net/cCarlson/L98m854d/

缺点:固定的标题结构/逻辑相当依赖于特定维度,因此抽象可能不是一个可行的选择

【讨论】:

需要固定的标题和固定的第一列。 啊...谢谢你指出这一点,panfil。我会进行编辑。干杯【参考方案17】:

Position : sticky 不适用于 chrome 中的 (thead) 和其他 webkit 浏览器(如 safari)中的某些元素。

但它适用于 (th)

body 
  background-color: rgba(0, 255, 200, 0.1);


.intro 
  color: rgb(228, 23, 23);


.wrapper 
  overflow-y: scroll;
  height: 300px;


.sticky 
  position: sticky;
  top: 0;
  color: black;
  background-color: white;
<div class="container intro">
  <h1>Sticky Table Header</h1>
  <p>Postion : sticky doesn't work for some elements like (thead) in chrome and other webkit browsers like safari. </p>
  <p>But it works fine with (th)</p>
</div>
<div class="container wrapper">
  <table class="table table-striped">
    <thead>
      <tr>
        <th class="sticky">Firstname</th>
        <th class="sticky">Lastname</th>
        <th class="sticky">Email</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>James</td>
        <td>Vince</td>
        <td>james@example.com</td>
      </tr>
      <tr>
        <td>Jonny</td>
        <td>Bairstow</td>
        <td>jonny@example.com</td>
      </tr>
      <tr>
        <td>James</td>
        <td>Anderson</td>
        <td>james@example.com</td>
      </tr>
      <tr>
        <td>Stuart</td>
        <td>Broad</td>
        <td>stuart@example.com</td>
      </tr>
      <tr>
        <td>Eoin</td>
        <td>Morgan</td>
        <td>eoin@example.com</td>
      </tr>
      <tr>
        <td>Joe</td>
        <td>Root</td>
        <td>joe@example.com</td>
      </tr>
      <tr>
        <td>Chris</td>
        <td>Woakes</td>
        <td>chris@example.com</td>
      </tr>
      <tr>
        <td>Liam</td>
        <td>PLunkett</td>
        <td>liam@example.com</td>
      </tr>
      <tr>
        <td>Jason</td>
        <td>Roy</td>
        <td>jason@example.com</td>
      </tr>
      <tr>
        <td>Alex</td>
        <td>Hales</td>
        <td>alex@example.com</td>
      </tr>
      <tr>
        <td>Jos</td>
        <td>Buttler</td>
        <td>jos@example.com</td>
      </tr>
      <tr>
        <td>Ben</td>
        <td>Stokes</td>
        <td>ben@example.com</td>
      </tr>
      <tr>
        <td>Jofra</td>
        <td>Archer</td>
        <td>jofra@example.com</td>
      </tr>
      <tr>
        <td>Mitchell</td>
        <td>Starc</td>
        <td>mitchell@example.com</td>
      </tr>
      <tr>
        <td>Aaron</td>
        <td>Finch</td>
        <td>aaron@example.com</td>
      </tr>
      <tr>
        <td>David</td>
        <td>Warner</td>
        <td>david@example.com</td>
      </tr>
      <tr>
        <td>Steve</td>
        <td>Smith</td>
        <td>steve@example.com</td>
      </tr>
      <tr>
        <td>Glenn</td>
        <td>Maxwell</td>
        <td>glenn@example.com</td>
      </tr>
      <tr>
        <td>Marcus</td>
        <td>Stoinis</td>
        <td>marcus@example.com</td>
      </tr>
      <tr>
        <td>Alex</td>
        <td>Carey</td>
        <td>alex@example.com</td>
      </tr>
      <tr>
        <td>Nathan</td>
        <td>Coulter Nile</td>
        <td>nathan@example.com</td>
      </tr>
      <tr>
        <td>Pat</td>
        <td>Cummins</td>
        <td>pat@example.com</td>
      </tr>
      <tr>
        <td>Adam</td>
        <td>Zampa</td>
        <td>zampa@example.com</td>
      </tr>
    </tbody>
  </table>
</div>

或visit my codepen example:

【讨论】:

【参考方案18】:

这是我刚刚根据此处的答案使用 css 网格构建的另一个解决方案:

https://codesandbox.io/s/sweet-resonance-m733i

【讨论】:

【参考方案19】:

这是我在有点困惑后刚刚提出的解决方案。似乎需要设置一些 z-index 属性才能使其正常工作,我的解决方案并非完美无缺,但它适用于我的应用程序:

CSS(在 SCSS 中)的关键是首先设置非粘性元素的属性以建立 z-index 属性。

.wrapper 
position: relative;
white-space: nowrap;
overflow: auto;
height: 200px;
table 
    border-collapse: collapse;
    tbody 
        tr 
            td 
                padding: .5em .75em;
                box-shadow: inset 0px -1px 0px 0px #000000;
                position: relative;
                z-index: -9999;
                background: white;
                &:first-of-type 
                    position: -webkit-sticky;
                    position: sticky;
                    left: 0px;
                    background: #eee;
                    z-index: -999;
                    box-shadow: inset -1px -1px 0px 0px #000000;
                
            
            &:first-of-type 
                position: sticky;
                top: 0;
                td 
                    background: #eee; 
                    &:first-of-type 
                        left: 0;
                        top: 0;
                        background: #eee;
                        z-index: 999;
                    
                
            
            &:nth-of-type(2) 
                position: sticky;
                top: calc(1em + 1em + 2px);
                background: white;
                td:first-of-type 
                    position: sticky;
                    left: 0;
                    z-index: 998;
                
            
        
    

https://codepen.io/the_Northway/pen/VwMmwXG

【讨论】:

【参考方案20】:

我认为这会对您有所帮助: https://datatables.net/release-datatables/extensions/FixedHeader/examples/header_footer.html

简而言之,如果你知道如何创建一个数据表,你只需要在你的底部添加这个 jQuery 行:

$(document).ready(function() 
    var table = $('#example').DataTable();

    new $.fn.dataTable.FixedHeader( table, 
        bottom: true
     );
 );

bottom: true // 用于固定底部标题。

【讨论】:

【参考方案21】:

如果您只想使用纯 HTML 和 CSS,我已经为您的问题提供了解决方案: 在这个jsFiddle 中,您可以看到一个非脚本解决方案,它提供了一个带有固定标题的表格。 为固定的第一列调整标记也应该不是问题。 您只需要为hWrapper-div 内的第一列创建一个绝对定位表,然后重新定位vWrapper-div。 使用服务器端或浏览器端的诱人引擎提供动态内容应该不是问题,我的解决方案适用于所有现代浏览器和 IE8 以后的旧浏览器。

【讨论】:

【参考方案22】:

只需要将样式改为

<table style="position: relative;">
   <thead>
      <thead>
        <tr>
           <th></th>
        </tr>
      </thead>
   </thead>
   <tbody style="position: absolute;height: 300px;overflow:auto;">
      <tr>
         <td></td>
      </tr>
   </tbody>
</table>

演示:https://plnkr.co/edit/Qxy5RMJBXmkaJAOjBtQn?p=preview

【讨论】:

在您的演示中,第一列不固定

具有动态列的表布局固定和整行 colspan

】具有动态列的表布局固定和整行colspan【英文标题】:Table-layoutfixedandfullrowcolspanwithdynamiccolumns【发布时间】:2017-07-0900:11:12【问题描述】:我试图设置表格列的宽度,但我注意到当它在FF中工作时,它在Chrome/Edge中被完全忽略。... 查看详情

使用 datatable.js 具有固定标题和固定列的数据表

】使用datatable.js具有固定标题和固定列的数据表【英文标题】:Datatablewithfixedheaderandfixedcolumnsusingdatatable.js【发布时间】:2018-09-1111:19:34【问题描述】:我需要一个启用datatable的表,该表具有使用主浏览器滚动条滚动固定页眉/页... 查看详情

具有固定列和流动列的 CSS 布局

】具有固定列和流动列的CSS布局【英文标题】:CSSlayoutwithfixedandliquidcolumns【发布时间】:2012-05-0113:52:09【问题描述】:我在创建部分流动的布局时遇到问题。布局必须具有100%的宽度和高度,但不应有滚动条(溢出:隐藏;)。... 查看详情

使用元素ui删除具有固定列的表中的垂直线[关闭]

】使用元素ui删除具有固定列的表中的垂直线[关闭]【英文标题】:Removeverticallineintablewithfixedcolumnusingelementui[closed]【发布时间】:2020-12-2512:14:31【问题描述】:#问我使用element-ui。visit并在表数据中使用固定列。并且在元素ui上具... 查看详情

具有固定标题和固定第一列的动态 HTML 表

】具有固定标题和固定第一列的动态HTML表【英文标题】:DynamicHTMLTablewithFixedHeaderandFixedFirstcolumn【发布时间】:2014-02-2208:00:37【问题描述】:我正在动态创建一个html表格并填写其内容。之后,我将完整的HTML添加到我的aspx页面上... 查看详情

html具有固定行和列的表(代码片段)

查看详情

具有固定列和标题的可滚动表格,带有现代 CSS

】具有固定列和标题的可滚动表格,带有现代CSS【英文标题】:Scrollabletablewithfixedcolumnsandheader,withmodernCSS【发布时间】:2018-02-2618:28:58【问题描述】:如何使用现代CSS制作尽可能少的JavaScript表格?我想要的功能是:固定列(定... 查看详情

在 Chrome 浏览器中具有固定列的 DataTable 显示标题和正文之间的空间

】在Chrome浏览器中具有固定列的DataTable显示标题和正文之间的空间【英文标题】:DataTablewithFixedColumninChromebrowserit\'sshowingspacebetweenHeaderandBody【发布时间】:2020-02-0109:25:52【问题描述】:当使用固定列和/或延迟加载动态加载数据... 查看详情

CSS - tr上的固定高度和桌子上的固定高度?

...le?【发布时间】:2016-05-0120:00:54【问题描述】:我需要有具有固定高度行的表格,并且该表格本身必须具有固定高度。例如,所有行的高度为8像素,表格的高度为400像素。如果行数少于表格的总高度,那么表格的剩余部分应该... 查看详情

具有流体左列和固定右列的两列 div 布局

】具有流体左列和固定右列的两列div布局【英文标题】:Twocolumndivlayoutwithfluidleftandfixedrightcolumn【发布时间】:2011-08-0411:55:36【问题描述】:我想使用DIV进行两列布局,其中右列将具有200像素的固定宽度,而左列将占据剩余的所... 查看详情

具有固定列宽和最大高度的 CSS 表格

】具有固定列宽和最大高度的CSS表格【英文标题】:CSStablewithfixedcolumnwidthsandmaxheight【发布时间】:2019-07-3118:16:25【问题描述】:我正在尝试创建一个具有固定列宽和固定最大高度的表格,它会滚动到最大高度之外。阅读后,我... 查看详情

具有固定页眉和页脚以及没有固定宽度的可滚动正文的 HTML 表格

】具有固定页眉和页脚以及没有固定宽度的可滚动正文的HTML表格【英文标题】:HTMLtablewithfixedheaderandfooterandscrollablebodywithoutfixedwidths【发布时间】:2016-09-1307:54:56【问题描述】:我想创建一个带有固定thead和tfoot以及可滚动tbody的... 查看详情

具有固定列表的固定标题不根据宽度响应

】具有固定列表的固定标题不根据宽度响应【英文标题】:Fixedheaderwithfixedcolumntableisnotresponsiveaccordingtowidth【发布时间】:2019-07-0621:56:15【问题描述】:我制作了一个带有固定标题和列的表格。但是在这里我已经指定了我不想要... 查看详情

具有固定增量的列的 R 回归

】具有固定增量的列的R回归【英文标题】:Rregressionovercolumnswithfixeddeltas【发布时间】:2015-01-1709:29:11【问题描述】:我在Rdf中有一个数据框,其中每一行X是一个主题(N=100),每一列S是两年内每个月完成一项任务的每个主题的... 查看详情

具有多个固定行和列的 HTML 表格

】具有多个固定行和列的HTML表格【英文标题】:HTMLtablewithmultiplefixedrowsandcolumns【发布时间】:2019-04-0423:45:16【问题描述】:我有一张这样的桌子:现在,实际上,将有超过100行和/或列。自然,在这样的表格中,有人可能会忘记... 查看详情

具有多列的单个固定表与灵活的抽象表

】具有多列的单个固定表与灵活的抽象表【英文标题】:singlefixedtablewithmultiplecolumnsvsflexibleabstracttables【发布时间】:2011-04-3001:03:03【问题描述】:我想知道您是否有一个网站,其中包含需要不同字段的十几种不同类型的列表(... 查看详情

Kivy 网格布局固定了某些列的列宽

...:05:20【问题描述】:我想构建一个网格布局,其中某些列具有固定宽度(以包含图像),而其他列应占用可用空间。这是我目前的情况(最后一栏):正如您在蓝色背景上看到的那样,列对于图像来说太大了。但是,由于有更多... 查看详情

如何在 Flutter 中创建具有固定列的水平滚动表格?

】如何在Flutter中创建具有固定列的水平滚动表格?【英文标题】:HowtocreateahorizontallyscrollingtablewithfixedcolumninFlutter?【发布时间】:2019-11-1809:44:10【问题描述】:我想创建一系列可以垂直滚动的表格,每个表格的行数/列数可能不... 查看详情