12

I am using the Material-UI framework for React to display a table. I would like to use a sticky header; however, I do not want to set a height on my table, as I'd like it to scroll with the page. The following snippet does not stick the header unless I set a height on the TableContainer.

https://codesandbox.io/s/winter-firefly-5wlx2?file=/src/App.js

import React from "react";
import {
  TableContainer,
  Table,
  TableHead,
  TableRow,
  TableCell
} from "@material-ui/core";
import "./styles.css";

export default function App() {
  return (
    <TableContainer>
      <Table stickyHeader>
        <TableHead>
          <TableRow>
            <TableCell>Value</TableCell>
          </TableRow>
        </TableHead>
        {
          Array(100).fill("Test").map((e) => <TableRow><TableCell>{e}</TableCell></TableRow>)
        }
      </Table>
    </TableContainer>
  );
}
Dynamic
  • 497
  • 1
  • 10
  • 17

3 Answers3

21

Get rid of the TableContainer overflow-x: auto and it should work

const useStyles = makeStyles({
  customTableContainer: {
    overflowX: "initial"
  }
})

export default function App() {
  const classes = useStyles();
  return (
    <TableContainer classes={{root: classes.customTableContainer}}>
      <Table stickyHeader>
      
      ...

Edit cool-shadow-59lrh

Reference: https://css-tricks.com/dealing-with-overflow-and-position-sticky/

95faf8e76605e973
  • 13,643
  • 3
  • 24
  • 51
  • Any way to do this while keeping 100% width? – Dynamic Oct 02 '20 at 22:18
  • i did not touch the `width` property of `TableContainer` - it is still at `100%` `width`. If you comment out the `overflowX: "initial"` on my code - you can see that it is still very similar to your sandbox, the only difference I made is on the sticky header – 95faf8e76605e973 Oct 02 '20 at 22:20
  • Let me rephrase: is there any way to keep the x direction scrollable within the table while making the y direction scrollable with the page - all while keeping the sticky header working. – Dynamic Oct 02 '20 at 22:22
  • It's quite possible. Take a look at [this](https://stackoverflow.com/questions/14977864/fixed-header-table-with-horizontal-scrollbar-and-vertical-scrollbar-on) and [this](https://stackoverflow.com/questions/36014802/fixed-table-header-scroll-both-horizontal-and-vertical-css-only) – 95faf8e76605e973 Oct 02 '20 at 22:40
  • 1
    Thank you so much, I've been looking for this fix for 2 days – Stanford Mar 17 '21 at 09:06
  • I was having issues by wrapping my `` in a `` component. Building off the current answer, the solution worked for me:``, and of course `
    `
    – G M Aug 02 '22 at 23:55
1

Actually I was facing something similar, I wanted my table to be 100% of the available height, so I gave 100% height to the parent tag instead of the table, then in my table a made the calc of the parents height with my table's container reference, the implementation would be something like this

// 1. create a ref
const tableContainerRef = useRef(null);

// 2. wait until the container ref is populated and retrieve the parents height
const containerMaxHeight = useMemo(() => {
  if (!tableFormRef.current) return null;

  return tableFormRef.current.parentElement.clientHeight;
}, [tableFormRef.current]);

// 3. use the height of the parent as your table's maxHeight
return (
  <div ref={tableContainerRef}>
    <TableContainer style={{maxHeight: containerMaxHeight}}>
      <Table>
       ...
      </Table>
    </TableContainer>
  </div>
);
0

Turns out if you just use 100vh instead of 100% it works:

export default function App() {
  return (
    <TableContainer sx={{ maxHeight: "100vh" }}>
      <Table stickyHeader>