Bug 138201

Summary: Caret doesn't move while scrolling -webkit-overflow-scrolling: touch content on iOS
Product: WebKit Reporter: Chris Rebert <webkit>
Component: FormsAssignee: Megan Gardner <megan_gardner>
Status: NEW ---    
Severity: Normal CC: ae, ajuma, ap, carlos, ccorcos, dbates, enrica, fgoeb, fred.wang, gabrielmaldi, gaston.avila, hans.oksendahl, hnrch02+webkit, icewil, info, js.magoon, peter.koshelev, pikatore, piotr, pleger2, q2224859, samtsai, selim, simon.fraser, vitaly.kosenko, webkit-bug-importer, wenson_hsieh, xenonelive
Priority: P2 Keywords: HasReduction, InRadar
Version: Safari 9   
Hardware: iPhone / iPad   
OS: iOS 10   
URL: http://output.jsbin.com/hoxuxu
See Also: https://bugs.webkit.org/show_bug.cgi?id=179927
https://bugs.webkit.org/show_bug.cgi?id=202125
Bug Depends on:    
Bug Blocks: 159753    
Attachments:
Description Flags
Copy of 1st JS Bin example none

Description Chris Rebert 2014-10-29 17:45:22 PDT
Original Bootstrap bug: https://github.com/twbs/bootstrap/issues/14708

1. Open http://jsbin.com/himir/2 in iOS 8 Safari.
2. Click the green button
3. Tap into the "First Name" text field
4. Place finger on part of the empty white background of the modal form box
5. Move your finger upwards so as to scroll the modal down, but don't take your finger off of the screen.

Actual Result:
Observe that the blinking blue text cursor remains at its original location before the scrolling began.

Expected Result:
Either the cursor should move along with the text field or it should temporarily stop being displayed altogether.


This bug has been reproduced on iOS 7 and iOS 8.
Comment 1 Chris Rebert 2014-10-29 17:55:52 PDT
Have also filed this as:
<rdar://problem/18819624>
Comment 2 Chris Rebert 2015-05-06 13:40:02 PDT
Created attachment 252514 [details]
Copy of 1st JS Bin example
Comment 3 Chris Rebert 2015-10-30 01:20:15 PDT
I am unable to re-test the testcase against iOS 9 since it's affected by bug 150715.
Comment 4 Chris Rebert 2016-02-07 16:40:47 PST
Updated testcase to avoid bug 150715.
Comment 5 Chris Rebert 2016-02-07 16:41:53 PST
I can't reproduce this in iOS 9.2.
Comment 6 Josh Pike 2016-02-08 19:16:21 PST
I can. Please reopen the issue.

A good example of a site this issue occurs on:


https://material.angularjs.org/latest/demo/input

Issue occurs in Safari, WKWebKit view

iOS 9.2.1
Comment 7 Chris Rebert 2016-02-08 19:32:53 PST
Interesting. Confirmed.
Comment 8 Josh Pike 2016-02-24 14:31:49 PST
Not one to be a nag, but I think this bug is a pretty serious usability issue. It's a deal breaker in creating SPAs for iOS, which is becoming an increasing trend.

What is this issue most probably due to?
Comment 9 Josh Pike 2016-03-10 17:24:28 PST
Are there are any known workaround to this? It's driving me insane and my users are constantly complaining about it.
Comment 10 Carlos 2016-03-11 02:17:02 PST
I have spent some days trying to find a workaround without success.

Here there is a gif when we can see the caret floating when scrolling https://media.giphy.com/media/3o7abrmGRJeHg0PYZy/giphy.gif

Things I know:
- still happening in iOS 9.3
- Only happens when the scroll is not in the body. Usually to have a fixed layer like a header.
- Only happens when -webkit-overflow-scrolling: touch is activated (for able to scroll with momentum)
Comment 11 Chris Rebert 2016-03-11 02:24:03 PST
Carlos, could you post the URL of your JS Bin?
Looks like it might be a simpler (and thus better) testcase than the current AngularJS one.
Comment 12 Carlos 2016-03-11 02:31:43 PST
http://output.jsbin.com/hoxuxu
http://jsbin.com/hoxuxu/edit?html,css,output

Also, here is another issue with the caret and scroll that maybe is related and can help. https://stackoverflow.com/questions/35700636/input-caret-floating-over-a-fixed-layer-when-scrolling

Thanks
Comment 13 Josh Pike 2016-03-15 18:40:48 PDT
I should add:

My input fields use transform3D(0,0,0) as a workaround to fix the safari disappearing fields bug:

http://stackoverflow.com/questions/9807620/ipad-safari-scrolling-causes-html-elements-to-disappear-and-reappear-with-a-dela

This may or may not be a contributing factor.

It's incredible that this is still a problem!
Comment 14 Josh Pike 2016-03-15 18:42:47 PDT
I've run into it again in another scenario...

http://stackoverflow.com/questions/20737503/mobile-safari-input-caret-does-not-scroll-along-with-overflow-scrolling-touch

This issue needs WAY more attention.
Comment 15 Simon Fraser (smfr) 2016-03-15 18:47:52 PDT
(In reply to comment #14)
> I've run into it again in another scenario...
> 
> http://stackoverflow.com/questions/20737503/mobile-safari-input-caret-does-
> not-scroll-along-with-overflow-scrolling-touch

Did you file a bug on that issue?
Comment 16 Josh Pike 2016-03-15 18:48:41 PDT
In Apple's bug reporter? Yes. Months ago.
Comment 17 Simon Fraser (smfr) 2016-03-15 18:49:55 PDT
Can you comment with the bug number please.
Comment 18 Josh Pike 2016-03-15 18:50:48 PDT
24882755
Comment 19 Simon Fraser (smfr) 2016-03-15 19:01:14 PDT
(In reply to comment #18)
> 24882755

Thank you. I'll look into it.
Comment 20 Josh Pike 2016-03-15 21:29:13 PDT
Found a workaround!

This workaround is partially in angular.js but should work with any JS framework (or pure JS).

On tapping an input field, I used $location.hash to jump to the field above it straight after focus, which caused the input cursor to stay where it was.

If I just trigger a .blur() then a focus() about 300-400 ms after the scroll jumped, the input cursor 'reset' its position to the correct one.
Comment 21 vitaly.kosenko 2017-07-18 04:27:19 PDT
Why do I still see error in Safari 10 on iOS 10.3.2 in http://jsfiddle.net/gxT3w. I'am setting focus and start scrolling
Comment 22 gabrielmaldi 2017-10-03 10:58:30 PDT
I can still repro this issue in UIWebView on iOS 11.1.
Comment 23 Simon Fraser (smfr) 2017-10-11 11:30:39 PDT
Does it reproduce in WKWebView?
Comment 24 gabrielmaldi 2017-10-12 19:20:39 PDT
(In reply to Simon Fraser (smfr) from comment #23)
> Does it reproduce in WKWebView?

Yes, it does.

I just tested the following code on my iPhone 6S running iOS 11.1 beta 2:

```
WKWebView *webView = [[WKWebView alloc] init];
NSURL *url = [NSURL URLWithString:@"https://jsfiddle.net/gabrielmaldi/n5pgedzv/show/"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[webView loadRequest:request];
```

And this is the result:

https://youtu.be/KYBOEePlysk

Even though it repros in WKWebView, native web apps have no option but to use the older UIWebView because WKWebView doesn't handle local files well (and a web server is needed). So it would be great if this issue got fixed and also backported to UIWebView.

Thanks
Comment 25 Not Internet Explorer 2017-10-16 07:59:38 PDT
How is this issue not resolved yet? Seriously.

As carlos already issued at 2016-03-11 (WTF):

- still happening in iOS 9.3
- Only happens when the scroll is not in the body. Usually to have a fixed layer like a header.
- Only happens when -webkit-overflow-scrolling: touch is activated (for able to scroll with momentum)
Comment 26 Simon Fraser (smfr) 2017-10-17 20:52:43 PDT
With both UIWebView and WKWebView on iOS 11, I can reproduce the caret remaining visible when scrolling on https://jsfiddle.net/gabrielmaldi/n5pgedzv/show/. However, in both cases when the scroll ends the caret snaps to the correct location.
Comment 27 Simon Fraser (smfr) 2017-10-17 20:58:19 PDT
We need to track when the caret is inside accelerated overflow scroll and just hide it while scrolling, as we do inside position:fixed (see -shouldHideSelectionWhenScrolling).
Comment 28 Hans 2017-11-08 13:45:02 PST
It has been quite a while since this bug was reported is there an ETA for a fix?  While this bug does not prevent the user from inputting using the onscreen keyboard it does break the expected user interaction and I believe it should be considered a P1.
Comment 29 Jon M 2017-11-29 15:23:23 PST
Would love for this bug to get some attention. Our users complain about it due to not knowing where text is going to get entered until a user starts typing or performs another action on the site.
Comment 34 gabrielmaldi 2018-08-22 17:49:10 PDT
Just confirmed the issue exists in iOS 12 developer beta 9, running on my iPhone X using Xcode 10 beta 6.

Same code and behavior (YouTube video) I posted in [Comment 24](https://bugs.webkit.org/show_bug.cgi?id=138201#c24) for both WKWebView and UIWebView.
Comment 35 Chet Corcos 2018-10-16 16:41:47 PDT
I'm having this same issue. Looks like a native re-rendering problem. If I listen to the "scroll" event and change `paddingBottom = Math.random() + "px"` causing a re-render, then the caret moves. The view also janks around though too. Not a solution, just a demonstration. Please fix this Apple! :)
Comment 36 Chet Corcos 2018-10-16 17:03:24 PDT
I have a really hacky solution that appears to work in the meantime. It takes a toll on performance though :/


```
import * as raf from "raf"

let elm: HTMLDivElement | undefined

function getElm() {
	if (!elm) {
		elm = document.createElement("div")
		elm.style.position = "fixed"
		elm.style.top = "-9999px"
		elm.style.left = "-9999px"
		elm.style.zIndex = "-9999"
		document.body.appendChild(elm)
	}
	return elm
}

let pendingRender = false

function forceRerender() {
	if (pendingRender) {
		return
	}
	pendingRender = true
	raf(() => {
		pendingRender = false
		getElm().style.height = Math.random() + "px"
	})
}

function rerenderSelectionCaret() {
	if (window.getSelection().anchorNode) {
		forceRerender()
	}
}


// get your scroller element
scroller.addEventListener("scroll", rerenderSelectionCaret)
```
Comment 37 Mato 2018-11-07 03:19:28 PST
In our case, this even prevented form field values from being rendered. You can see the caret moving but no text is shown. Querying the field's value properly returns the entered text. By forcing a re-render, e.g. by changing CSS properties of the field, the value is rendered then.

This is really a major issue. We've tested it on the latest versions of iOS 11 and 12. Removing "-webkit-overflow-scrolling" solves the rendering issue but sacrifices UX.
Comment 38 Mato 2018-11-07 03:26:26 PST
(In reply to Mato from comment #37)
> In our case, this even prevented form field values from being rendered. You
> can see the caret moving but no text is shown. Querying the field's value
> properly returns the entered text. By forcing a re-render, e.g. by changing
> CSS properties of the field, the value is rendered then.
> 
> This is really a major issue. We've tested it on the latest versions of iOS
> 11 and 12. Removing "-webkit-overflow-scrolling" solves the rendering issue
> but sacrifices UX.

An additional information I forgot to mention is, that we're experiencing this issue in both, Safari and WkWebView.
Comment 39 Simon Fraser (smfr) 2018-11-07 10:45:58 PST
(In reply to Mato from comment #37)
> In our case, this even prevented form field values from being rendered. You
> can see the caret moving but no text is shown. Querying the field's value
> properly returns the entered text. By forcing a re-render, e.g. by changing
> CSS properties of the field, the value is rendered then.

That sounds like a separate issue. Can you file a new bug with a test case?
Comment 40 Piotr 2019-10-25 00:18:16 PDT
Still experiencing this in iOS 13.1.3 in WKWebView and Safari.

HavenĀ“t been able to find any workaround. Tried using the scroll event to hide the caret, re-rendering the field by setting value to something else and then back again on scroll did help a little bit but broke the bouncy scroll. So stuck with a glitchy app.
Comment 41 peter.koshelev 2022-03-10 10:13:52 PST
any solution for this!?