Fixed header
Set fixedHeader to keep the column headers visible while the user scrolls through a long dataset. The table body becomes independently scrollable within a container whose height is controlled by fixedHeaderScrollHeight.
Fixed header
40 rows and ~1160px of columns. By default wide content scrolls horizontally inside the table. Turn fixedHeader off to unlock the disable-responsive checkbox: with both off, the table overflows the demo card instead of scrolling. While fixedHeader is on the checkbox is disabled, since fixedHeader always creates a scroll container.
import DataTable, { type TableColumn } from 'react-data-table-component';
const columns: TableColumn<Employee>[] = [
{ name: '#', selector: r => r.id, width: '60px' },
{ name: 'Name', selector: r => r.name, sortable: true },
{ name: 'Department', selector: r => r.department, sortable: true },
{
name: 'Salary',
selector: r => r.salary,
sortable: true,
right: true,
format: r => `$${r.salary.toLocaleString()}`,
},
{ name: 'Status', selector: r => r.status },
];
<DataTable
columns={columns}
data={data} // large dataset
fixedHeader
fixedHeaderScrollHeight="300px"
highlightOnHover
/>;How it works
When fixedHeader is enabled, the responsive wrapper gainsoverflow-y: auto and the max-height you set viafixedHeaderScrollHeight. The column header row getsposition: sticky; top: 0 so it remains in view as the body scrolls within that container.
Because the scroll container is the responsive wrapper, horizontal scrolling for wide tables continues to work normally. Both axes scroll together, but the header sticks on the vertical axis.
Turning the scroll container off
responsive={false} removes the table's own horizontal scroll container, letting wide content overflow into the parent instead. It exists for a few specific situations:
- Parent-owned scrolling. The table sits inside your own scroll container (a dashboard panel, a split view, several tables sharing one horizontal scrollbar). Nesting the table's
overflow-x: autoinside yours would produce scrollbars within scrollbars. - Print and PDF export. An overflow container clips everything past the fold; disabling it lets the full table width render in print stylesheets.
- Table dictates layout. You want the page itself to widen or scroll rather than the table.
<div className="my-own-scroll-container">
<DataTable columns={columns} data={data} responsive={false} />
<OtherWidgetSharingTheScroll />
</div>;Trade-offs: features that rely on the table's own scrollport degrade. Pinned columns stick against whatever scroll container the parent provides, which usually works, but the custom pinned-columns scrollbar does not render, and the native one is left visible instead.fixedHeader still creates a vertical scroll container regardless, since a height cap without overflow is meaningless. Leave responsive on (the default) unless one of the cases above applies.
With pagination
Fixed header and pagination work together without any extra configuration. The scroll height only constrains the table body rows. The pagination bar sits below the responsive wrapper and is always fully visible.
<DataTable
columns={columns}
data={data}
fixedHeader
fixedHeaderScrollHeight="400px"
pagination
paginationPerPage={20}
/>;With selection
The checkbox column header scrolls with all other headers and stays fixed. The select-all checkbox remains accessible at the top of the scrollable area.
<DataTable columns={columns} data={data} fixedHeader fixedHeaderScrollHeight="350px" selectableRows />;Tracking scroll position with onScroll
The onScroll prop fires on every scroll event inside the table body. It receives a standard React.UIEvent<HTMLDivElement> so you can read scrollTop,scrollLeft, or any other scroll geometry from event.target.
onScroll
Scroll the table body — the current scrollTop value updates in real time.
const [scrollTop, setScrollTop] = useState(0);
<DataTable
columns={columns}
data={data}
fixedHeader
fixedHeaderScrollHeight="300px"
onScroll={e => setScrollTop(Math.round((e.target as HTMLDivElement).scrollTop))}
/>;Prop reference
| Prop | Type | Default | Description |
|---|---|---|---|
responsive | boolean | true | Wrap the table in a horizontally scrollable container. Disable only when a parent element owns scrolling, see Turning the scroll container off. |
fixedHeader | boolean | false | Stick the column header at the top when scrolling. |
fixedHeaderScrollHeight | string | "100vh" | Max height of the scrollable body when fixedHeader is on. |
onScroll | (event) => void | - | Called when the user scrolls the table body. Works with fixedHeader on or off. |
See it combined with other features in the Audit log viewer recipe.