In MUI v5 React, the scroll bar vanishes from view when the drawer is open

Currently, I am working on developing a responsive drawer in React using mui v5. In the set-up, the minimum width of the drawer is defined as 600px when it expands to full width. However, an issue arises when the screen exceeds 600px - at this point, the drawer's width decreases to 240px.

The problem occurs when the screen is larger than 600px: when the drawer is open, the page's scrollbar disappears, rendering the page unscrollable. Conversely, when the drawer is closed, the scrollbar reappears, allowing for scrolling.

To address this concern, the objective is to ensure that the scrollbar remains visible even when the drawer is opened.

Everything operates smoothly when the width is equal to or less than 600px.

To explore the code sandbox, visit this link: code sandbox


const drawerWidth = 240;
const transitionDuration = 1000; //alternative: can also leverage theme.transitions.duration

const useStyles = makeStyles(() => {
  return {
    menuButton: {
      marginRight: (theme) => theme.spacing(2)
    },
    hide: {
      display: "none"
    },
    appBar: {
      zIndex: (theme) => `${theme.zIndex.drawer + 1} !important`
    },
    drawer: {
      width: (theme) => theme.drawerWidth,
      "& .MuiBackdrop-root": {
        display: "none"
      }
    },
    drawerPaper: {
      width: (theme) => theme.drawerWidth,
      backgroundColor: "rgba(120, 120, 120, 0.2)"
    },
    content: {
      padding: (theme) => theme.spacing(3),
      transition: (theme) =>
        theme.transitions.create("margin", {
          easing: theme.transitions.easing.easeOut,
          duration: transitionDuration
        }),
      minWidth: (theme) => theme.drawerWidth,
      marginLeft: (theme) => 0
    },
    contentShift: {
      transition: (theme) =>
        theme.transitions.create("margin", {
          easing: theme.transitions.easing.easeOut,
          duration: transitionDuration
        }),
      minWidth: (theme) => theme.drawerWidth,
      marginLeft: (theme) => theme.drawerWidth
    }
  };
});

export default function App() {
  const theme = useTheme();
  const greaterThan375 = useMediaQuery("(min-width:600px)");
  theme.drawerWidth = greaterThan375 ? drawerWidth : "100%";
  const classes = useStyles(theme);
  const [open, setOpen] = React.useState(greaterThan375);

  useEffect(() => {
    setOpen(greaterThan375);
  }, [greaterThan375]);

  const handleMenuClick = () => {
    setOpen(!open);
  };

  return (
    <div>
      {/*fixed is default */}
      <AppBar position="fixed" className={classes.appBar}>
        <Toolbar>
          <IconButton //hide on desktop
            color="inherit"
            onClick={handleMenuClick}
            edge="start"
            className={clsx(classes.menuButton, greaterThan375 && classes.hide)}
          >
            <MenuIcon />
          </IconButton>
          <Typography variant="h6" noWrap>
            Responsive Drawer
          </Typography>
        </Toolbar>
      </AppBar>
      <Drawer
        //add full width for responsive
        className={classes.drawer}
        variant="temporary"
        //elevation={3} only works with variant="temporary"
        open={open}
        transitionDuration={{
          enter: transitionDuration,
          exit: transitionDuration
        }}
        classes={{
          paper: classes.drawerPaper
        }}
        PaperProps={{ elevation: 9 }}
      >
        <Toolbar />
        <div>
          <List>
            {["Home", "Page 1", "Page 2", "Page 3"].map((text, index) => (
              <ListItem button key={text}>
                <ListItemIcon>
                  <AppsIcon />
                </ListItemIcon>
                <ListItemText primary={text} />
              </ListItem>
            ))}
          </List>
        </div>
      </Drawer>
      <main className={clsx(classes.content, { [classes.contentShift]: open })}>
        <Toolbar />
        <Typography>
          Dummy text for demonstration purposes.
        </Typography>
      </main>
    </div>
  );
}


Answer №1

Underneath the surface, the Drawer component utilizes a Modal. Within the Drawer component, there is a property called ModalProps where you can specify additional props for the Modal. To prevent scrolling locking in this scenario, make sure to set the disableScrollLock flag on the Modal.

      <Drawer
        // ...
        ModalProps={{ disableScrollLock: true }}
      >
        // ...
      </Drawer>

Answer №2

The issue was resolved by switching the drawers variant from temporary to persistent.

<Drawer
      //add full width for responsive
        className={classes.drawer}
        variant="persistent"
        //elevation={3} only works with variant="temporary"
        open={open}
        transitionDuration={{
          enter: transitionDuration,
          exit: transitionDuration
        }}
        classes={{
          paper: classes.drawerPaper
        }}
        // PaperProps={{ elevation: 9 }}
      >
        <Toolbar/>
        <div>
          <List>
            {["Home", "Page 1", "Page 2", "Page 3"].map((text, index) => (
              <ListItem button key={text}>
                <ListItemIcon>
                  <AppsIcon />
                </ListItemIcon>
                <ListItemText primary={text} />
              </ListItem>
            ))}
          </List>
        </div>
      </Drawer>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

TranslateY animation glitching

I need help with expanding a box to 100% height after click, then collapsing and sticking to the bottom. I created a function in Vue framework to handle the animation, but it's not working smoothly. How can I make it less buggy? Check out the demo her ...

Using an express server in conjunction with webpack-dev-server for production environments

I am currently in the process of developing an application using React that communicates with an API hosted on a separate backend. In my server.js file, I have set up express to listen on one port for WebpackDevServer, and another port to serve a basic i ...

Is there a way to position an X item on the first row and another X item on the following row using flexbox?

I want to use flexbox to arrange 10 buttons in a row on a large screen. On a medium screen, I'd like 5 buttons on the first row and 5 on the second row. For small screens, 2 buttons per row, and for very small screens, one button per row. It's im ...

Combining various arbitrary values, like :has in Tailwind, can be achieved by following these steps

I'm facing an issue where I need to hide an element if it has children. In regular CSS, this is achieved with the following code: &:not(:has(*)){ display: none } However, when trying to implement this in Tailwind, I'm struggling to figure ...

Creating an AJAX URL in an external JavaScript file within a Django project

How can I verify if a student user's email exists in the database using keyup event in a registration form, and prevent form submission if the email is already registered? Below are the relevant files for achieving this: urls.py urlpatterns = [ ...

Steps to eliminate pre-chosen alternatives upon loading select control?

When using react-select with pre-selected options and multiple select enabled, the issue arises where clicking on the Select box still displays the already pre-selected options. How can I remove these duplicate options from the list? Below is a snippet of ...

Is it possible to retrieve state within a createAsyncThunk function that uses axios with Redux Toolkit?

Trying to get to grips with redux toolkit, I've hit a snag. In the snippet below, I'm attempting to access state (loginDetails.username and loginDetails.password) within my createAsyncThunk. It seems like I'm missing something - I've e ...

Ensure all <li> tags within a HTML document exhibit consistent jquery mousedown and hover effects, abstaining from the assignment of unique IDs to each

I understand that this approach might not be correct, but I wanted to create a simulation of what I am trying to achieve. Is there a way for each <li> element within a specific <ul class="myul"> to have separate mousedown, mouseout, hover effe ...

What is the process for filtering out a particular version of an npm package?

Here is my current configuration: "@vue/test-utils": "^1.0.0-beta.25" Can anyone recommend a way to exclude a particular version of this package while still using the caret ^ notation? I specifically need to exclude version 1.0.0-beta.31 as it has cause ...

Questions regarding the navigation bar

I am currently working on designing a navigation bar featuring a dropdown menu. I envision HOME, FIXTURES, RESULTS, LEADERBOARD all appearing on the same line. Specifically, I would like UPCOMING WEEK, MONTHS to be the dropdown children of FIXTURES, and G ...

Hover over the image to trigger animation effects

Looking for a way to enhance my current jQuery script that creates an orange transparent hover effect over images. How can I add animations, specifically a fade in and out effect? $(document).ready(function() { $('#gallery a').bind('mo ...

a method for inserting a space after a certain character, with the exception of when that character is located at the start or end of a line

I've created a regular expression that can modify various patterns like: anything1 * anything2* anything3 anything1* anything2 * anything3 anything1 * anything2 * anything3 anything1*anything2 *anything3 anything1 * anything2 *anything3 anything1*any ...

Is it possible to utilize the useRef Hook for the purpose of storing and accessing previous state values?

If you have already implemented the useState and useEffect Hooks for maintaining previous state, another approach is to utilize the useRef Hook to track previous state values as well. ...

Generating hierarchical structures from div elements

Looking for guidance on how to parse a HTML page like the one below and create a hierarchical Javascript object or JSON. Any assistance would be much appreciated. <div class="t"> <div> <div class="c"> <input t ...

Sending data with React using POST request

Currently in my React application, I have a form that includes fields for username and password (with plans to add "confirm password" as well). When submitting the form, I need it to send JSON data containing the email and password in its body. The passwo ...

Empty value for $_POST variable following xmlhttp request

When my code makes an xmlhttp request to a php file with an ID for record deletion from the database, I encounter an issue. The error message 'comicID' is undefined shows up when attempting to delete. This signifies that the variable containing t ...

What is the correct way to invoke a function from the reducer/actions within this specific scenario?

There seems to be an issue with the action/reducer I am attempting to call. It appears that the function is not being read correctly when called. The problem lies within the deleteWorkout function. I've attempted to use mapDispatchToProps and have al ...

What are some tactics for avoiding movement in the presence of a border setting?

I created a webpage that has the following structure: .topbar-container { width: 100%; position: fixed; top: 0; background-color: #2d3e50; z-index: 999; display: flex; transition: height 500ms; } @media (min-width: 992px) { .topbar-cont ...

Collection of categories within the drop-down menu

I'm currently utilizing Twitter Bootstrap and would like to create a collection of concealed fields within a dropdown menu: <li class="dropdown"> <a class="dropdown-toggle" data-toggle="dropdown" href="#"> Export <b class="ca ...

JavaScript - Retrieve events from an element and assign them to a keyboard button

I am currently curious about the following scenario: Suppose I have an element with a particular event. For example, when this element is clicked, it triggers alert('clicked); Now, my question is: Is there a way to capture the events of this element ...