bootstrap icon indicating copy to clipboard operation
bootstrap copied to clipboard

offcanvas isn't scrollable

Open kfirba opened this issue 9 years ago • 21 comments

Hey.

For some reason the offcanvas isn't scrollable on phones. I tried both iPhones and androids (LG and samsung) and the offcanvas, once exceeded the 100% height isn't scrollable for some reason.

You can see more details in the SO question:

http://stackoverflow.com/questions/33787983/jasny-bootstrap-offcanvas-doesnt-scroll-on-phones

kfirba avatar Nov 18 '15 19:11 kfirba

I'm also having this issue and not able to solve it. all the solutions found in github and stackovrflow don't work. most point to having to refer to the last version to sort this out. has there been a solution yet?

mohamedhamad avatar Dec 14 '15 16:12 mohamedhamad

I found this only happens on smaller phone sizes (not iphone 6 for example). I believe it can be fixed by adding data-placement="left" (for a navmenu-fixed-left), at least with this it works in all my test devices.

Edit: This does not fix the issue.

rhein avatar Jan 05 '16 16:01 rhein

This workaround does not work for me. I checked your website, and it doesnt work there either. I was able to get scrolling to work once when its first opened by hacking the css and a small javascript event. But the second time its opened scrolling is frozen again. :disappointed:

mgwidmann avatar Jan 14 '16 22:01 mgwidmann

Completely agree, checked it myself and it is not working. Sorry for this, but I did have it scrolling for sure. Must have been something in addition to the data-placement, digging trough my commits right now to find it. Edited my previous answer to reflect this as not_working.

rhein avatar Jan 14 '16 22:01 rhein

@rhein bah.. doesn't work :x nice try tho.

@jasny Why look for a workaround and don't just solve the problem :)?

kfirba avatar Jan 14 '16 22:01 kfirba

ok, I got it (kind of) working again. You also have to set data-disableScrolling="false" AND use the not-minified js file. This might be a completely different issue, but take a look at the comments at a freshly downloaded js: the minified version says 3.1.0, while the not-minified version says 3.1.3.

Anyways now the menu does scroll, the only downside is that the body also scrolls. But that is not a big issue for me. The relevant part is line 159 of the not-minified js, this seems to break scrolling not only on the body but on all other elements as well.

@kfirba @mgwidmann Please let me know if this works for you as well.

rhein avatar Jan 15 '16 00:01 rhein

@rhein Hey.

I've added that code to my button:

 <button type="button" class="navbar-toggle collapsed" data-toggle="offcanvas" data-target=".navmenu" data-placement="right" data-disableScrolling="false">
            <span class="sr-only">Toggle navigation</span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
            </button>

And I'm also using the sass version and concatenate some css files with gulp. It still doesn't work.

I've dug into the code and found that if I set the disableScrolling option to false it works.

If I also manually call

$('body').off('touchmove.bs');

It works. The downside now is that EVERYTHING is scrolling. The body and the nav-menu which is annoying. I've tried to play with it to only get the side-menu scrolling but I couldn't.

kfirba avatar Jan 15 '16 07:01 kfirba

@kfirba Yes, this is pretty much what I did. The downside is ok for me, as at least on iOS devices body and nav-menu are scrolling independently, so it is not too much of an annoyance and the menu is actually usable.

Just as a sidenote: I have tried wrapping all the page content in an extra div and change the js into something like this:

$('#content').on('touchmove.bs', function(e) {
    e.preventDefault();
});

in order to prevent the scrolling, but that does not work.

I guess we have to live with this for now until somebody comes up with a clever idea on how to prevent scrolling on touch devices.

rhein avatar Jan 15 '16 09:01 rhein

@rhein I see. When adding the properties on the button it didn't work so I had to invoke a JS function manually.

kfirba avatar Jan 15 '16 09:01 kfirba

Yes, looks like setting the properties via data-attributes does not work. So, to sum it up for others:

  1. Use the not-minified js (maybe minify it yourself later)
  2. Change the JS (from line 46) to read like this:
OffCanvas.DEFAULTS = {
toggle: true,
placement: 'auto',
autohide: true,
recalc: true,
disableScrolling: false,
modal: false
}

The important part here is disableScrolling: false,

Alternative

Call

$('body').off('touchmove.bs');

right after invoking the nav-menu. This should re-enable scrolling for both the nav-menu and the body.

The Downside: it might be annoying to have the body scrolling as well.

@kfirba Do you think this sums it up correctly?

rhein avatar Jan 15 '16 09:01 rhein

@rhein Unfortunately, yup. :)

kfirba avatar Jan 15 '16 09:01 kfirba

Yeah, disable scrolling works as in it allows the side menu to scroll. However, the body being scrollable was not acceptable for us. We had to roll back the version to get things to work again, through a combination of that and some css hacks things are working for us. This definitely needs to work out of the box though or this component is useless.

mgwidmann avatar Jan 15 '16 15:01 mgwidmann

@mgwidmann Do you mind sharing your solution?

rhein avatar Jan 15 '16 15:01 rhein

@mgwidmann I would be great if you could share your solution or even send in a pull request. Thanks!

jasny avatar Jan 15 '16 16:01 jasny

I can't share the codebase, but I can show you the relevant code that got this to work for me. Hopefully you can find a better solution because mine involves setting some CSS which is kind of hacky.

SCSS:

// This is our main div that surrounds all content, but not the nav
#main.nav-open {
  position: fixed;
  left: $navmenu-width;
  overflow: hidden;
  height: 100%;
}

And we add that class with

$('#navmenu').on('shown.bs.offcanvas hidden.bs.offcanvas', function(){
    $('#main').toggleClass('nav-open');
  });

mgwidmann avatar Jan 15 '16 16:01 mgwidmann

@mgwidmann thank you, it helped So what I did

  1. set disableScrolling to false
  2. wrapped all the conent except nav in a div with class="prevent-scrolling"
  3. added this css body.canvas-slid .prevent-scrolling {position: fixed; right: 235px; left: -235px; overflow: hidden; height: 100%;} Where 235px is the width of my offcanvas

640miles avatar Feb 29 '16 14:02 640miles

I have experienced the same issue. The way I "solved" it, is using this: $('body').off('touchmove.bs'); when the navbar toggle is being clicked. It's not the best way, but it's something

walter220 avatar Aug 22 '16 13:08 walter220

This seems to be working for me:

        $(".offcanvas").on("show.bs.offcanvas", function () {
            $("body").css("overflow", "hidden");
            $("body").on("touchmove.bs", function (e) {
                if (!$(e.target).closest(".offcanvas")) {
                    e.preventDefault();
                    e.stopPropagation();
                }
            });

        });

        $(".offcanvas").on("hidden.bs.offcanvas", function () {
            $("body").css("overflow", "auto");
            $("body").off("touchmove.bs");
        });

On the show.bs.offcanvas event, I am stopping scrolling on the entire body EXCEPT for elements that are children of an element with the "offcanvas" class. Then I remove it when the canvas is hidden to re-enable normal scrolling. Lastly, I set the body to overflow: hidden to fix an issue where the page would scroll if the slider was scrolled all the way to the very top or bottom, then scrolled again in the same direction.

This is allowing the content of the panel to scroll while not scrolling the rest of the page.

AdamLyon avatar Oct 07 '16 00:10 AdamLyon

For those interested, I made a PR to fix the issue of data-disablescrolling="false" not working: https://github.com/jasny/bootstrap/pull/503.

nicofrand avatar Jan 17 '17 08:01 nicofrand

This is what worked for me. The 3.1.2 version worked for me for iOS but had problem with desktop browsers and I would get locked scrolling after opening and closing the side menu. So I replaced this line in jasny-bootstrap.js with the version from 3.1.3 . I kept the CSS with the 3.1.2 version. This is important because the changes in the CSS cause this to not work in iOS.

//replace this line
//if ($('body').data('offcanvas-style') === undefined) $('body').data('offcanvas-style', $('body').attr('style'))

//with this line from 3.1.3
     if ($('body').data('offcanvas-style') === undefined) {
          $('body').data('offcanvas-style', $('body').attr('style') || '')
      }

Now scrolling works fine for iOS and Desktop browsers for me.

delay avatar May 19 '17 15:05 delay

offcanvas sets the style of body to overflow : hidden, that is why it is not scrollable, you can simply use document.body.style.overflow = "auto" on click on the button using which you are opening the offcanvas.

akash-hcah avatar Sep 19 '22 19:09 akash-hcah