Shadcn React Table

Search documentation

Search the docs

Sticky header & footer

The header row (enableStickyHeader, default true) sticks to the top of the scroll surface. Enable enableStickyFooter (default false) to also pin the aggregation/footer row to the bottom. As you scroll through rows, both stay pinned in view.

Sticky header & footer
GitHub
ID
AvaThompsonOwnerEngineeringactive22$45,000Jan 2, 2023
0%
LiamNguyenAdminMarketinginactive25$47,137Jan 13, 2023
9%
NoahSilvaEditorDesignpending28$49,274Jan 24, 2023
18%
EmmaCarterViewerSalesactive31$51,411Feb 4, 2023
27%
OliviaRossiOwnerSupportinactive34$53,548Feb 15, 2023
36%
WilliamWalkerAdminEngineeringpending37$55,685Feb 26, 2023
45%
SophiaPatelEditorMarketingactive40$57,822Mar 9, 2023
54%
JamesMullerViewerDesigninactive43$59,959Mar 20, 2023
63%
IsabellaParkOwnerSalespending46$62,096Mar 31, 2023
72%
LucasReyesAdminSupportactive49$64,233Apr 11, 2023
81%
MiaJohanssonEditorEngineeringinactive52$66,370Apr 22, 2023
90%
BenjaminCostaViewerMarketingpending55$68,507May 3, 2023
99%
CharlotteChenOwnerDesignactive58$70,644May 14, 2023
7%
HenryCohenAdminSalesinactive61$72,781May 25, 2023
16%
AmeliaNovakEditorSupportpending24$74,918Jun 5, 2023
25%
JackDiazViewerEngineeringactive27$77,055Jun 16, 2023
34%
HarperDuboisOwnerMarketinginactive30$79,192Jun 27, 2023
43%
LeoHaddadAdminDesignpending33$81,329Jul 8, 2023
52%
EllaKhanEditorSalesactive36$83,466Jul 19, 2023
61%
MasonTanakaViewerSupportinactive39$85,603Jul 30, 2023
70%
AvaThompsonOwnerEngineeringpending42$87,740Aug 10, 2023
79%
LiamNguyenAdminMarketingactive45$89,877Aug 21, 2023
88%
NoahSilvaEditorDesigninactive48$92,014Sep 1, 2023
97%
EmmaCarterViewerSalespending51$94,151Sep 12, 2023
5%
OliviaRossiOwnerSupportactive54$96,288Sep 23, 2023
14%
WilliamWalkerAdminEngineeringinactive57$98,425Oct 4, 2023
23%
SophiaPatelEditorMarketingpending60$100,562Oct 15, 2023
32%
JamesMullerViewerDesignactive23$102,699Oct 26, 2023
41%
IsabellaParkOwnerSalesinactive26$104,836Nov 6, 2023
50%
LucasReyesAdminSupportpending29$106,973Nov 17, 2023
59%
MiaJohanssonEditorEngineeringactive32$109,110Nov 28, 2023
68%
BenjaminCostaViewerMarketinginactive35$111,247Dec 9, 2023
77%
CharlotteChenOwnerDesignpending38$113,384Dec 20, 2023
86%
HenryCohenAdminSalesactive41$115,521Dec 31, 2023
95%
AmeliaNovakEditorSupportinactive44$117,658Jan 11, 2024
3%
JackDiazViewerEngineeringpending47$119,795Jan 22, 2024
12%
HarperDuboisOwnerMarketingactive50$121,932Feb 2, 2024
21%
LeoHaddadAdminDesigninactive53$124,069Feb 13, 2024
30%
EllaKhanEditorSalespending56$126,206Feb 24, 2024
39%
MasonTanakaViewerSupportactive59$128,343Mar 6, 2024
48%
$3,466,860

Bounded surface height

Sticky behavior requires a bounded scroll surface — there is nothing to stick to if the table grows to fit all its rows. While enableStickyHeader is on (the default), the surface is automatically capped near the viewport height (clamp(350px, 100dvh - 200px, 9999px)), so tall tables scroll internally out of the box. The - 200px is a heuristic that reserves room for the toolbar and pagination — if the table sits below a lot of other page content, the surface can still extend past the viewport; pick your own bound in that case. To do so, set a max height with surfaceClassName on <DataTable /> — it overrides the default:

const table = useDataTable({
  data,
  columns,
  getRowId: (row) => row.id,
  enableStickyHeader: true,
  enableStickyFooter: true,
})

return <DataTable table={table} surfaceClassName="max-h-[460px]" />

Once the content overflows the bound, the header pins to the top and the footer pins to the bottom while the rows scroll between them. Setting enableStickyHeader: false removes both the pinning and the default bound, letting the table grow to its full height.

MRT parity note

Material React Table defaults enableStickyHeader and enableStickyFooter to false. This table deliberately defaults enableStickyHeader to true so headers stay useful out of the box, but leaves enableStickyFooter at false (opt in when you have an aggregation/footer row). The sticky-implies-bounded-surface behavior itself matches MRT.

Footer cells are populated from each column's footer definition or from aggregation values. See Grouping for how aggregation rows are produced.

Nothing to stick to?

If the header or footer is not sticking, the surface is probably not bounded — check that surfaceClassName isn't removing the default max-height (e.g. max-h-none) and that the data actually overflows the bound.