【问题标题】:Table with fixed header and fixed column on pure css在纯 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 行为应用于行和单元格,但我不太明白它在哪里适用。
  • 这个答案可能对你有帮助stackoverflow.com/questions/14834198/…

标签: html css html-table markup fixed-header-tables


【解决方案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 值等于第一列的widthjsfiddle.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】:

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


    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 table{border-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

                      【讨论】:

                      • 在您的演示中,第一列不固定
                      猜你喜欢
                      相关资源
                      最近更新 更多
                      热门标签