A sticky and on top <TableHeader /> component

I’m using shadcn’s data table components built on TanStack Table, and I’m trying to make the <TableHeader /> sticky so it stays on top of the rows. However, I haven’t been able to get it working properly without breaking the styling or running into an issue where the header and rows become misaligned when horizontally scrolling.

How can I correctly make the table header sticky while keeping the header and rows aligned during horizontal scroll?

I kept the snippet brief and removed most for readability, but I’m happy to share more details if needed.

  <Table className="h-full w-full"> 
      <TableHeader> {/* feat: sticky and on top */}
        {table.getHeaderGroups().map((headerGroup) => (
          <TableRow key={headerGroup.id}>
            {headerGroup.headers.map((header) => {
              return (
                <TableHead 
                  key={header.id} 
                  className='border-r last:border-r-0'
                >
                  {header.isPlaceholder
                    ? null
                    : flexRender(
                        header.column.columnDef.header,
                        header.getContext()
                      )}
                </TableHead>
              )
            })}
          </TableRow>
        ))}
      </TableHeader>
      {/* ... */}
    </Table>
Was this page helpful?