# Fix: Transparent Header Cells on Horizontal Scroll with TanStack Table + TanStack Virtual

# The Problem

When using TanStack Table with TanStack Virtual and many columns that extend beyond the viewport, scrolling horizontally causes the header cells to appear transparent. Body row content bleeds through behind the sticky header as you scroll right.

This happens even though the header row itself has `bg-background`.

# Why It Happens

In a typical virtualized data grid setup, the structure looks like this:

```plaintext
<div role="rowgroup" class="sticky top-0 z-10 grid">        <!-- header rowgroup -->
  <div role="row" class="bg-background flex min-w-full">     <!-- header row -->
    <div role="columnheader" class="relative shrink-0">      <!-- header cell (no bg!) -->
```

The header **row** has `bg-background`, but individual header **cells** only get `bg-background` conditionally — typically when `header.column.getIsPinned()` is true. Non-pinned header cells have no background.

When columns extend past the viewport width, the row's background doesn't fully cover all cells in certain rendering scenarios. The sticky positioning combined with `min-w-full` on the row and `shrink-0` on cells creates a situation where the background doesn't paint behind overflow cells.

# The Fix

Two changes, both in the data grid component where headers are rendered:

## 1\. Add `bg-background` to the header rowgroup

```diff
  <div
    role="rowgroup"
    data-slot="grid-header"
    ref={headerRef}
-   className="sticky top-0 z-10 grid"
+   className="bg-background sticky top-0 z-10 grid"
  >
```

## 2\. Give all header cells `bg-background`, not just pinned ones

```diff
  <div
    role="columnheader"
-   className={cn('relative shrink-0', {
+   className={cn('bg-background relative shrink-0', {
      grow: stretchColumns && header.column.id !== 'select' && header.column.id !== 'actions',
-     'bg-background': header.column.getIsPinned(),
    })}
  >
```

The pinned-only conditional was the root cause. Every header cell needs an opaque background so nothing bleeds through when scrolling horizontally — not just the ones pinned to the left/right edge.
