Material: mdContent: Disable overflow when mdSideNav is open

Created on 24 Feb 2015  Â·  19Comments  Â·  Source: angular/material

Is there a way to disable mdContent's overflow when mdSideNav is open or is there a proper structure for mdContent to disable overflow when mdSideNav is open?
screenshot from 2015-02-24 16 21 29
_Angular Material v0.8.0_

fixed

Most helpful comment

i had same issue, I temporarily solved it by adding this in my css

md-sidenav, md-backdrop {
position: fixed !important;
}

hopefully developers will solve it soon.

All 19 comments

Here's my codepen.
When you click the button and then scroll down you can see that sideNav also scrolls down. Is there any way to disable it?

i had same issue, I temporarily solved it by adding this in my css

md-sidenav, md-backdrop {
position: fixed !important;
}

hopefully developers will solve it soon.

@milanart Can you provide codepen or plunkr for your example? I badly need the structure. Thanks in advance.

i've added just css, http://codepen.io/anon/pen/NPzxwK

desktop user still be able to scroll the main contents using browser's scroll bar.
I'm partially also able to fix that scrolling by adding css overflow:hidden using some angular code. but its not firing up as expected. I'm working on it. will update with new codepen once i'm succeeded.

please check this, http://plnkr.co/edit/oOcUfHZUteamozhTvije?p=preview

I tried to use $rootScope.isOpen= !$mdSidenav('left').isOpen(); this can make isOpen = true. but problem is, I cant figure out how to make isOpen = false; after sidenav is closed again.
any inputs?

@milanart Great! Thanks a lot. Anyway. You just have to change 'left' to 'menu'.

actually, i just added that line from my local project, where i'm testing. but it wont work even if its changed the menu handler.

anyways, i got a new fix http://codepen.io/anon/pen/QwxvxM using css only. when clicked menu-toggle, the md-content will scrolled to top.

added following css in previous version.

md-backdrop ~ md-content {
position: fixed;
overflow: hidden;
}

@mateeyow
found permanent solution. in angular-material.js file, just below

$animate[isOpen ? 'enter' : 'leave'](backdrop, parent),

add following line.

        $animate[isOpen ? 'addClass' : 'removeClass']($document.find('body'),'itsOpen'),

the code should look something like,

return promise = $q.all([
        $animate[isOpen ? 'enter' : 'leave'](backdrop, parent),
        $animate[isOpen ? 'addClass' : 'removeClass']($document.find('body'),'itsOpen'),
        $animate[isOpen ? 'removeClass' : 'addClass'](element, 'md-closed').then(function() {
          // If we opened, and haven't closed again before the animation finished

          if (scope.isOpen) {
            element.focus();
          }
        })
      ]);

add this css line,

.itsOpen{
  overflow: hidden;
}

you can remove all other css fixes applied earlier.

btw, there is option of disableParentScroll in buttonsheet.
https://material.angularjs.org/#/api/material.components.bottomSheet/service/$mdBottomSheet

there should be similar option for sidenav aswell.

@milanart I don't think It's a good idea to tweak your angular-material copy. If you find this as an excellent solution I think you should open a merge request to the repository. The css workaround is great already. :+1:

But let's just keep this issue open. :)

@mateeyow Yes, even i do not prefer this way of fixing problems. But the css fix was causing a problem. when user is in between the page and clicks toggle button, it takes user to top of page because of position:fixed property. which leads to bad user experience.

@milanart Yes, I've also noticed that, maybe you should open an issue concerning that matter.

Here is an updated demo that shows how disableParentScroll fixes the issue(s):
http://codepen.io/ThomasBurleson/pen/MYPvqM

Notice that the sideNav.parent is height:100%

Don't know. When you wrap your navigation into a div thats not working. Maybe its better to set the overflow property on the body/window instead?

@johannesjo That's what I ended up doing. In the html file that opens the sidenav:

<md-content>
    <!-- your overflowing content here -->
</md-content>

Then, in your template's controller:

    //This sets up a trigger event when the sidenav closes
    $scope.sideNavIsOpen = function() {
        return false;  
    };

    $mdComponentRegistry.when('right').then(function(sideNav) {
        $scope.sideNavIsOpen = angular.bind(sideNav, sideNav.isOpen); 
    });

    $scope.$watch('sideNavIsOpen()', function() {
        if(!$scope.sideNavIsOpen()) {
            $('body').removeClass('not-scrollable');

            console.log('closed');
        }
        else {
            $('body').addClass('not-scrollable');
            console.log('open');
        }
    });    

And define the css class like so:

.not-scrollable {
    overflow-y: hidden;
}

This way, you don't scroll on the out of focus content, only on the sidenav's content. The sidenav can have its own controller if you want, just make sure to put this in the parent template's controller. Hope this helped :)

@lscordilis this works for me but isn't there a better solution?

@Jdruwe Not that I'm aware of. There's probably an angular way to do it, but instead of complicating my code with a directive, I just decided to go the jQuery route. Besides, right now, using the $mdComponentRegistry to assign events to opening and closing a sideNav is considered the best practice.

https://github.com/angular/material/issues/974

But keep in mind this, I don't know if it's been fixed yet: https://github.com/angular/material/issues/4143

I fixed it using ng-class.
On Oct 19, 2015 16:37, "lscordilis" [email protected] wrote:

@Jdruwe https://github.com/Jdruwe Not that I'm aware of. There's
probably an angular way to do it, but instead of complicating my code with
a directive, I just decided to go the jQuery route.

—
Reply to this email directly or view it on GitHub
https://github.com/angular/material/issues/1637#issuecomment-149234129.

Thanks for all the tips everyone!
I also had a similar issue (https://github.com/angular/material/issues/8369) ,
and my final working solution is a combination of the advice above (using ng-class),
but I also wanted to warn people with responsive UI, that sideNav.isOpen is "broken" if you use md-is-locked-open.

E.g., my side nav is:

<md-sidenav md-component-id="left" md-is-locked-open="$mdMedia('gt-xs')">

So the final working solution for me is:

CSS:

.overflow-y-scroll {
  -webkit-overflow-scrolling: touch;
  overflow-y: scroll;
}
.not-scrollable {
  overflow-y: hidden;
}

JS (TypeScript actually):

$rootScope.sideNavIsOpen = () => false; // overridden later.
// I use $mdComponentRegistry due to: https://github.com/angular/material/issues/8308#issuecomment-216641458
$mdComponentRegistry.when('left').then(function(sideNav: any) {
$rootScope.sideNavIsOpen = () => sideNav.isOpen() &&
// When gt-xs, then the sideNav is always open (and sideNav.isOpen may return true/false regardless).
!$mdMedia('gt-xs');
});

HTML:

<md-content flex ng-class="sideNavIsOpen() ? 'not-scrollable' : 'overflow-y-scroll'">

For me the solution was to update the css with this

md-sidenav, md-backdrop {
  position: fixed;
}
.isOpen {
  overflow:hidden
} 
Was this page helpful?
0 / 5 - 0 ratings

Related issues

LeoLozes picture LeoLozes  Â·  3Comments

Dona278 picture Dona278  Â·  3Comments

ghost picture ghost  Â·  3Comments

reggiepangilinan picture reggiepangilinan  Â·  3Comments

robertmesserle picture robertmesserle  Â·  3Comments