Search code examples
javascriptreactjsmaterial-uiz-index

Z-Index on Popper menu?


I have a working example reproducing this issue on codesandbox.io.

What I'm trying to do is do the 'sit below' menu as demonstrated on the Material-UI documentation.

   return (
      <div className={classes.root}>
        <div>
          <Button
            buttonRef={node => {
              this.anchorEl = node;
            }}
            aria-owns={open ? "menu-list-grow" : null}
            aria-haspopup="true"
            onClick={this.handleToggle}
          >
            Toggle Menu Grow
          </Button>
          <Popper open={open} anchorEl={this.anchorEl} transition disablePortal>
            {({ TransitionProps, placement }) => (
              <Grow
                {...TransitionProps}
                id="menu-list-grow"
                style={{
                  transformOrigin:
                    placement === "bottom" ? "center top" : "center bottom"
                }}
              >
                <Paper>
                  <ClickAwayListener onClickAway={this.handleClose}>
                    <MenuList>
                      <MenuItem onClick={this.handleClose}>Profile</MenuItem>
                      <MenuItem onClick={this.handleClose}>My account</MenuItem>
                      <MenuItem onClick={this.handleClose}>Logout</MenuItem>
                    </MenuList>
                  </ClickAwayListener>
                </Paper>
              </Grow>
            )}
          </Popper>
        </div>

        <Button color="default" variant="contained">
          {" "}
          I'm a button that sits under the menu
        </Button>
      </div>
    );

The issue I have here is that the Button further down the DOM, from the menu is always on top.

I've tried manually adding zIndex to various parts of the menu - but to no avail.

I suspect that the issue is something to do with the transition.

Can someone explain what's going on here, and how would I solve it?


Solution

  • I removed the disablePortal prop on the Popper component :

    <Popper open={open} anchorEl={this.anchorEl} transition disablePortal>
    

    Which now becomes

    <Popper open={open} anchorEl={this.anchorEl} transition>
    

    See the Material-UI documentation for the Popper component disablePortal prop to see why:

    Disable the portal behavior. The children stay within it's parent DOM hierarchy.

    By default, the Popper component uses the React Portal API : https://reactjs.org/docs/portals.html

    Portals provide a first-class way to render children into a DOM node that exists outside the DOM hierarchy of the parent component

    Using the React Portal API, the Material-UI Popper component renders by default outside the DOM hierarchy of the parent tree, this explains why it resolves the overlaying issue.

    The modified working code is on codesandbox.io