w3c / pointerevents

Pointer Events
https://w3c.github.io/pointerevents/
Other
68 stars 34 forks source link

touch-action:none and overflow:auto #319

Closed liviutinta closed 2 years ago

liviutinta commented 4 years ago

In the following code:

<div id="container" style="touch-action:none; overflow: scroll">
  <div id="intermediate" style="overflow: auto">
    <div id="target"></div>
  </div>
</div>

If scroll action starts at #target, for the purposes of determining supported touch behaviour, should we consider #intermediate to be a scroller only if it is able to be scrolled (content is big enough) or in all cases?

This is in reference to [1]: A touch behavior is supported if it conforms to the touch-action property of each element between the hit tested element and its nearest ancestor with the default touch behavior (including both the hit tested element and the element with the default touch behavior).

[1] https://www.w3.org/TR/pointerevents3/#determining-supported-touch-behavior

NavidZ commented 4 years ago

@smaug---- from the FF side which I believe is very much the same as Chromium

In Chromium we consider something scrollable only if it has the content to be scrolled (i.e. as you mentioned content is big enough). Do you see a particular issue with that?

liviutinta commented 4 years ago

I don't see an issue, just looking for clarification. Now let's say that #target has content that is bigger than the screen (on a mobile phone). It does not overflow the #intermediate div. Should we allow default touch behaviour in this case? I tested on both Chrome and Firefox and I can scroll. Is that the correct behaviour based on the spec?

bokand commented 4 years ago

if it is able to be scrolled (content is big enough)

Just FYI: the canonical way to say this is that "it has scrollable overflow". I.e. it's child content is larger than the box's padding rect

In Chromium we consider something scrollable only if it has the content to be scrolled (i.e. as you mentioned content is big enough). Do you see a particular issue with that?

This is problematic because, in Blink, we compute the effective touch action during style recalc. We don't yet have (up-to-date) layout information at that point so we can't accurately tell whether or not #intermetiate actually has overflow. That seems to imply that if we want this behavior the computation must happen after layout or be performed during a touchstart.

According to bballo@, Gecko just assumes overflow:auto is a scroller regardless of overflow. That seems reasonable to me - perhaps we should specify that and do the same in Blink?

bokand commented 4 years ago

Now let's say that #target has content that is bigger than the screen (on a mobile phone). It does not overflow the #intermediate div. Should we allow default touch behaviour in this case? I tested on both Chrome and Firefox and I can scroll. Is that the correct behaviour based on the spec?

So in this case #target doesn't overflow #intermediate but #intermediate overflows #container? Based on Blink's current implementation that shouldn't work, #intermediate doesn't have overflow so we have to look all the way up to #container to compute the touch behavior which will see touch-action:none. I'm guessing it does work because the stale layout data is actually correct so we see #intermediate as scrollable but we could carefully setup a case where it fails.

As Gecko's behavior is to always treat overflow:auto as a scroller, we'd only look up to #intermediate to compute the touch behavior so scrolling should be allowed and that explains what you're seeing.

theres-waldo commented 4 years ago

Now let's say that #target has content that is bigger than the screen (on a mobile phone). It does not overflow the #intermediate div. Should we allow default touch behaviour in this case? I tested on both Chrome and Firefox and I can scroll. Is that the correct behaviour based on the spec?

So in this case #target doesn't overflow #intermediate but #intermediate overflows #container?

I think perhaps the more interesting case (and possibly what @liviutinta was getting at) is when #target does not overflow #intermediate and #intermediate does not overflow #container either, but #container overflows the visual viewport. Should the touch-action: none prevent scrolling the visual viewport within the layout viewport in that case?

A similar question previously came up for overscroll-behavior, where the oucome was that there should be no special provision to preserve the ability to scroll the visual viewport within the layout viewport in a case like this.

bokand commented 4 years ago

Should the touch-action: none prevent scrolling the visual viewport within the layout viewport in that case?

Interesting. IMHO it should prevent scrolling for similar reasoning as was used in the overscroll-behavior issue. I think the argument for touch-action is actually stronger - consider a finger-painting app handling touches by setting touch-action none. If the user zooms in (e.g. by pinch-zooming over a non-painting-canvas part of the page), moving a finger over the canvas shouldn't now pan the page.

theres-waldo commented 4 years ago

Thanks, that sounds reasonable to me (and I believe is in line with the current Firefox behaviour).

patrickhlauke commented 2 years ago

discussed this today in the PEWG meeting. adding some further info here as this situation seems to occur with position:sticky and similar cases. from @flackr: position:sticky refers to the nearest ancestor scrollport https://www.w3.org/TR/css-position-3/#valdef-position-sticky where scroll port is defined here: https://drafts.csswg.org/css-overflow-3/#scroll-container

flackr commented 2 years ago

I agree with @bokand. As we currently do for sticky position we should look to the nearest scroll container, which is defined to be overflow: hidden | scroll | auto, but not overflow: visible | clip per https://drafts.csswg.org/css-overflow-3/#scroll-container . Beyond making sure that touch-action can be calculated at style time, this helps ensure that we get deterministic behavior which ensures that sites don't break if for example your font is slightly too large or small or screen is the wrong size.

For example, consider a shade with touch-action: none and popup message box containing a possibly scrollable message such as this demo: https://output.jsbin.com/tunejer. If we determine the touch action dynamically, then whether they can scroll the main page by swiping on the message box depends on whether it had overflow. Note that chrome currently have a bug with overscroll-behavior only applying to scroll containers which have overflow.