Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Modal] Scrollbar and padding issue #10000

Closed
lorensr opened this issue Jan 23, 2018 · 53 comments
Closed

[Modal] Scrollbar and padding issue #10000

lorensr opened this issue Jan 23, 2018 · 53 comments
Labels
bug 🐛 Something doesn't work component: modal This is the name of the generic UI component, not the React module!

Comments

@lorensr
Copy link
Contributor

lorensr commented Jan 23, 2018

When a Menu opens, the page's scrollbar disappears. This may affect page layout. In my case, it jumps everything over to the right, which is a visual bug.

Solution

Either A) fix this in the library, or B) Note this behavior in the docs, and provide ways of solving it:

https://material-ui.com/demos/menus/

The container for the things jumping is absolute, left: 0, right: 0, with sections that are either text-align: center or display: flex; flex-direction: column; align-items: center;

Your Environment

Tech Version
Material-UI 1.0.0-beta.29

Related issues

These are all closed, and I didn't find the solution in them:

#8475 #7431 #6656 #8710

@oliviertassinari oliviertassinari added the component: Popover The React component. label Jan 23, 2018
@oliviertassinari
Copy link
Member

oliviertassinari commented Jan 23, 2018

In my case, it jumps everything over to the right, which is a visual bug.

@lorensr Do you have a reproduction example? It's a well-known limitation of disabling the scrollbar. We handle absolute positioned elements that have the .mui-fixed class name.
We need to document it!

@pelotom
Copy link
Member

pelotom commented Jan 23, 2018

FYI, another thing I've found is that the .mui-fixed fix only works if your fixed element also has

box-sizing: content-box;

@lorensr
Copy link
Contributor Author

lorensr commented Jan 25, 2018

Thanks, adding the class worked. I didn't need content-box. The element is border-box.

It should also be noted that when the scroll bar is removed, the block header inside my right: 0 element didn't stretch to the right edge of the browser.

image

Fixed by changing right: -20px, so now css is:

main {
  position: absolute;
  box-sizing: border-box;
  left: 0;
  right: -20px;
  overflow-x: hidden;
}

The downside is that when the scrollbar is present, centered children are now 10 pixels to the right of center, and I have to hide overflow.

@abhishiv
Copy link

In some cases it's not possible to apply the mui-fixed css class to some fixed elements. For example the crisp chat widget at the bottom of my page. Probably happens with intercom widget as well.

Does anyone else have the same problem and found a solution?
localhost_4000

@oliviertassinari oliviertassinari added the bug 🐛 Something doesn't work label Apr 9, 2018
@oliviertassinari oliviertassinari added component: modal This is the name of the generic UI component, not the React module! and removed component: Popover The React component. labels Apr 9, 2018
@oliviertassinari oliviertassinari changed the title [Menu] Scrollbar disappears on open [Modal] Scrollbar and padding issue Apr 9, 2018
@michielglibert
Copy link

I had a similar issue, but the container was not absolute. What fixed it for me was adding !important to my padding like this:

padding: 0 !important;

@chrisshaddad
Copy link

chrisshaddad commented Jul 10, 2018

I'm not 100% sure if this is the correct way to do it but i added the following css properties to the <body> tag

body { 
    position: absolute;
    left: -17px;
    right: -17px;
    padding-top: 0;
    padding-right: 17px;
    padding-left: 17px;
    padding-bottom: 0px;
    overflow-x: hidden;
    overflow-y: auto !important  //Remove the !important if you want the scroll bar to disappear
}

@cvocke
Copy link

cvocke commented Jul 16, 2018

Hopefully this helps someone else:

After trying some various css overrides that seemed to work but felt wrong, such as @chrisshaddad's, I found we were getting shifting due to previously forcing overflow-y: scroll on our whole app. We had forced the y-axis scrollbar app-wide to prevent shifting due to our pages having varying lengths - some requiring y-axis scrolling, some not.

Instead of placing a bunch of extra body or inline styling, we were able to fix the shifting by isolating the overflow-y: scroll to the content below our fixed AppBar/Header. Now we have an evergreen scrollbar for the page content, rather than the whole window, along with no shifting from modals/menus since the scrollbar is attached to the page content and not the body.

For reference our DOM looks like:

<div>
  <Header />
  <div className="pageContent">
    <div className="page">
      <Route exact path="/pathToPage"> component={PageContent} />
    </div>
  </div>
</div>

and the CSS (our header's height is 45px):

.pageContent {
  position: absolute;
  top: 45px;
  left: 0;
  right: 0;
  bottom: 0;
}
.pageContent .page {
  height: 100%;
  overflow-y: scroll;
}

@jasontrigg0 jasontrigg0 mentioned this issue Aug 2, 2018
2 tasks
@rememberYou
Copy link

rememberYou commented Sep 8, 2018

Hello,

I currently have this same problem and I must admit that I cannot find my happiness in any of the solutions mentioned.

From what I understood, Modal does not allow to use the scrollbar, which is problematic because I use a Modal to perform an advanced search and a Modal doesn't always need to have a short content.

Thinking about the problem and the solutions you mentioned, I was wondering why it would not be possible for Material-UI to implement a scrollable property for everything related to Modal, Dialog, Menu and other popup elements. By default, this boolean property would be false, but could be true to allow a scrollbar to be displayed in the component.

If this is not possible, maybe implement a ScrollBar component outright, even if I prefer the idea before.

I suspect that this is easier said than done. I would therefore like to thank you for the exceptional work you are doing.

@avdd
Copy link

avdd commented Sep 9, 2018

FWIW I just set a global body { overflow-y: scroll } and everything seems to work nicely.

@rememberYou
Copy link

@avdd This does not help since it will allow you to scroll in the body and not in the modal.

@oliviertassinari
Copy link
Member

@rememberYou The modal is a low level primitive, you might want to use the dialog instead: https://material-ui.com/demos/dialogs/#scrolling-long-content.

@avdd
Copy link

avdd commented Sep 9, 2018

@rememberYou ModalManager sets overflow:hidden directly on the container element (body) when the modal is visible and resets it when the modal is finished, so, yes it does work for me.

https://github.com/mui-org/material-ui/blob/7d4aeaf4c9cdf00a9c7eb41bd9bb7cac61840739/packages/material-ui/src/Modal/ModalManager.js#L24

@rememberYou
Copy link

rememberYou commented Sep 9, 2018

@oliviertassinari thank you for the solution.
@avdd my apologies, I didn't try with the ModalManager.

@nathanmarks
Copy link
Member

@lorensr Is this still an issue?

@rememberYou
Copy link

@oliviertassinari One last thing, I tried with the Dialog, it works well, but since I want a more particular design, I like to use the Modals.

The issue is that I have a Modal (Login) that has a link to open a second Modal (SignUp) that itself has a link to return to the Login.

In this case, do I have to use the ModalManager to easily add and remove a Modal? Sorry to get out of the subject of the issue, I didn't find any documentation on the subject.

@lorensr
Copy link
Contributor Author

lorensr commented Sep 10, 2018

@nathanmarks yes, looks like modal components docs pages still don't mention .mui-fixed

@stephen099
Copy link

stephen099 commented Nov 14, 2018

Using 3.5.1 - the Dialog shifts to the left before closing.

Reproducible here https://material-ui.com/demos/dialogs/ - open and close the Simple Dialog demo.

After testing, this started in v3.3.

@oliviertassinari
Copy link
Member

@stephen099 Thank you for reporting! I confirm, but it's a different issue.

@vajnorcan
Copy link

I've noticed that on the header (with the latest mui), the mui-fixed is added to the class names, but there is no styling assigned to it (by inspecting the header, there is no mui-fixed rule loaded.

I'm wondering, why is this 'add padding' happening in the first place, why is it needed? For me it's broken by the Menu component.

How do I prevent this from happening without having to override the css styling with !important ... ? Thanks

@WholemealDrop
Copy link

I'm witnessing this in use of Select components as well. Whenever a Select dropdown is opened, overflow: hidden, padding-right: 15px is added to the main body tag of my app. Is there a solution this besides overriding styles? I feel like this isn't expected behavior

@oliviertassinari
Copy link
Member

@WholemealDrop Follow #17353.

@WholemealDrop
Copy link

@oliviertassinari ahah apparently my search skills aren't that great. Thank you!

@archfz
Copy link

archfz commented Dec 18, 2019

@oliviertassinari I have managed to reduce the problem to the core. The issue seems to be that somehow there is incorrect calculations when display: flex + minHeight: 100vh + body no padding and margin is combined. It seems like that the code expects to be a scrollbar there but in fact there is not. This code should reproduce the issue.

import React, {FunctionComponent, SyntheticEvent, useState} from 'react';
import {IconButton, Menu, MenuItem, Tooltip} from "@material-ui/core";
import TranslateIcon from "@material-ui/icons/Translate";
import MuiAppBar from "@material-ui/core/AppBar";
import Toolbar from "@material-ui/core/Toolbar";

const AdminAppContainer: FunctionComponent = () => {
  const handleMenu = (event: SyntheticEvent) => setAnchorEl(event.currentTarget);
  const [anchorEl, setAnchorEl] = useState<Element | null>(null);
  const open = Boolean(anchorEl);
  const handleClose = () => setAnchorEl(null);

  const body = document.getElementsByTagName('body')[0];
  body.style.margin = "0";
  body.style.padding = "0";

  return (
    <div style={{ display: 'flex', minHeight: '100vh'}}>
    <MuiAppBar color="secondary" >
      <Toolbar>
        <div style={{flex: 1}}></div>
        <div>
          <Tooltip title='asd'>
            <IconButton onClick={handleMenu}><TranslateIcon /></IconButton>
          </Tooltip>
          <Menu anchorEl={anchorEl} open={open} onClose={handleClose}>
            <MenuItem key={'test'} onClick={handleClose}>Test</MenuItem>
          </Menu>
        </div>
      </Toolbar>
    </MuiAppBar>
    </div>
  )
};

@mbrookes
Copy link
Member

@archfz Could you create a codesandbox please? (You could start with one of the docs examples.)

@mbrookes
Copy link
Member

mbrookes commented Jan 8, 2020

@archfz Sorry, missed this.

What am I looking for here? I don't experience any layout changes.

@WholemealDrop
Copy link

@archfz Sorry, missed this.

What am I looking for here? I don't experience any layout changes.

When you click on the character in the top right, it moves to the left when the menu item opens and then moves back to the right when the menu item closes.

@oliviertassinari
Copy link
Member

Could you open a new issue? It seems something new.

@oliviertassinari
Copy link
Member

@archfz Ok, it's a conflict with the tooltip. Let's ignore it.

@archfz
Copy link

archfz commented Jan 12, 2020

@oliviertassinari Well we should not ignore it cause it's a real issue. React-admin uses material UI and it actually is an issue out of the box. I have created an issue here #19203

@samheyman
Copy link

samheyman commented Mar 1, 2020

The solution re-iterated by @Toshiuk is to simply add the following:

  • Menu, StyledMenu:
    disableScrollLock={ true }

  • Select:
    MenuProps={{ disableScrollLock: true }}

We really need to make solutions more easily findable! :-)

@Risbot

This comment has been minimized.

@mui mui locked as resolved and limited conversation to collaborators Mar 9, 2020
@mui mui unlocked this conversation Mar 9, 2020
@sandunr
Copy link

sandunr commented Apr 11, 2020

just add the following css
body { padding-right: 0px !important; }

@Vincent-Alibert
Copy link

Vincent-Alibert commented Apr 22, 2020

hello, in my app i use this solution.
I add disableScrollLock={true} disablePortal={true} id="custom" on my component <Menu> and in my css
#custom { .MuiPopover-paper, .MuiPopover-paper { max-height: inherit !important; } }
this work perfectly in my case. I hope this tricks can help.

@fastlogin
Copy link

I experienced the same problems working with Dialogs. The following is the only solution that I have tried that both removes the shifting of content and still locks the scroll of the underlying page/removes its scrollbar.

Solution:
Go to the outermost container div or any outermost div (any container that encapsulates your entire app) in your app and set its width to this:

width: calc(100vw - 1px);

1px can be substituted with 34px or any other low value. This will make it so that opening a Dialog will hide the scroll bar of the underlying page, if present, and will not create any sort of shift in the position of the content. Scrolling is still locked for the underlying page and scrolling is still possible for your dialog.

@cy-sachin-m
Copy link

disableScrollLock={ true }

You are just brilliant, Thank you

@artyom-88
Copy link

I had a similar issue, but the container was not absolute. What fixed it for me was adding !important to my padding like this:

padding: 0 !important;

How did you fixed content jump on menu open?

@artyom-88
Copy link

artyom-88 commented Dec 14, 2020

The solution re-iterated by @Toshiuk is to simply add the following:

  • Menu, StyledMenu:
    disableScrollLock={ true }
  • Select:
    MenuProps={{ disableScrollLock: true }}

We really need to make solutions more easily findable! :-)

It's a bad solution, because it disables scroll lock when dropdown menu is open. If you click on selector and scroll, the dropdown menu won't hide.

image
https://codesandbox.io/s/suspicious-wozniak-847u9

@onpaws
Copy link
Contributor

onpaws commented Apr 14, 2021

Wanted to post the solution that worked best for us in case it helps someone else too.
In our case we had some CSS on the body element causing behavior similar to what's described here.

body { 
...
overflow-y: auto;
}

overflow-y was causing the page to shift when s were visible, ostensibly b/c of the scroll lock behavior. First we tried disableScrollLock which worked, but of course then users could scroll. So in the end removing the style from body let us keep the default scroll lock behavior, which is probably better in the end, and no page shifting.

@dalalRohit
Copy link

The way I fixed it was just add disableScrollLock={ true } in my component :)

Thank you so much for this!

@RyanAquino
Copy link

The way I fixed it was just add disableScrollLock={ true } in my component :)

Thank you !, verified working on React Material UI v4

@oliviertassinari
Copy link
Member

I believe that we have move the discussion on this issue to #17353.

@mui mui locked as resolved and limited conversation to collaborators Sep 21, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug 🐛 Something doesn't work component: modal This is the name of the generic UI component, not the React module!
Projects
None yet
Development

No branches or pull requests