阅读视图

发现新文章,点击刷新页面。

前端好搭档:table 和 position sticky

前言

前端开发中,总是会接到各式各样的交互需求。最近产品想在移动端中实现一个报表功能,在页面中以表格的形式展示各个统计数据。

这本来是个普普通通的需求,使用 html 的 table 标签就可以实现,但是要求在页面滑动过程中表头要固定在顶部,同时在表格滑出页面时,表头取消固定在顶部,大致如下:

image-20251011154234246

表头固定现在有 CSS position: sticky 可以直接实现,但是滑出屏幕后不再固定,这个交互第一直觉要用 JS 去实现了,因为 position: sticky 应该会让元素一直保持在顶部,就像下面这个“固定在顶部的内容”元素一样。

table_base1

代码示例:

当时的想法是先写个示例看看,用 position: sticky 加 JS 实现。

方案实现

页面的基础内容如下,一个页面标题加内容,内容区域使用 table 标签实现表格功能。

<h1>HTML表格基础示例</h1>
<div class="content">
  <p>这是第一个表格,包含10条数据。</p>
  <table>
    <colgroup>
      <col style="width: 200px;">
      <col style="width: 150px;">
      <col style="width: 300px;">
      <col style="width: 200px;">
    </colgroup>
    <thead>
      <tr>
        <th>姓名</th>
        <th>年龄</th>
        <th>职位</th>
        <th>部门</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>张三</td>
        <td>28</td>
        <td>软件工程师</td>
        <td>研发部</td>
      </tr>
      <!-- ...更多数据行 -->
    </tbody>
  </table>
  <!-- ...更多其他表格 -->
</div>

CSS 部分就是设置内容区域(类名为 content 的元素)可以滑动和表头固定,关键代码如下:

body {
    display: flex;
    flex-direction: column;
}
.content {
    flex: 1;
    overflow-y: auto;
}
table {
    border-collapse: collapse;
}
th {
    position: sticky;
    top: 0;
    z-index: 10;
}

代码中我们在表头设置了 position: sticky 属性,让其在滑动出屏幕时可以固定在顶部,让我们看下效果。

table_base2

示例代码:

可以看到我们直接实现了最终的效果,在表格离开视图后,表头也不再固定在顶部。平时在使用 position: sticky 时倒是没发现这点,查了 MDN 文档解释如下:

一个 sticky 元素会“固定”在离它最近的一个拥有“滚动机制”的祖先上(当该祖先的 overflowhiddenscrollautooverlay 时),即便这个祖先不是最近的真实可滚动祖先。

但是示例代码中只在内容区域(类名为 content 的元素)设置了 overflow 属性,按理说表头会一直固定在顶部才对,只能暂时理解 table 有特殊的渲染机制。

总结

实践结果来说,在 table 表头设置 position: sticky 会有一些比较特殊的行为,这个行为又比较符合平时认知的习惯(表格的表头顶部固定,表格滑出屏幕后不再固定表头)。

上面的 position: sticky 仅仅是初步的方案,如果你的表格宽度超过一屏幕,此时的左右滑动会是基于内容区域(类名为 content 的元素),你可能想通过在 table 外层加一个 div 来实现仅仅 table 区域左右滑动,但是外层 div 设置了 overflow 属性,表头就不会再基于内容区域(类名为 content 的元素)固定了,所以可能需要通过 JS 实现左右滑动。

在此基础上要是有首列固定的需求,也需要通过 JS 去实现。

左右滑动是基于内容区域效果如下:

table_base3

最后,文中若有不对的地方,欢迎讨论指正。

❌