Sticky row and column header in table

百般思念 提交于 2020-07-09 04:17:06

问题


I am trying to design a table that has a sticky thead and also sticky row headers. So, basically, all th elements must be sticky.

I have stumbled across the position: sticky css3 attribute that seems to be a great candidate for the job, even though it's not yet supported in many browsers (which is not an issue to me). However the MDN documentation says:

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

Getting this into consideration, I have built a basic example that works in Safari 10.0, even though the borders of the sticky elements are not conserved.

In firefox 50.0, the borders get don't get displayed but the headers are not sticky.

So, my question is: how can I cleanly achieve this fixed header positioning by using position: sticky. It seems like the implementation (when implemented) is not complete and tables are even less supported.

If it's not possible, I am also open to a solution in JavaScript that achieves this (but adding jQuery to my stack would be quite cumbersome since my whole app is in react).

Here is a code snippet of what I have for now. Please note that in order to have some sticky headers, you basically need safari or the alpha version of chrome.

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>

Resources I have tried:

  • a great article from typanus
  • Position sticky on thead that gave me a good lead on some clean usage of position: sticky
  • the position: sticky spec

回答1:


Seems likes you have everything there. It's also called as freezed panes effect. A bit tuned version:

Forkable Codepen sample

Update: better borders.

* {
  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>


来源:https://stackoverflow.com/questions/40760241/sticky-row-and-column-header-in-table

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!