Bug 199691 - The whole viewport shifts down when resetting document scrollTop
Summary: The whole viewport shifts down when resetting document scrollTop
Status: NEW
Alias: None
Product: WebKit
Classification: Unclassified
Component: HTML Editing (show other bugs)
Version: Safari Technology Preview
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Nobody
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2019-07-10 16:37 PDT by Xidorn Quan
Modified: 2020-04-20 18:58 PDT (History)
6 users (show)

See Also:


Attachments
testcase (971 bytes, text/html)
2019-07-10 16:37 PDT, Xidorn Quan
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Xidorn Quan 2019-07-10 16:37:25 PDT
Created attachment 373876 [details]
testcase

Steps to reproduce:
1. open the attached testcase on iOS
2. tap the "Hello world" text

Expect result:
The keyboard shows up without moving the viewport.

Actual result:
The whole viewport briefly shifts down.


In this testcase, the page tries to move the text up manually (for various reasons), thus it wants to remove the scrolling on document done by the browser. But that triggers this issue.

The effect is similar to bug 198737, and this is probably the actual cause of that issue.

This is reproducible on both iOS 12 and iOS 13.

Similar to bug 198737, you can see this shift clearer via using simulators with Debug / Slow Animations enabled.
Comment 1 Radar WebKit Bug Importer 2019-07-11 12:50:14 PDT
<rdar://problem/52966595>
Comment 2 Ryosuke Niwa 2019-07-12 15:42:30 PDT
The scrolling in iOS is asynchronous. By the time scroll event is fired, the scrolling had already happened asynchronously so that's too late.
Comment 3 Simon Fraser (smfr) 2019-07-12 16:21:55 PDT
document.addEventListener('scroll', evt => {
  document.documentElement.scrollTop = 0;
  document.body.scrollTop = 0;
});

This is a really bad pattern that we see commonly; if you rubber-band the content, it will also try to set the scrollTop back to 0.
Comment 4 Xidorn Quan 2019-07-13 21:27:01 PDT
(In reply to Simon Fraser (smfr) from comment #3)
> document.addEventListener('scroll', evt => {
>   document.documentElement.scrollTop = 0;
>   document.body.scrollTop = 0;
> });
> 
> This is a really bad pattern that we see commonly; if you rubber-band the
> content, it will also try to set the scrollTop back to 0.

I feel like this is potentially an anti-pattern, but how would you recommend for the case where author may want to move the element manually, for example, when they want to zoom to the current visible area?
Comment 5 Ryosuke Niwa 2019-07-14 14:45:16 PDT
(In reply to Xidorn Quan from comment #4)
> (In reply to Simon Fraser (smfr) from comment #3)
> > document.addEventListener('scroll', evt => {
> >   document.documentElement.scrollTop = 0;
> >   document.body.scrollTop = 0;
> > });
> > 
> > This is a really bad pattern that we see commonly; if you rubber-band the
> > content, it will also try to set the scrollTop back to 0.
> 
> I feel like this is potentially an anti-pattern, but how would you recommend
> for the case where author may want to move the element manually, for
> example, when they want to zoom to the current visible area?

The recommended approach is to move the element immediately when the input element is focused so the WebKit wouldn't try to scroll to it. In general, once the keyboard has started being brought up, there is nothing you can do to cancel the scrolling.
Comment 6 Xidorn Quan 2019-07-14 17:18:53 PDT
> The recommended approach is to move the element immediately when the input element is focused so the WebKit wouldn't try to scroll to it.

Thanks for the advice. It's not always trivial to do in practice, but I guess it's not impossible either.

I wonder, though, why would resetting the scrollTop makes the viewport shift down while we are just trying to stop it from shifting up?
Comment 7 Xidorn Quan 2019-07-15 17:39:17 PDT
(In reply to Ryosuke Niwa from comment #5)
> The recommended approach is to move the element immediately when the input
> element is focused so the WebKit wouldn't try to scroll to it.

Actually, this approach doesn't seem to work either.

As shown in this testcase, I do move the element immediately when it's focused, and it just has a transition to do so smoothly.

Even if I remove the transition (so that the moving happens immediately in handler of focus event in any sense), the viewport still scroll.
Comment 8 Ryosuke Niwa 2020-03-10 23:21:53 PDT
(In reply to Xidorn Quan from comment #7)
> (In reply to Ryosuke Niwa from comment #5)
> > The recommended approach is to move the element immediately when the input
> > element is focused so the WebKit wouldn't try to scroll to it.
> 
> Actually, this approach doesn't seem to work either.
> 
> As shown in this testcase, I do move the element immediately when it's
> focused, and it just has a transition to do so smoothly.
> 
> Even if I remove the transition (so that the moving happens immediately in
> handler of focus event in any sense), the viewport still scroll.

Hm... is this still an issue in the latest betas of iOS 13.4?
Comment 9 Xidorn Quan 2020-04-20 18:58:05 PDT
(In reply to Ryosuke Niwa from comment #8)
> Hm... is this still an issue in the latest betas of iOS 13.4?

Sorry for the late reply.

I didn't get a chance to test on the beta version, but it still seems to be an issue on the latest 13.4.1.