原生<table>标签也能实现末列固定

2,378 阅读4分钟
mmexport1732796227163.gif

开发一个带有固定列的表格,绝对是前端开发中顶顶简单的事情了。

如果你用 Element UI 或者 Ant Design 就可以直接使用 fixed="right" 来实现了,

但如果不依赖任何前端框架(如 Vue.js、React 等)或 UI 组件库(如 Element UI、Ant Design 等),只使用原生的 HTML <table> 标签来开发表格界面,就要用到 position: sticky;,来把表格 “ 粘起来 ”了。

先上demo:

<div class="table-wrapper">
    <table border="1" cellspacing="0" cellpadding="0">
      <thead>
        <tr>
          <th>列1</th>
          ...
          <th>操作</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>xxxxxxxx</td>
          ...
          <td><button>删除</button></td>
        </tr>
      </tbody>
    </table>
  </div>
<style>
    table {
      border-collapse: collapse;
      border: none;
    }
    tr {
      border-top: 1px solid #000;
    }
    tr:last-child {
      border-bottom: 1px solid #000;
    }
    th,
    td {
      border: none;
      padding: 10px 20px;
      text-align: left;
    }
    /* 以上是table的基础样式 */

    /* 以下是table固定列的决定性样式 */
    /* 设置表格容器的宽度,允许水平滚动,并设置相对定位以便固定列能够正确定位 */
    .table-wrapper {
      width: 600px;
      overflow-x: auto; /* 允许表格水平滚动 */
      position: relative; /* 为固定列提供定位上下文 */
    }
    /* 使表格的最后一列在滚动时固定定位 */
    th:last-child,
    td:last-child {
      position: sticky; /* 使元素在滚动时固定定位 */
      right: 0; /* 固定在视口的右侧 */
      background-color: #fff; /* 设置背景色,防止内容透明 */
      z-index: 1; /* 确保固定列在滚动时始终可见 */
      white-space: nowrap; /* 最后一列不换行,保持内容完整显示 */
    }
  </style>

这些css如何生效的?

在这个HTML demo中,表格的最后一列被固定的效果主要是通过以下CSS属性实现的:

  1. position: sticky; :这个属性是使元素在跨越特定阈值时(在本例中是滚动到视口边缘时)变为固定定位的关键。对于th:last-child, td:last-child选择器,它指定了当这些元素滚动到视口(或包含它们的滚动容器)的边缘时,它们将“粘”在那里,而不是随着页面继续滚动而移动。
  2. right: 0; :这个属性与position: sticky;一起使用,指定了当元素变为固定定位时,它应该“粘”在视口的哪个位置。在这个例子中,right: 0;意味着元素将固定在视口的右侧。
  3. z-index: 1; :这个属性确保了当表格的其他部分滚动到固定列下方时,固定列仍然保持在顶部。z-index属性控制元素的堆叠顺序,数值越大的元素会显示在越上面。

请注意,position: sticky;的支持情况可能因浏览器而异,因此在实际部署之前,请确保在目标浏览器上测试此功能。此外,虽然这个demo在大多数情况下都能正常工作,但在某些极端情况下(如表格内容过多或浏览器性能限制),可能会遇到滚动性能问题。

关于position: sticky的补充:

position: sticky; 是 CSS 中的一个定位属性值,它允许一个元素在跨越特定阈值时(如滚动到视口边缘)在相对定位和固定定位之间切换。换句话说,当页面滚动时,一个 position: sticky; 的元素会在它到达视口(或指定的包含块)的某个位置时“粘”在那里,而不是随着页面继续滚动。

具体来说,position: sticky; 的工作原理如下:

  1. 默认行为:在滚动过程中,元素会表现为 position: relative;,即元素会保持在文档流中的正常位置。
  2. 粘性定位:当元素滚动到其包含块(通常是视口或最近的具有滚动机制的祖先元素)的指定位置时,它会“粘”在那里,表现为 position: fixed;,即相对于视口或包含块进行定位,而不是随页面滚动。
  3. 阈值设定:通过 toprightbottom 或 left 属性来设置元素何时开始粘性定位。例如,position: sticky; top: 0; 会使元素在滚动到视口顶部时固定。
  4. 层叠上下文position: sticky; 的元素会创建一个新的层叠上下文,这意味着该元素内的定位元素会相对于它进行定位,而不是视口或文档流。

使用 position: sticky; 可以创建一些非常有用的界面效果,如固定表头、侧边导航栏等,同时保持页面的滚动性能。然而,需要注意的是,并非所有浏览器都完全支持 position: sticky;,因此在实际应用中需要测试兼容性。

在你的表格示例中,通过为表格的最后一列设置 position: sticky; right: 0;,可以实现当表格水平滚动时,最后一列始终保持在视口的右侧,从而提供了一种用户友好的滚动体验。