thead上的position: sticky属性

62

您可能已经知道,position: sticky;已经在Webkit中实现(演示)。 到目前为止,我所看到的是它只在父元素内起作用。但我想知道是否可以在带有表格的滚动

中使用这个属性。

因此,它需要在

的滚动事件上“监听”,而不是在上。

我知道我可以使用JavaScript和绝对定位来实现这一点,但我想知道sticky-positioning是否支持此功能。

6个回答

124

在2018年,thead th上的position sticky可行!

只需在样式表中添加这一行:

thead th { position: sticky; top: 0; }

为了使样式生效,您的表格需要包括theadth

<table>
    <thead>
        <tr>
            <th>column 1</th>
            <th>column 2</th>
            <th>column 3</th>
            <th>column 4</th>            
        </tr>    
    </thead>
    <tbody>
      // your body code
    </tbody>
</table>

另外,如果在 thead 中有多行数据,你可以选择第一行来保持粘性:

thead tr:first-child th { position: sticky; top: 0; }

截至2018年3月,现代浏览器基本上都支持这个功能。 参考:https://caniuse.com/#feat=css-sticky 感谢@ctf0提供的信息(参考于2017年12月3日的评论)。

10
由于这个bug(https://bugs.chromium.org/p/chromium/issues/detail?id=702927),导致`thead { position: sticky }`无法按预期工作。 - flying sheep
12
如果<thead>中有多行<th>,它能正常工作吗? - SantoshK
3
很棒的答案。诀窍在于位置必须放在th元素上,父元素不能有溢出:隐藏。 - Gustavo Gonçalves
3
重要提示:在此需要补充的是,Firefox 能够将整个 THEAD 固定,即使它有多个 TRs。而 Chrome 不能。您必须逐个固定所有单元格,并将第一行单元格设为 top:0,后续行分别设为 top:20pxtop:40px 等。这会极大地降低开发体验。 - aross
1
默认情况下,父元素将需要溢出设置为 overflow:visible。对于父元素的 hiddenauto 属性,Sticky无效的 - Nux
显示剩余3条评论

14
如果您需要 Chrome 浏览器中的粘性标头,则可以在 thead 元素内为 td 元素设置 position: sticky; top: some_valuetop 属性是必需的)。
请参见:
<table border=1>
  <thead>
    <tr>
      <td style='position: sticky; top: -1px;background: red'>Sticky Column</td>
      <td>Simple column</td>
    </tr>
  </thead>

固定表头的表格


4
对我来说,解决方案是 thead th {position: sticky; top: 0;} - ctf0
在我看来,这是更好的答案。仅使用 position: sticky 对我无效。添加 top 规则完美地解决了问题! - Suhas
2
太好了...寻找已久...这对Chrome浏览器很有帮助...同时,您需要正确设置背景颜色和文本颜色以匹配...可能会对某些人有所帮助。 - nikudale
1
@FilipeEsperandio 这是Chrome/FF中的一个错误,奇怪的是在Chrome的跟踪器中已经标记为已解决。这是令人沮丧的事情之一,Edge做得正确的少之又少。 - Dan

10

position: sticky在表格元素上不起作用(只要它们的display属性以table-开头),因为表格不属于规范的一部分:

其他类型的布局,例如表格、"浮动"框、Ruby注释、网格布局、列和正常"流"内容的基本处理,在其他模块中描述。


编辑:截至2019年7月,根据https://caniuse.com/#feat=css-sticky,Firefox支持此功能,Chrome至少支持<th>标签。


2
不太确定。Mozilla 显然正在努力推出这个:https://bugzilla.mozilla.org/show_bug.cgi?id=975644 - retrovertigo
1
@retrovertigo,现在已经修复了。 - Qwertie
@Qwertie 谢谢你的更新 :) "在 Firefox 59 中已验证修复" - retrovertigo
2018年,thead的position: sticky属性已经可用,详见下方更新的答案:https://dev59.com/TGct5IYBdhLWcg3wNqwg#49270067 - Evolve
2019年7月的修正:Firefox在MacOS上支持thead元素上的position: sticky。根据我的测试,Windows上的Firefox 69会彻底搞砸它,忽略背景颜色,但不忽略文本颜色(导致标题完全无法阅读),并在滚动时随机使元素出现和消失。 Webkit目前不支持thead的这种方式,将其视为position: static(或相对位置-不确定差异是否真正有意义)。 - Janus Bahs Jacquet

3
设置 thead 的 position:sticky 属性就足够了,不需要为 th 设置它:
table.StickyHeader thead {
    position: sticky;
    top: 0px;
}

测试通过:

Edge 105.0.1343.42, Firefox 105.0, Chrome 105.0.5195.127, Opera 91.0.4516.16

但是,当 thead 的位置设置为 sticky 且 th 具有背景颜色时,Firefox 无法呈现 th 的边框:

table.StickyHeader th {
    border: 1px solid black;
    padding: 5px;
    background-color: gold;
    text-align: center;
}

Firefox

Edge, Chrome, Opera

该内容与编程有关。

到目前为止,这是最简单的解决方案。同时,对于我来说也是唯一一个在考虑到表格的复杂样式设置时有效的解决方案。 - Darya Balu

3

事实证明,position: sticky 只能在窗口中使用,而不能在滚动的 div 中使用。

我创建了一个带有表头的非常长的表格的测试案例

h1 {
  font-size: 18px;
  font-weight: bold;
  margin: 10px 0;
}

div.testTable {
  height: 200px;
  overflow: auto;
}

table.stickyHead thead {
  position: -webkit-sticky;
  top: 0px;
  background: grey;
}

table.stickyHead td,
table.stickyHead th {
  padding: 2px 3px;
}
<h1>Position sticky</h1>
<div class="testTable">
  <table class="stickyHead">
    <thead>
      <tr>
        <th>column 1</th>
        <th>column 2</th>
        <th>column 3</th>
        <th>column 4</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>1</td>
        <td>2</td>
        <td>3</td>
        <td>4</td>
      </tr>
      <tr>
        <td>1</td>
        <td>2</td>
        <td>3</td>
        <td>4</td>
      </tr>
      <tr>
        <td>1</td>
        <td>2</td>
        <td>3</td>
        <td>4</td>
      </tr>
      <tr>
        <td>1</td>
        <td>2</td>
        <td>3</td>
        <td>4</td>
      </tr>
      <tr>
        <td>1</td>
        <td>2</td>
        <td>3</td>
        <td>4</td>
      </tr>
      <tr>
        <td>1</td>
        <td>2</td>
        <td>3</td>
        <td>4</td>
      </tr>
      <tr>
        <td>1</td>
        <td>2</td>
        <td>3</td>
        <td>4</td>
      </tr>
      <tr>
        <td>1</td>
        <td>2</td>
        <td>3</td>
        <td>4</td>
      </tr>
      <tr>
        <td>1</td>
        <td>2</td>
        <td>3</td>
        <td>4</td>
      </tr>
      <tr>
        <td>1</td>
        <td>2</td>
        <td>3</td>
        <td>4</td>
      </tr>
      <tr>
        <td>1</td>
        <td>2</td>
        <td>3</td>
        <td>4</td>
      </tr>
      <tr>
        <td>1</td>
        <td>2</td>
        <td>3</td>
        <td>4</td>
      </tr>
      <tr>
        <td>1</td>
        <td>2</td>
        <td>3</td>
        <td>4</td>
      </tr>
      <tr>
        <td>1</td>
        <td>2</td>
        <td>3</td>
        <td>4</td>
      </tr>
      <tr>
        <td>1</td>
        <td>2</td>
        <td>3</td>
        <td>4</td>
      </tr>
      <tr>
        <td>1</td>
        <td>2</td>
        <td>3</td>
        <td>4</td>
      </tr>
      <tr>
        <td>1</td>
        <td>2</td>
        <td>3</td>
        <td>4</td>
      </tr>
    </tbody>
  </table>
</div>

如您所见,如果从包装器中移除溢出并使窗口不那么高,表头将粘在窗口顶部。即使您为包装的 div 设置了 position: relative,也不适用于它。


2
测试用例在Firefox和Chrome中均无法工作(Blink可能已删除了对position:sticky的支持)。当前支持情况请参见http://caniuse.com/#feat=css-sticky。 - czerny
它在Bugzilla中有一个错误:https://bugzilla.mozilla.org/show_bug.cgi?id=975644 - retrovertigo
4
这不正确(或已不再正确)。我运行了你的测试,并只做了两个更改就使粘性标题正常工作:我将-webkit-前缀从位置中删除,并将位置设置在th上,而不是thead上:http://jsfiddle.net/xNsaM/128/ 。很好地解决了问题。 - Conor Mancone
1
现在看起来它只能在Firefox上运行,但是如果设置overflow-x为auto,则无法正常工作。 - Fuseteam

0

注意:

position:sticky在2019年已经不能在Google Chrome中使用,建议改用fixeddisplay:inline-block


3
从之前的答案中得知,请注意使用sticky: 这在Chrome v35到v51上不起作用,但是在启用实验性Web平台功能标志的情况下,Chrome 52会重新启用此功能。从Chrome 56开始,position:sticky可以直接使用。 - lucasvm1980

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接