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

Angular中CdkVirtualScrollViewport表头无法固定问题求助

Fix Fixed Header with CDK Virtual Scroll in Angular

To get a fixed table header with scroll only in the body when using Angular CDK Virtual Scroll, split your table into separate fixed header and scrollable body sections, then align their columns properly. Here's how to implement it:

Step 1: Import Required Module

First, ensure you’ve added the CDK Scrolling module to your Angular module:

import { ScrollingModule } from '@angular/cdk/scrolling';

@NgModule({
  imports: [
    // Other existing imports
    ScrollingModule
  ]
})
export class YourFeatureModule { }

Step 2: HTML Structure

Separate the header and body into distinct sections—keep the header outside the virtual scroll viewport so it stays fixed:

<div class="fixed-header-table-container">
  <!-- Fixed Header Table -->
  <table class="table-header">
    <thead>
      <tr>
        <th class="col-1">ID</th>
        <th class="col-2">Name</th>
        <th class="col-3">Email</th>
        <th class="col-4">Status</th>
      </tr>
    </thead>
  </table>

  <!-- Virtual Scroll Viewport for Table Body -->
  <cdk-virtual-scroll-viewport itemSize="50" class="table-body-viewport">
    <table class="table-body">
      <tbody>
        <tr *cdkVirtualFor="let user of usersList" class="table-row">
          <td class="col-1">{{user.id}}</td>
          <td class="col-2">{{user.name}}</td>
          <td class="col-3">{{user.email}}</td>
          <td class="col-4">{{user.status}}</td>
        </tr>
      </tbody>
    </table>
  </cdk-virtual-scroll-viewport>
</div>

Step 3: CSS Styling

Ensure the header stays fixed, the body scrolls, and columns align perfectly:

.fixed-header-table-container {
  width: 100%;
  max-height: 500px; /* Set your desired container height */
  position: relative;
}

/* Fixed Header */
.table-header {
  width: 100%;
  table-layout: fixed; /* Critical for column alignment between header/body */
  border-collapse: collapse;
  position: sticky;
  top: 0;
  background: white; /* Prevents body content from showing through */
  z-index: 1;
}

/* Adjust for scrollbar width to avoid header content being cut off */
.table-header th:last-child {
  padding-right: 17px; /* Matches default browser scrollbar width */
}

/* Virtual Scroll Viewport */
.table-body-viewport {
  height: calc(100% - 40px); /* Subtract header height to avoid overlap */
  width: 100%;
}

/* Body Table */
.table-body {
  width: 100%;
  table-layout: fixed; /* Match header's table layout */
  border-collapse: collapse;
}

/* Column Widths - Match header and body columns exactly */
.col-1 { width: 10%; }
.col-2 { width: 30%; }
.col-3 { width: 40%; }
.col-4 { width: 20%; }

/* Row Styling */
.table-row {
  height: 50px; /* Must match itemSize value in cdkVirtualFor */
}

th, td {
  padding: 12px;
  text-align: left;
  border-bottom: 1px solid #eee;
}

Key Fixes & Notes

  • Split Header/Body: Moving the header outside the cdk-virtual-scroll-viewport prevents it from scrolling with the body.
  • itemSize Alignment: Set this value to the exact height of your table rows to ensure virtual scroll calculates correctly.
  • table-layout: fixed: This forces columns to maintain consistent widths between header and body, even with varying content lengths.
  • Scrollbar Padding: Adding padding to the last header column stops content from being hidden behind the body’s scrollbar.

内容的提问来源于stack exchange,提问作者Bhushan Khaladkar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 22:20:20