带粘性表头与首列的类表格结构无法垂直滚动问题排查
实现带粘性表头和首列的可滚动类表格结构
核心问题分析
- 首列粘性失效:当前
.tr-resource-cell的sticky定位参考的是.tr-matrix,但水平滚动容器是.tr-matrix-container,滚动时首列的粘性定位会失效导致消失。 - 表头无法固定:表头和内容区共用同一个滚动容器,添加垂直滚动后表头会跟着内容一起滚动,无法单独固定。
- 双重水平滚动条:
.tr-matrix-container和.tr-matrix都开启了水平滚动,导致出现重叠的滚动条。
解决方案
1. 调整HTML结构
无需大幅改动结构,保持原有层级即可,确保表头和内容区共享同一个水平滚动容器。
2. 修改SCSS样式
关键修改点:
- 统一水平滚动容器到
.tr-matrix-container,仅为内容区开启垂直滚动 - 给表头添加垂直粘性定位,确保滚动时固定
- 修正首列的粘性定位参考容器
- 调整z-index确保元素层级正确
修改后的SCSS代码:
$headerHeight: 2.5rem; $resourceCellWidth: 8.5rem; $rowHeight: 7.5rem; $rowWidth: 16.625rem; html, body { margin: 0; padding: 0; height: 100vh; overflow: hidden; } .tr-matrix-container { position: relative; overflow-x: auto; height: 100vh; // 表头垂直固定,跟随水平滚动 .tr-matrix-header { position: sticky; top: 0; z-index: 3; display: flex; height: $headerHeight; background-color: #333333; // 避免内容透过表头显示 .tr-header-col { width: $rowWidth; color: #ffffff; border: 1px solid #cbcbcb; box-shadow: 0 0.2rem 0.2rem rgba(0, 0, 0, 0.6); box-sizing: border-box; flex-shrink: 0; } .tr-zoom-level-cell { position: sticky; left: 0; z-index: 4; width: $resourceCellWidth; height: $headerHeight; box-shadow: 0.2rem 0.2rem 0.2rem rgba(0, 0, 0, 0.6); } } // 内容区仅开启垂直滚动,水平滚动依赖外层容器 .tr-matrix { overflow-y: auto; height: calc(100vh - #{$headerHeight}); .tr-row { display: flex; height: $rowHeight; } .tr-resource-cell { position: sticky; left: 0; z-index: 2; background-color: #ffffff; width: $resourceCellWidth; border: 1px solid #cbcbcb; border-top-width: 0; box-sizing: border-box; box-shadow: 0.2rem 0 0.2rem rgba(0, 0, 0, 0.5); flex-shrink: 0; } .tr-cell { width: $rowWidth; border: 1px solid #cbcbcb; border-left-width: 0; border-top-width: 0; box-sizing: border-box; flex-shrink: 0; } } }
3. 关键细节说明
- 滚动容器统一:仅
.tr-matrix-container设置overflow-x: auto,.tr-matrix只开启overflow-y: auto,彻底解决双重滚动条问题。 - 表头垂直固定:
.tr-matrix-header添加position: sticky; top: 0,确保垂直滚动时表头固定在顶部,同时跟随外层容器的水平滚动。 - 首列粘性修正:
.tr-resource-cell和.tr-zoom-level-cell的left: 0粘性定位现在参考的是.tr-matrix-container(最外层滚动容器),水平滚动时首列会保持固定。 - 层级控制:通过z-index确保表头首列(z=4)> 表头其他列(z=3)> 内容首列(z=2),避免元素遮挡。
4. React组件适配提示
如果后续重构为React组件,可通过以下方式优化:
- 使用
useRef获取.tr-matrix-container和.tr-matrix的DOM元素,监听滚动事件同步两者的水平滚动位置(部分浏览器可能需要手动同步)。 - 动态计算内容区高度,适配不同的布局场景(比如页面有其他顶部导航时,调整
calc(100vh - #{$headerHeight} - 导航高度))。
内容的提问来源于stack exchange,提问作者Bruce O.
相关产品推荐
相关产品推荐

