Bug 183870 - [iOS][pointer-events] Fix scrolling on nested pointer-events: auto inside pointer-events: none
Summary: [iOS][pointer-events] Fix scrolling on nested pointer-events: auto inside poi...
Status: REOPENED
Alias: None
Product: WebKit
Classification: Unclassified
Component: CSS (show other bugs)
Version: Safari 11
Hardware: iPhone / iPad iOS 11
: P2 Critical
Assignee: Matthieu Dubet
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2018-03-21 14:36 PDT by jonjohnjohnson
Modified: 2024-03-07 01:30 PST (History)
7 users (show)

See Also:


Attachments
Scroll interactions from child scroller on left side scroller only scrolls ancestor. Unlike the right. (9.91 MB, video/quicktime)
2018-12-03 15:15 PST, jonjohnjohnson
no flags Details
Another test case, that uses :checked pseudo class to show the hack that fixes the in the same scroller. (2.11 KB, text/html)
2018-12-03 16:44 PST, jonjohnjohnson
no flags Details
Simpler testcase (1.57 KB, text/html)
2018-12-03 19:16 PST, Simon Fraser (smfr)
no flags Details
iOS scroll interactions only captured by scroll containers above other scroll containers in z space (2.56 KB, text/html)
2018-12-07 14:31 PST, jonjohnjohnson
no flags Details
Map popover testcase (53.20 KB, text/html)
2024-01-08 01:37 PST, Felix Niklas
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description jonjohnjohnson 2018-03-21 14:36:43 PDT
To start out, I'm sure this is intentional because of the way scrolling is optimized for touch, but I'm wondering if you could offer some way to enable the same behavior that desktop safari and other browsers allow...

If you set 'pointer-events: none' or 'visibility: hidden' on an element that has a scrollport, then on set 'visibility: visible' or 'pointer-events: auto' on it's descendants, most browsers still allow the scrolling to work enabling experiences like this...

Try on safari desktop -> http://jsbin.com/cujesed/1

In the example, you can scroll the white blocks up from the bottom edge of the screen, filling out more of the screen where their scroll container sits, but when the white blocks are scrolled down to the bottom edge, you are still able to scroll the whole red webpage while your pointer is in the area that would scroll the white blocks if they were scrolled up.

Then try on iOS safari, notice you cannot scroll up on the white blocks. On 'touchstart' I am trying to reset the visibility/pointer-events on the scroll container, which is seen when the background changes to grey, but no scrolling is enabled.

In future versions of iOS Safari could we have a way to do this, leveraging 'native scrolling' instead of writing our own javascript based touch interactions to 'polyfill' the lack of scrolling?

Steps to produce...
1. Go to provided link on iOS Safari -> http://jsbin.com/cujesed/1
2. See how white boxes ('app-tray') sit at bottom of screen with styling of pointer-events:none (or visibility:hidden)
3. Descendants of 'app-tray' are styled with pointer-events:auto (or visibility:visible)
4. Notice how you cannot scroll the white boxes ('app-tray').
5. Go to link on desktop safari and see how you can scroll the white boxes into the screen.
Comment 1 Radar WebKit Bug Importer 2018-03-22 10:32:57 PDT
<rdar://problem/38757252>
Comment 2 jonjohnjohnson 2018-11-18 11:01:04 PST
Here's an even more reduced test case showing the bug AND a work around, which makes me think my initial belief of this being intentional in iOS was incorrect:

- https://jsbin.com/talomas/quiet
- https://jsbin.com/talomas/edit?html,css,output


Steps to see the differences in the scrollers:
1. Open test case in iOS https://jsbin.com/talomas/quiet
2. Swipe vertically in the pink areas of both the left and right side of the screen, notice it just scrolls the document/body.
3. Swipe vertically on the right side from the striped area, notice it allows for scrolling of the pink background scroller.
4. Attempt the same vertically scrolling in the left side from the striped area. Nothing will get the pink scroller to scroll. It only passes the scrolling events down to the document/body scroller.

Results:
The left side scroller *should accept vertical scrolling interactions on iOS (and always on macOS, even if sometimes it's bugged between being viewed in an iframe or not?) above its striped background children elements.

Expected Results:
Both left and right side scrollers should allows for vertical scrolling from scrolling interactions (touch/mouse) above their striped background children elements.

There are two vertical scrollers at the top of the screen, with pointer-events removed on themselves, but again, with a child element that re-enables pointer-events. The top half of the scrollers scrollport in both, allows pointer-events to pass through, so scrolling there will just scroll the body element of the document. But if you scroll from above the child elements, with striped backgrounds, you *should be able to scroll both scrollers.

The left side scroller, shows the bug where on iOS (and even sometimes on macOS) you cannot scroll.

The right side scroller has horizontally overflowing and scrollable content, just by adding `overflow-x: scroll` to its 'tray-inner' element, and this in itself seems to be the work around to get iOS safari to recognize vertical scrolling on itself for its parent scroller. You shouldn't need to make an element scrollable in an opposite axis in order for it to actually accept scrolling of its parent scroller, especially since this more or less creates just another problem in a user accidentally scrolling that other axis.

I hope this helps describe the problem more clearly. And if not, I can try to record a video of the differences from macOS and iOS.

cc simon.fraser@apple.com
Comment 3 Simon Fraser (smfr) 2018-12-03 14:16:05 PST
I still find that test case pretty hard to understand. Please use different colors for the "good" and bad" scrolling areas. Words help.

FWIW, Chrome has the same broken behavior for the left-pink-side scrolling. It works in Firefox.
Comment 4 jonjohnjohnson 2018-12-03 15:15:37 PST
Created attachment 356417 [details]
Scroll interactions from child scroller on left side scroller only scrolls ancestor. Unlike the right.
Comment 5 jonjohnjohnson 2018-12-03 15:34:52 PST
I attached a quick video showing vertical touch interactions attempting to scroll vertically from all areas of the original test case, left and right side scrollers with the interaction originating on scroll containers themselves, as well as originating on the striped elements inside the scroll containers, showing the left not working like the right side. That is itself the issue. That they don't behave the same.

The left, only ever "chains" up scrolling the viewport. The right, allows itself to scroll. This is only remedied on the right side scroller by creating a horizontal scroller on that inner element (overflow-x: scroll). This somehow makes it so now the vertical scroller it lives within can actually accept pointer events.

I've updated the case, to highlight the broken behavior with red colors in the left scroller and green colors in the right scroller.

If you inspect the case, you'll see besides color differences, one line of css different for the green/right scroller.

.tray-horz .tray-inner {
overflow-x: scroll;
}

The red/left side scroller should allow itself to be vertically scrolled from an event on the striped element, just as the green/right side scroller. The attached video shows this doesn't happen and is broken in the left.

simon.fraser@apple.com, the original test case I posted here does work in chrome as well as in desktop safari, just not ios safari (http://jsbin.com/cujesed/1), the more isolated case chasing the hack to *fix the broken behavior doesn't work in chrome, like you stated. They seem to have a similar, but slightly different issue: https://bugs.chromium.org/p/chromium/issues/detail?id=909083

Sorry I still have yet to fully grasp a lot of lingo you guys use for the inner-workings of browsers/specs, and though I try to be verbose enough to explain these things, I'm surely both too wordy and not specific enough.
Comment 6 jonjohnjohnson 2018-12-03 15:58:20 PST
Here's another video which shows the bug on desktop Safari.

http://cl.ly/444ac5407c74

Mouse is hovering different areas of each scroller, attempting to vertically scroll in each area.

Green area, scrolls body. Correct.
Red area, scrolls body. Correct.
Green striped area, scrolls green scroll. Correct.
Red striped area, scrolls body. Incorrect.

Again, the only reason the green striped area is working to scroll the green scroller is because it has an element inside it that scrolls horizontally. I'm only showing this "fix" to highlight how I think the left side should behave, if it wasn't bugged.
Comment 7 jonjohnjohnson 2018-12-03 16:44:44 PST
Created attachment 356435 [details]
Another test case, that uses :checked pseudo class to show the hack that fixes the in the same scroller.

Here is another test case, showing the difference of what is expected against what is bugged within the same scroll container. I hope this helps.

This test case is bugged on iOS and desktop safari, though again, it may not be exactly the same bug as blinks, regarding pointer-events and scroll containers, as shown in this issues original test case (https://output.jsbin.com/cujesed/1).
Comment 8 jonjohnjohnson 2018-12-03 16:52:05 PST
One last attempt to try to be even clearer.

When the test case found at https://jsbin.com/talomas/quiet, is accessed within an iframe on safari desktop. Like here https://jsbin.com/talomas/edit?html,css,output, it doesn't exhibit the broken behavior on the left side scroller. Just trying to highlight ways in which it is broken and and ways in which it is not.

And from my original post, I mention use of the visibility property, because any time I attempt its use to replace the pointer-events property (`visibility: hidden` takes the place of `pointer-events: none` and `visibility: visible` takes the place of `pointer-events: auto`) the same exact bug appears.
Comment 9 Simon Fraser (smfr) 2018-12-03 19:16:01 PST
Created attachment 356447 [details]
Simpler testcase

Scrolling in this testcase is pretty bizarre, and I think it's buggy in all browsers. I would expect no browser to allow scrolling of the "This should not be scrollable" div, but if your mouse is over the left side of it, they allow scrolling.
Comment 10 jonjohnjohnson 2018-12-03 19:31:54 PST
simon.fraser@apple.com the attachment 356447 [details] you posted does in fact work as expected for me in Firefox Nightly. Allowing me to scroll the "This should not be scrollable" element from the right hand side as well as the left.

But surely, quite bizarre artifacts you found.

Also, I was under the impression the `all` value for `pointer-events` was solely for SVG, even if behaved as `auto` for non svg compat?

As far as the original original test case UI. It's about allowing something to scroll out onto the screen from a sliver of its content, and while closed, not have scroll events pull it out into view obfuscating scroll interaction for the main view.

I think this is a reasonable ask for this setup of layout/styling?
Comment 11 jonjohnjohnson 2018-12-03 19:38:23 PST
Also, simon.fraser@apple.com, I do have webRender enabled in my firefox, which historically has made their pointer-events/scrolling behave in a more sane manner.

Bug report reference : https://bugzilla.mozilla.org/show_bug.cgi?id=1456938
Comment 12 jonjohnjohnson 2018-12-07 14:31:11 PST
Created attachment 356837 [details]
iOS scroll interactions only captured by scroll containers above other scroll containers in z space

Another test case showing the weirdness that motivated originally filing this issue.

Just like in desktop, iOS should not allow the text block to be scrolled when scrolling from red block. It should behave like scrolling interactions on green block, not scrolling text at all.
Comment 13 jonjohnjohnson 2019-04-06 05:51:52 PDT
(In reply to Simon Fraser (smfr) from comment #9)
> I would expect no browser to allow scrolling of the "This should
> not be scrollable" div, but if your mouse is over the left side of it, they
> allow scrolling.

Why is it exactly that you'd expect no scrolling would occur over the right hand side?
All browsers allow for "text selection" to drag that element from the right hand side exposing the elements scrolling mechanism. Is this something you also wouldn't expect? Or do you just think, that a scroll/wheel/gesture shouldn't manipulate it's scrolling mechanism while dragging to select text should scroll it?
Comment 14 Felix Niklas 2024-01-08 01:37:59 PST
Created attachment 469336 [details]
Map popover testcase

I ran into this bug when building a maps application. When you click on markers on the map a popup slides in from the bottom to half of the screen height. The popup can be scrolled up to reveal the full content. To allow the popup to scroll up all the way it has to be wrapped in a holder element that overlays the map. To make it possible to still interact with the map the holder element's pointer-events are disabled and re-enabled on the popup. This works well in all browsers except Safari. I think the demo illustrates the bug well.
Comment 15 Tim Nguyen (:ntim) 2024-01-08 03:38:08 PST

*** This bug has been marked as a duplicate of bug 258255 ***
Comment 16 Tim Nguyen (:ntim) 2024-01-08 03:38:53 PST
Actually, let's use this to track iOS.
Comment 17 Tim Nguyen (:ntim) 2024-01-08 03:40:34 PST
rdar://118341167
Comment 18 Matthieu Dubet 2024-02-27 16:00:39 PST
Pull request: https://github.com/WebKit/WebKit/pull/25195
Comment 19 Andre Jilderda 2024-03-07 01:30:34 PST
I ran into the same issue as Felix Niklas when trying to create a similar bottom sheet component. 

So in short, what I want to achieve is that the user can drag the bottom sheet (that is fixed and fills the entire viewport) up while still being able to interact with elements in the background when it's not fully expanded.

Example:
https://codesandbox.io/p/devbox/css-only-bottom-sheet-gsr3wr

Video of how this works in Edge 121 (how it is supposed to work) vs. Safari iOS 17.2 (simulator, broken):
https://files.mastodon.social/media_attachments/files/111/999/612/884/572/249/original/a86028cbff6ee46d.mp4

I found that there are some differences between Safari iOS 17.2 & Safari desktop 17.3.

On iOS 17.2:

- ❌ dragging the bottom sheet is NOT working,
- ✅ the click event on the map IS captured,
- ✅ dragging the map works

On desktop Safari 17.3:

- ✅ scrolling over the bottom sheet IS working,
- ✅ the click event on the map IS captured,
- ❌ scrolling over the map is NOT (you can't move the map)