position: sticky不能直接作用于thead,因其display为table-header-group不被支持;必须作用于th,且需同时满足滚动容器(max-h-96+overflow-y-auto)、背景色、z-index三条件。

position: sticky 能固定表头,但不是加了就动——它只在满足滚动上下文、层级和背景三个硬条件时才生效。
为什么 thead 上写 position: sticky 没反应
根本原因:thead 的 display 是 table-header-group,不支持 sticky 定位。浏览器只对 th 或 td 这类“可定位单元格”生效。
- 错误写法:
<thead style="position: sticky; top: 0"> —— 完全无效 <li>正确写法:把 <code>position: sticky; top: 0加到每个<th> 上 <li>Firefox v90 及更早版本对 <code>th上的sticky支持不稳定,v91+ 才推荐直接用 - iOS Safari 需额外加
width(如width: 20%)或transform: translateZ(0),否则计算错位 -
background-color必须显式设置(如#fff),不能是transparent或未声明,否则滚动时文字被下方td内容透出 -
z-index至少为10(推荐10起步),尤其当表格在 Modal、Tooltip 等层叠环境中时必须显式设值 - 建议加
border-bottom: 1px solid #ddd,否则表头和第一行数据之间容易视觉断裂 - 若用了
border-collapse: collapse,th需额外加background-clip: padding-box防止边框裁剪异常 - 给
<table> 加 <code>table-layout: fixed,强制按第一行(即<thead>)定义列宽 <li>所有 <code><th> 和对应 <code><td> 必须显式设 <code>width或min-width(如width: 120px或width: 20%) - 不要依赖内容撑开宽度——
table-layout: auto下 sticky 定位基准会漂移 - 列数多且需响应式时,用
<col>标签统一声明宽度比重复写width更稳定 - 把
<thead> 提到表格外,单独包裹成固定高度的 <code><div> <li><code><tbody> 套进另一个带 <code>max-height: 400px; overflow-y: auto的<div> <li>用 JS 监听 <code>resize和首次渲染,读取第一行<td> 的 <code>getBoundingClientRect().width,再赋给对应<th> <li>JS 同步逻辑必须含列宽缓存和防抖,否则频繁触发重排影响性能</li> <p>真正麻烦的不是那行 <code>position: sticky,而是列宽对齐、滚动容器高度、z-index层级、背景色这四点——漏掉任意一个,表头就可能半透明、错位、被盖住,或者干脆不动。
th 加了 sticky 却被遮住或透底
只写 position: sticky; top: 0 远远不够。缺一不可的三项是:background-color、z-index、滚动容器配置。
滚动后 th 和 td 列宽错位
这不是 bug,是表格默认按内容自适应宽度导致的渲染不同步。sticky 的 th 和滚动中的 td 分属不同渲染阶段,宽度没绑定。
IE11 及以下怎么降级
position: sticky 在 IE 完全不支持,纯 CSS fallback 不可行。必须结构分离 + JS 同步列宽。











