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

如何在overflow-x可滚动的HTML/CSS/Angular表格中固定最右侧列?

实现横向滚动表格固定最右侧列(叠加表格方案)

核心思路

通过两个独立表格实现:一个表格承载可横向滚动的主体内容(剔除最右侧列),另一个仅保留最右侧固定列,通过绝对定位将其叠加在主体表格的右侧,同时同步两个表格的纵向滚动位置,避免错位。


1. HTML 结构(Angular 模板)

<div class="table-container">
  <!-- 可横向滚动的主体表格(不含最右侧列) -->
  <table class="scroll-table">
    <thead>
      <tr>
        <th>列1</th>
        <th>列2</th>
        <th>列3</th>
        <th>列4</th>
        <!-- 按需添加更多滚动列 -->
      </tr>
    </thead>
    <tbody #scrollTableBody>
      <tr *ngFor="let item of dataList">
        <td>{{item.col1}}</td>
        <td>{{item.col2}}</td>
        <td>{{item.col3}}</td>
        <td>{{item.col4}}</td>
        <!-- 按需添加更多滚动列内容 -->
      </tr>
    </tbody>
  </table>

  <!-- 固定列表格(仅最右侧列) -->
  <table class="fixed-table">
    <thead>
      <tr>
        <th>操作列</th>
      </tr>
    </thead>
    <tbody #fixedTableBody>
      <tr *ngFor="let item of dataList">
        <td>
          <button (click)="editItem(item)">编辑</button>
          <button (click)="deleteItem(item)">删除</button>
        </td>
      </tr>
    </tbody>
  </table>
</div>

2. CSS 样式

.table-container {
  position: relative;
  overflow-x: auto;
  max-width: 100%;
  margin: 1rem;
}

/* 滚动表格:宽度减去固定列宽度,留出固定列位置 */
.scroll-table {
  width: calc(100% - 160px);
  border-collapse: collapse;
}

/* 固定列表格:绝对定位到容器右侧 */
.fixed-table {
  position: absolute;
  top: 0;
  right: 0;
  width: 160px; /* 固定列宽度,需和scroll-table的calc值对应 */
  border-collapse: collapse;
  background-color: #ffffff; /* 和表格背景一致,避免被滚动内容穿透 */
  z-index: 1;
}

/* 统一单元格样式,避免视觉错位 */
.scroll-table th, .scroll-table td,
.fixed-table th, .fixed-table td {
  border: 1px solid #e0e0e0;
  padding: 0.75rem;
  text-align: left;
}

.scroll-table thead th,
.fixed-table thead th {
  background-color: #f5f5f5;
  font-weight: 600;
}

3. Angular 组件逻辑

主要处理纵向滚动同步和行高对齐,避免固定列与主体表格错位:

import { Component, ViewChild, ElementRef, AfterViewInit } from '@angular/core';

@Component({
  selector: 'app-fixed-column-table',
  templateUrl: './fixed-column-table.component.html',
  styleUrls: ['./fixed-column-table.component.css']
})
export class FixedColumnTableComponent implements AfterViewInit {
  @ViewChild('scrollTableBody') scrollTableBody!: ElementRef<HTMLTableSectionElement>;
  @ViewChild('fixedTableBody') fixedTableBody!: ElementRef<HTMLTableSectionElement>;

  dataList = [
    { col1: '测试数据1-1', col2: '测试数据1-2', col3: '测试数据1-3', col4: '测试数据1-4' },
    { col1: '测试数据2-1', col2: '测试数据2-2', col3: '测试数据2-3', col4: '测试数据2-4' },
    { col1: '测试数据3-1(换行内容)', col2: '测试数据3-2', col3: '测试数据3-3', col4: '测试数据3-4' },
    // 可添加更多测试数据
  ];

  ngAfterViewInit(): void {
    // 同步纵向滚动位置
    this.scrollTableBody.nativeElement.addEventListener('scroll', () => {
      this.fixedTableBody.nativeElement.scrollTop = this.scrollTableBody.nativeElement.scrollTop;
    });

    // 同步行高(解决内容换行导致的行高不一致问题)
    const scrollRows = this.scrollTableBody.nativeElement.querySelectorAll('tr');
    const fixedRows = this.fixedTableBody.nativeElement.querySelectorAll('tr');
    
    scrollRows.forEach((row, index) => {
      const fixedRow = fixedRows[index];
      if (fixedRow) {
        fixedRow.style.height = `${row.offsetHeight}px`;
      }
    });
  }

  editItem(item: any): void {
    // 自定义编辑逻辑
    console.log('编辑:', item);
  }

  deleteItem(item: any): void {
    // 自定义删除逻辑
    console.log('删除:', item);
  }
}

关键注意事项

  • 固定列宽度需与scroll-table的calc(100% - 宽度值)严格对应,避免间隙或重叠。
  • 必须同步两个表格的纵向滚动位置,否则滚动主体内容时固定列会脱节。
  • 行高同步是可选但必要的步骤,若单元格内容可能换行,务必添加该逻辑避免错位。
  • 固定列的背景色需与主体表格一致,防止滚动时被内容穿透。

内容的提问来源于stack exchange,提问作者hydra-0-0-0-0

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 03:35:44