You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:实现带横向滚动、固定列与固定表头的无JS表格

问题:实现带固定表头、固定首列的横向滚动表格(纯CSS)

我想做一个宽表格,需要满足三个要求:

  • 支持横向滚动
  • 左侧首列固定不随横向滚动移动
  • 顶部表头在页面向下滚动时固定在屏幕顶部

我不确定这几个需求能不能兼容,试了几种方法后写出了下面的代码,现在的问题是表头无法和表格主体同步横向滚动。可以用div或者table元素实现,希望完全不用JavaScript。

我当前的代码

CSS

body {
  background: #F5F7FA;
  overflow-x: hidden;
}

.wrap {
  position: relative;
  margin: 10em auto 30em;
  max-width: 960px;
  overscroll-behavior: contain;
}

.headers {
  top: 0;
  position: -webkit-sticky;
  position: sticky;
  z-index: 1;
}

.tracks,
.scroller {
  display: flex;
  overflow-y: hidden;
  -webkit-overflow-scrolling: touch;
}

.scroller {
  overflow-x: hidden;
}

.tracks {
  overflow: auto;
  scroll-snap-type: x mandatory;
}

.scenes::-webkit-scrollbar,
.scroller::-webkit-scrollbar {
  display: none;
}

.track {
  flex: 1 0 calc(22% + 2px);
  scroll-snap-align: start;
}

.track.first {
    position: sticky;
    left: 0;
}

.sticky {
  position: sticky;
  top: 0;
}

.track + .track {
  margin-left: -1px;
}

.heading {
  height: 50px;
  display: flex;
  justify-content: center;
  align-items: center;
  position: -webkit-sticky;
  position: sticky;
  top: 0;
  border: solid #fff;
  border-width: 0 1px;
  z-index: 1;
  background: #efefef;
  font-weight: 700;
}

.entry {
  border: 1px solid #ebebeb;
  border-top: 0;
  background: #fff;
  height: 8em;
  padding: 1em;
}


@media (max-width: 767px) {
  .track {
    flex: 1 0 calc(50% + 7px);
  }
}

HTML

<div class="wrap">
  <div class="headers">
    
    <div class="scroller">
      <div class="track">
        <div class="heading">Heading 1</div>
      </div>
      <div class="track">
        <div class="heading">Heading 2</div>
      </div>
      <div class="track">
        <div class="heading">Heading 3</div>
      </div>
      <div class="track">
        <div class="heading">Heading 4</div>
      </div>
      <div class="track">
        <div class="heading">Heading 5</div>
      </div>
    </div>

  </div>

  <div class="tracks">

    <div class="track first">
      <div class="entry">
        <h3>Lorem, ipsum dolor.</h3>
      </div>
      <div class="entry">
        <h3>Lorem, ipsum.</h3>
      </div>
    </div>

    <div class="track">
      <div class="entry">
        <h3>Lorem, ipsum dolor.</h3>
      </div>
      <div class="entry">
        <h3>Lorem, ipsum.</h3>
      </div>
    </div>

    <div class="track">
      <div class="entry">
        <h3>Lorem, ipsum dolor.</h3>
      </div>
      <div class="entry">
        <h3>Lorem, ipsum.</h3>
      </div>
    </div>

    <div class="track">
      <div class="entry">
        <h3>Lorem, ipsum dolor.</h3>
      </div>
      <div class="entry">
        <h3>Lorem, ipsum.</h3>
      </div>
    </div>

    <div class="track">
      <div class="entry">
        <h3>Lorem, ipsum dolor.</h3>
      </div>
      <div class="entry">
        <h3>Lorem, ipsum.</h3>
      </div>
    </div>
   
  </div>
</div>

效果示意图

效果示意图

需求选项

  • 选项1:修复现有代码,让表头随表格其余部分同步横向滚动
  • 选项2:换一种纯CSS实现方案达成相同效果

解决方案

问题根源

你当前代码的核心问题是表头容器.scroller和表格主体容器.tracks是两个独立元素,没有共享同一个滚动上下文,导致横向滚动无法同步。

纯CSS解决方案(使用table元素,推荐)

用原生table结合CSS sticky属性可以完美实现所有需求,语义化更好且无需JavaScript:

/* 基础重置 */
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  background: #F5F7FA;
  padding: 10em 0 30em;
}

/* 滚动容器 */
.table-container {
  max-width: 960px;
  margin: 0 auto;
  overflow-x: auto;
  position: relative;
}

/* 表格样式 */
.sticky-table {
  width: max-content;
  border-collapse: separate;
  border-spacing: 0;
}

/* 表头固定 */
.sticky-table th {
  position: sticky;
  top: 0;
  background: #efefef;
  border: 1px solid #fff;
  height: 50px;
  padding: 0 1em;
  font-weight: 700;
}

/* 首列固定 */
.sticky-table th:first-child,
.sticky-table td:first-child {
  position: sticky;
  left: 0;
  z-index: 2;
}

/* 首列单元格背景调整 */
.sticky-table th:first-child {
  background: #efefef;
}
.sticky-table td:first-child {
  background: #fff;
  border-right: 1px solid #ebebeb;
}

/* 表格内容单元格 */
.sticky-table td {
  border: 1px solid #ebebeb;
  border-top: none;
  padding: 1em;
  width: 220px;
  height: 8em;
}

/* 隐藏滚动条(可选) */
.table-container::-webkit-scrollbar {
  display: none;
}

/* 移动端适配 */
@media (max-width: 767px) {
  .sticky-table td {
    width: 50%;
  }
}
<div class="table-container">
  <table class="sticky-table">
    <thead>
      <tr>
        <th>Heading 1</th>
        <th>Heading 2</th>
        <th>Heading 3</th>
        <th>Heading 4</th>
        <th>Heading 5</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>Lorem, ipsum dolor.</td>
        <td>Lorem, ipsum dolor.</td>
        <td>Lorem, ipsum dolor.</td>
        <td>Lorem, ipsum dolor.</td>
        <td>Lorem, ipsum dolor.</td>
      </tr>
      <tr>
        <td>Lorem, ipsum.</td>
        <td>Lorem, ipsum.</td>
        <td>Lorem, ipsum.</td>
        <td>Lorem, ipsum.</td>
        <td>Lorem, ipsum.</td>
      </tr>
    </tbody>
  </table>
</div>

方案说明

  1. 横向滚动:外层table-container设置overflow-x: auto,表格设置width: max-content,超出容器宽度时自动触发横向滚动。
  2. 表头固定:给所有<th>设置position: sticky; top: 0,页面向下滚动时表头会固定在屏幕顶部。
  3. 首列固定:给首列的<th>和<td>设置position: sticky; left: 0,并通过z-index确保首列不会被其他列覆盖。
  4. 完全基于CSS实现,无需JavaScript,兼容所有现代浏览器。

内容的提问来源于stack exchange,提问作者Radim Němeček

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 07:40:31