Height & scrolling
The grid is a flex column: the header pins to the top, the footer (pagination) pins to the bottom, and the body scrolls between them. You only choose how tall the grid is — there are three modes.
| Mode | How | Behaviour |
|---|---|---|
| Auto (default) | no height bound | Grid grows to its content; no inner scroll. |
| Capped | maxHeight={400} | Body grows to the cap, then scrolls. |
| Fixed / fill | height={400} or height="100%" | Grid is exactly that tall; the body flexes to fill and scrolls. |
:::tip No minHeight needed
For the body to scroll between a pinned header and footer, the grid just needs a bounded height —
via maxHeight, height, or a fixed-height parent. minHeight is not required; it exists only as
an optional floor so a near-empty grid doesn't collapse.
:::
Auto height (default)
With no height bound the grid is exactly as tall as its rows and never scrolls internally — drop it into a page and it just flows.
<DataTable columns={columns} data={data} />
Capped — maxHeight
The body grows until it reaches maxHeight, then scrolls while the header stays pinned. maxHeight
works on its own — you don't also need stickyHeader.
<DataTable columns={columns} data={data} maxHeight={260} />
Fixed / fill — height
Give the grid a fixed height (a number/CSS length), or height="100%" to fill a sized parent. The
body flexes to fill the space and scrolls, while the header and the pagination footer stay pinned — the
classic dashboard panel. This is the layout you reach for when you have only a sticky header and a
sticky footer and want the rows to scroll between them.
// Fill a sized parent — body scrolls between a pinned header & footer
<Box sx={{ height: 360 }}>
<DataTable columns={columns} data={data} height="100%" enablePagination />
</Box>
// …or a fixed pixel height
<DataTable columns={columns} data={data} height={360} enablePagination />
Sticky shorthands
stickyHeader and stickyFooter are conveniences for "just make the header/footer stick" without
picking an explicit height: each bounds the body at maxHeight (default 480). stickyFooter only
has a visible effect when there's a footer (i.e. enablePagination).
<DataTable columns={columns} data={data} stickyHeader enablePagination />
// equivalent to: maxHeight={480} with the header pinned
Props
| Prop | Type | Default | Description |
|---|---|---|---|
maxHeight | string | number | 480¹ | Cap the scroll viewport; the body scrolls past it. Active on its own. |
height | string | number | — | Fix the grid height; '100%' fills a sized parent. |
minHeight | string | number | — | Optional floor so a near-empty grid doesn't collapse. |
stickyHeader | boolean | — | Pin the header; on its own bounds the body at maxHeight. |
stickyFooter | boolean | — | Pin the pagination footer; like stickyHeader, bounds the body. |
¹ maxHeight only defaults to 480 in a bounded mode (stickyHeader / stickyFooter /
enableVirtualization). With no bound at all the grid stays auto-height.
:::note Virtualization
enableVirtualization needs a bounded height to know its viewport. Any of the modes above provides one —
maxHeight, height, or stickyHeader (which applies the default cap).
:::