table 中的粘性行和列 header

Sticky row and column header in table

我正在尝试设计具有粘性 thead 和粘性行 header 的 table。所以,基本上,所有 th 元素都必须是粘性的。

我偶然发现了 position: sticky css3 属性,它似乎很适合这项工作,尽管许多浏览器尚不支持它(这对我来说不是问题) .但是 MDN 文档说:

The effect of ‘position: sticky’ on table elements is the same as for ‘position: relative’.

考虑到这一点,我构建了一个可在 Safari 10.0 中运行的基本示例,即使粘性元素的边框未保留。

在 firefox 50.0 中,边框不显示,但 header 不粘。

所以,我的问题是:如何通过使用 position: sticky 来干净地实现这个固定的 header 定位。似乎实施(实施时)不完整,tables 得到的支持更少。

如果不可能,我也愿意接受 JavaScript 中实现此目的的解决方案(但将 jQuery 添加到我的堆栈会非常麻烦,因为我的整个应用程序都在响应中)。

这是我目前拥有的代码片段。请注意,为了获得一些粘性 header,您基本上需要 Safari 或 chrome 的 alpha 版本。

div#container {
  height: 200px;
  width: 300px;
  overflow: auto;
}

table {
  border-collapse: collapse;
}

tbody th {
  position: -webkit-sticky;
  position: sticky;
  left: 0px;
}

thead {
  position: -webkit-sticky;
  position: sticky;
  top: 0px;
}

th {
  background: #B8C1C8;
  border: 2px solid black;
}
<div id="container">
  <table>
    <thead>
      <tr>
        <th>hehe</th>
        <th>hello</th>
        <th>world</th>
        <th>hello</th>
        <th>world</th>
        <th>hello</th>
        <th>world</th>
        <th>hello</th>
        <th>world</th>
        <th>hello</th>
        <th>world</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <th>I'm a super long header</th>
        <td>hello</td>
        <td>world</td>
        <td>hello</td>
        <td>world</td>
        <td>hello</td>
        <td>world</td>
        <td>hello</td>
        <td>world</td>
        <td>hello</td>
        <td>world</td>
      </tr>
      <tr>
        <th>I'm a super long header</th>
        <td>hello</td>
        <td>world</td>
        <td>hello</td>
        <td>world</td>
        <td>hello</td>
        <td>world</td>
        <td>hello</td>
        <td>world</td>
        <td>hello</td>
        <td>world</td>
      </tr>
      <tr>
        <th>I'm a super long header</th>
        <td>hello</td>
        <td>world</td>
        <td>hello</td>
        <td>world</td>
        <td>hello</td>
        <td>world</td>
        <td>hello</td>
        <td>world</td>
        <td>hello</td>
        <td>world</td>
      </tr>
      <tr>
        <th>I'm a super long header</th>
        <td>hello</td>
        <td>world</td>
        <td>hello</td>
        <td>world</td>
        <td>hello</td>
        <td>world</td>
        <td>hello</td>
        <td>world</td>
        <td>hello</td>
        <td>world</td>
      </tr>
    </tbody>
  </table>
</div>

我试过的资源:

似乎喜欢你那里应有尽有。它也被称为冻结窗格效果。微调版本:

Forkable Codepen sample

更新:更好的边框。

* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

table {
  border-collapse: collapse;
  height: 20em;
  overflow: scroll;
  width: 50vw;
}

thead {
  background-color: #eee;
  color: gray;
  left: 0;
  position: -webkit-sticky;
  position: sticky;
  top: 0;
  z-index: 1;
}
thead th {
  background-color: #ddd;
}
thead th,
thead td {
  box-shadow: 0 0 0 1px #ccc;
}

tr {
  border-bottom: thin solid #ddd;
  width: 100%;
}

th,
td {
  min-width: 20em;
  padding: 0.5em;
}

th {
  background-color: #eee;
  box-shadow: 1px 0 0 0 #ccc;
  left: 0;
  min-width: 5em;
  position: -webkit-sticky;
  position: sticky;
}
<table>
  <thead>
    <tr>
      <th></th>
      <td>
        A
      </td>
      <td>
        B
      </td>
      <td>
        C
      </td>
      <td>
        D
      </td>
    </tr>
  </thead>
  <tbody></tbody>
  <tr>
    <th>
      1
    </th>
    <td>
      A 1
    </td>
    <td>
      B 1
    </td>
    <td>
      C 1
    </td>
    <td>
      D 1
    </td>
  </tr>
  <tr>
    <th>
      2
    </th>
    <td>
      A 2
    </td>
    <td>
      B 2
    </td>
    <td>
      C 2
    </td>
    <td>
      D 2
    </td>
  </tr>
  <tr>
    <th>
      3
    </th>
    <td>
      A 3
    </td>
    <td>
      B 3
    </td>
    <td>
      C 3
    </td>
    <td>
      D 3
    </td>
  </tr>
  <tr>
    <th>
      4
    </th>
    <td>
      A 4
    </td>
    <td>
      B 4
    </td>
    <td>
      C 4
    </td>
    <td>
      D 4
    </td>
  </tr>
  <tr>
    <th>
      5
    </th>
    <td>
      A 5
    </td>
    <td>
      B 5
    </td>
    <td>
      C 5
    </td>
    <td>
      D 5
    </td>
  </tr>
  <tr>
    <th>
      6
    </th>
    <td>
      A 6
    </td>
    <td>
      B 6
    </td>
    <td>
      C 6
    </td>
    <td>
      D 6
    </td>
  </tr>
  <tr>
    <th>
      7
    </th>
    <td>
      A 7
    </td>
    <td>
      B 7
    </td>
    <td>
      C 7
    </td>
    <td>
      D 7
    </td>
  </tr>
  <tr>
    <th>
      8
    </th>
    <td>
      A 8
    </td>
    <td>
      B 8
    </td>
    <td>
      C 8
    </td>
    <td>
      D 8
    </td>
  </tr>
  <tr>
    <th>
      9
    </th>
    <td>
      A 9
    </td>
    <td>
      B 9
    </td>
    <td>
      C 9
    </td>
    <td>
      D 9
    </td>
  </tr>
  <tr>
    <th>
      10
    </th>
    <td>
      A 10
    </td>
    <td>
      B 10
    </td>
    <td>
      C 10
    </td>
    <td>
      D 10
    </td>
  </tr>
  <tr>
    <th>
      11
    </th>
    <td>
      A 11
    </td>
    <td>
      B 11
    </td>
    <td>
      C 11
    </td>
    <td>
      D 11
    </td>
  </tr>
  <tr>
    <th>
      12
    </th>
    <td>
      A 12
    </td>
    <td>
      B 12
    </td>
    <td>
      C 12
    </td>
    <td>
      D 12
    </td>
  </tr>
  <tr>
    <th>
      13
    </th>
    <td>
      A 13
    </td>
    <td>
      B 13
    </td>
    <td>
      C 13
    </td>
    <td>
      D 13
    </td>
  </tr>
  <tr>
    <th>
      14
    </th>
    <td>
      A 14
    </td>
    <td>
      B 14
    </td>
    <td>
      C 14
    </td>
    <td>
      D 14
    </td>
  </tr>
  <tr>
    <th>
      15
    </th>
    <td>
      A 15
    </td>
    <td>
      B 15
    </td>
    <td>
      C 15
    </td>
    <td>
      D 15
    </td>
  </tr>
  <tr>
    <th>
      16
    </th>
    <td>
      A 16
    </td>
    <td>
      B 16
    </td>
    <td>
      C 16
    </td>
    <td>
      D 16
    </td>
  </tr>
  <tr>
    <th>
      17
    </th>
    <td>
      A 17
    </td>
    <td>
      B 17
    </td>
    <td>
      C 17
    </td>
    <td>
      D 17
    </td>
  </tr>
  <tr>
    <th>
      18
    </th>
    <td>
      A 18
    </td>
    <td>
      B 18
    </td>
    <td>
      C 18
    </td>
    <td>
      D 18
    </td>
  </tr>
  <tr>
    <th>
      19
    </th>
    <td>
      A 19
    </td>
    <td>
      B 19
    </td>
    <td>
      C 19
    </td>
    <td>
      D 19
    </td>
  </tr>
  <tr>
    <th>
      20
    </th>
    <td>
      A 20
    </td>
    <td>
      B 20
    </td>
    <td>
      C 20
    </td>
    <td>
      D 20
    </td>
  </tr>
</table>