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

-webkit-overflow-scrolling: touch does not "obey" z-index #14

Open
bridgestew opened this issue Mar 27, 2012 · 34 comments
Open

-webkit-overflow-scrolling: touch does not "obey" z-index #14

bridgestew opened this issue Mar 27, 2012 · 34 comments

Comments

@bridgestew
Copy link

Summary:

-webkit-overflow-scrolling: touch does not "obey" z-index.

Platforms:

iOS5, not sure about other platforms

How to reproduce:

  1. Build a content area and a modal overlay above it using HTML/CSS
  2. View on iPad for the example below. When you attempt to scroll the page, the content behind the modal scrolls. I wouldn't expect this, since attempting to click a link behind a z-index div doesn't work...

Reduced Example:

(Hastily thrown together example. No Media queries applied, so ignore the ugly -- just check out the bug.)
http://jsfiddle.net/cPHMN/48/embedded/result/

Bug Tracker ticket(s):

Workarounds:

@scottjehl
Copy link
Owner

Interesting. This sounds and looks similar to how touch devices vary in their bubbling of scroll events on elements in the page.

Is your scroll region short enough to trigger a scroll? I wonder how it'll behave if it is...

On Mar 27, 2012, at 9:19 PM, bridgestew wrote:

Summary:

-webkit-overflow-scrolling: touch does not "obey" z-index.

Platforms:

iOS5, not sure about other platforms

How to reproduce:

  1. Build a content area and a modal overlay above it using HTML/CSS
  2. View on iPad for the example below. When you attempt to scroll the page, the content behind the modal scrolls. I wouldn't expect this, since attempting to click a link behind a z-index div doesn't work...

Reduced Example:

(Hastily thrown together example. No Media queries applied, so ignore the ugly -- just check out the bug.)
http://jsfiddle.net/cPHMN/48/embedded/result/

Bug Tracker ticket(s):

Workarounds:


Reply to this email directly or view it on GitHub:
#14

@bridgestew
Copy link
Author

I don't understand your question about the scroll region being short enough. :)

@moll
Copy link

moll commented May 6, 2012

One workaround is to apply the same overflow: scroll and -webkit-overflow-scrolling: touch on the layer above it to stop the lower one from getting the events.

@kpuputti
Copy link

I think I ran into the same issue with my custom map component.

I have a large pannable image (with -webkit-overflow-scrolling: touch) and absolutely positioned marker images on top. Sometimes I get one marker to show up, but usually they are hidden no matter what the z-index is.

Any solutions yet for this?

@moll
Copy link

moll commented May 28, 2012

@kpuputti This bug's problem with z-index is only functional — visually the items are correct. You sure the map you've got has a lower z-index than all the markers?

@kpuputti
Copy link

@moll Yes, the z-index on the map is lower than on the markers.

I'm using Overthrow ( http://filamentgroup.github.com/Overthrow/ ) and the map works fine on Android 2.3 & 4.0, WP7, iOS 4.2. Of these platforms, at least Android 4.0 supports the native touch scrolling.

This comment is the only info I've found:
http://mobile.tutsplus.com/tutorials/mobile-web-apps/ios-5-fixed-positioning-and-content-scrolling/comment-page-1/#comment-17477

@kpuputti
Copy link

Oh, I found the solution. My problem seemed to be the same as in this issue:

#8

and the proposed workaround fixed the problem.

@hober
Copy link

hober commented Aug 28, 2012

This is not a bug; -webkit-overflow-scrolling: touch induces a stacking context. Just like if you put opacity: 0.9 or a 3d transform on the element.

@toddparker
Copy link
Collaborator

Thanks for chiming in with this info @hober.

@cstewartgannett
Copy link

@hober How is this not a bug? I have my context layered properly and -webkit-overflow-scrolling: touch on the top most layer. Functionally everything works properly, except that the background scrolls instead of my modal, unless I use the scrollbar to scroll the div (which contains an unavoidable iFrame). Has anyone else found a workaround for this?

@noordawod
Copy link

Hello all,

I am in the same boat here, unfortunately. But I did find a solution to this. Actually only one, for now.

The solution that I've found is to turn off overflow for the DIV underneath (having lesser z-index) using "overflow:hidden". This seems to trick iOS into capturing the touch events on the top-most DIV (having a higher z-index).

The only downside to this trick, however, is once the DIV having the higher z-index is dismissed (using animation or not), and "overflow:auto" or "overflow:scroll" is reapplied to the DIV underneath, a short "flick" is noticed as if the iOS is redrawing that DIV.

If any of you guys or gals found a better solution, it'd be nice to share.

/Noor

@moll
Copy link

moll commented May 12, 2013

@noordawod:

If any of you guys or gals found a better solution, it'd be nice to share.

Well, I consider the workaround I posted a year ago to be a better solution as it doesn't require JavaScript nor changes other elements' styles.

@noordawod
Copy link

@moll

I've seen and checked your proposed solution before. Surely, I had these CSS rules in place since I wanted the top DIV to have a scrollbar, even before I saw your post (it only made sense to me.)

Now, the interesting thing is that although this works when the DIV is displayed without any animation, the solution doesn't work when animating the DIV (for example, making it appear by sliding it from the bottom of the screen to the top, like Safari's Bookmarks panel on the iPhone.)

This must be a bug in iOS's transformations, I am guessing. Not opacity, as @hober suggested, since when I show the DIV instantly without an animation, and set its opacity to 0.9, scrolling still works.

So we're back to the first post by @bridgestew since it doesn't work when the DIV is animated, sadly.

/Noor

@noordawod
Copy link

And like I mentioned before, only setting overflow to hidden on the lower DIV makes the top DIV respond to touch scrolling (when the top DIV has been animated to its position.)

@noordawod
Copy link

Here's more information about a stacking context, introduced by @hober :
http://daneden.me/2012/04/css-transforms-and-z-index/

@thztti
Copy link

thztti commented Sep 2, 2013

@moll your trick works. Thanks!

@tymcdowell
Copy link

I stumbled onto this conversation because I have a similar issue that I have now fixed. I have a menu panel that is absolutely positioned above the main page. I hide/show this panel using an opacity transition. Both this panel and the main page use -webkit-overflow-scrolling:touch. My problem was that when showing the menu the scrolling would not work and instead the main page behind it would scroll. To fix this, I simply removed the -webkit-overflow-scrolling:touch from the menu when hidden and add it back when shown. It seems that the order in which this value is added is very important here. I was surprised to see that there is no flicker when you do this.

Cheers

@sofish
Copy link

sofish commented May 24, 2014

@moll seems not working on ios7

@joeybaker
Copy link

This bug appears to be gone in iOS8.

@iclanzan
Copy link

Still present on iOS 8.1.

@janson
Copy link

janson commented Jan 19, 2015

Like @iclanzan, I can confirm it is still present in iOS 8.1 Here's what I think is the relevant bug report on Webkit Bugzilla

Edit: nope.

My workaround:

.modal {
    overflow-y: scroll;
    -webkit-overflow-scrolling: touch;
}
.content-behind-modal {
    overflow: hidden;
    -webkit-overflow-scrolling: auto;
}

@shi-sergiom
Copy link

@moll your trick did indeed work like a charm, until iOS8 was released.
i could change the -webkit-overflow-scroll: auto; (as mentioned by @jason) but that adds a flicker that I'm not willing to live with.

@robinscholz
Copy link

@noordawod
calling the css as part of the animation queue solved the problem for me.
("div").css("webkit-overflow-scrolling" , "touch");

@manoj30dec
Copy link

Just target IOS device with media query and put overflow:touch; instead of -webkit-overflow-scrolling: touch; that works for me :-)

@ScallyGames
Copy link

ScallyGames commented Jun 6, 2016

Is there any working workaround for this issue? (The workaround from @moll does not work in my case, the one from @noordawod does, however while the short flicker is still acceptable, the repaint causes heavy performance problems which are far from acceptable)

Two things I've noticed (testing with iPhone 5+6 on iOS 9.1 and 9.3.2):
• it only occurs when launching the page/app from the homescreen (pinned app)
• changing the device orientation (portrait -> landscape) after page load fixes the problem and everything works as expected

PS: why are the default bullet points bold and enormously large?

Edit: I was able to reduce my project source to a rather comprehensible MCVE (check out this pen). To see the described behaviour you have to load the full-screen version (full) on a iOS device, save it to your home screen and call it from there. Then touch the yellow bar and try to scroll the list below.

@ScallyGames
Copy link

It seems that this issue (at least in some cases) does not occur when removing

html, body
{
    width: 100%;
    height: 100%;
}

from the CSS.

This is not a suitable solution however, since those declarations are essential for percentage scale values to work.

@gauravksoni
Copy link

-webkit-overflow-scrolling: touch; overcomes z-index . and if we remove it then the scroll flickers. Is there any good solution of it?

@noordawod
Copy link

Yeah, do like I did years ago: ditch hybrid and go native.

@CommanderXL
Copy link

@gauravksoni Well. I choose to change some html structure to meet the demand.Becase of the mechanism of z-index.

@kaankucukx
Copy link

Wow, 5 years topic.

I haven't been to this since yesterday, surprisingly its weird not to face with it.

3 hours of research i come up with, overflow:hidden to outer most div-element. (i can say body) this works with the position:fixed inner element situations.

You should care all your segmented elements stack context transform - z-index properties.

@studentIvan
Copy link

studentIvan commented Feb 16, 2018

workaround by me:

  1. remove position fixed from container and it's parents
  2. block useless touchmove (unimportant)
window.addEventListener('touchmove', (touchEvent) => {
        /** touch scroll block */
        const sBlock = '.rs-infinity-scroll-block';
        const { target } = touchEvent;
        if (target && target.closest && !(target.closest(sBlock))) {
          touchEvent.preventDefault();
        }
      }, false);

@nickjohnson
Copy link

As many of you, I was led to this thread because of a common issue. In some cases our modal would seem locked in iOS Safari, and the body would retain the scroll touch events. From the developer console we could toggle the body's position:fixed style off and on, then the scroll would come back to our modal. This only seems to happen on some sites where our modal is triggered. We assume it must be some js or css library grabbing precedence. So we tried simulating the console method with this hack, using jQuery:

$('body').css('position','').css('position','fixed');

That didn't work, so I set a timeout on the position reset.

$('body').css('position','');
setTimeout(function(){$('body').css('position','fixed');},100);

And that did it for us. Hacky? Yes! But it works well for us. I hope this may help someone else out there. We spent way too much time on this one :(

@shibinvr
Copy link

Any solution for this scrolling issue. actually, I am investigating a solution for this. Issue happen only iPhone X and above. I need to stop scrolling the background part when the mobile menu is open. Its working in Android, iPhone 8...why happen only iPhone X and above I am using -webkit-overflow-scrolling: touch for scrolling in iPhone.

@diachedelic
Copy link

I have been using the execllent body-scroll-lock library as a workaround for this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests