Bug 191204 - Broken viewport mechanics when software keyboard is visible
Summary: Broken viewport mechanics when software keyboard is visible
Status: NEW
Alias: None
Product: WebKit
Classification: Unclassified
Component: Layout and Rendering (show other bugs)
Version: Safari 12
Hardware: iPhone / iPad All
: P2 Normal
Assignee: Nobody
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2018-11-02 12:55 PDT by Piotrek Koszuliński (Reinmar)
Modified: 2019-07-24 18:35 PDT (History)
8 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Piotrek Koszuliński (Reinmar) 2018-11-02 12:55:29 PDT
NOTE: A nicely formatted version of this bug report: https://gist.github.com/Reinmar/91c70d2882523f47da7c498050421204

## Introduction

The behaviour of the Safari@iOS's viewport makes it very hard to position anything reliably when the software keyboard is visible.

We're dealing with this problem in CKEditor 5, but I see that other rich-text editor have similar problems. I haven't yet seen a rich-text editor which would work well on Safari@iOS (in fact, some of them hide their samples when visiting from Safari@iOS – perhaps to not scare people away ;)). And people have really spent a lot of time on this.

So, the problem is that when the software keyboard appears the following three things stop working:

* `position:fixed` becomes unreliable,
* `window.innerHeight` returns a useless value,
* `position:absolute; top: window.scrollY` and `position:absolute; bottom: -window.scrollY` become unreliable too.

Since all of those methods to position something in the viewport fail it's an art to keep things in place. You can try to workaround this by positioning things absolutely and only to the top of the viewport (I saw some apps succeed to keep things there; although, I don't know how). But that's both hacky (special code for mobile Safari only), unstable and it does not resolve all the issues. For instance, sometimes you just need to know the lower boundary of the viewport e.g. to scroll the viewport to the caret (https://github.com/ckeditor/ckeditor5/issues/1321#issuecomment-435330662).

PS. By "viewport" I mean the part of the screen where I can see the website. This is, the green box in the *Chrome@Android's version* of this diagram https://cloud.githubusercontent.com/assets/1099479/16153438/9bb4ffce-34a6-11e6-8e42-83d79b9156e8.png

## Test playgrounds

### Fixed positioning

Demo: https://ckeditor5.github.io/misc/viewport-fixed.html

Screenshots from Safari@iOS:

* https://ckeditor5.github.io/misc/viewport-screenshots/fixed-ios-1.PNG
* https://ckeditor5.github.io/misc/viewport-screenshots/fixed-ios-2.PNG
* https://ckeditor5.github.io/misc/viewport-screenshots/fixed-ios-3.PNG
* https://ckeditor5.github.io/misc/viewport-screenshots/fixed-ios-4.PNG

Screenshots from Chrome@Android:

* https://ckeditor5.github.io/misc/viewport-screenshots/fixed-android-1.png
* https://ckeditor5.github.io/misc/viewport-screenshots/fixed-android-2.png
* https://ckeditor5.github.io/misc/viewport-screenshots/fixed-android-3.png
* https://ckeditor5.github.io/misc/viewport-screenshots/fixed-android-4.png

As you can see, on Android the green and red boxes are always fully visibile. Even when the software keyboard is visible.

### window.innerHeight and absolute positioning

Demo: https://ckeditor5.github.io/misc/viewport-absolute.html

Screenshots from Safari@iOS:

* https://ckeditor5.github.io/misc/viewport-screenshots/absolute-ios-1.PNG
* https://ckeditor5.github.io/misc/viewport-screenshots/absolute-ios-2.PNG
* https://ckeditor5.github.io/misc/viewport-screenshots/absolute-ios-3.PNG
* https://ckeditor5.github.io/misc/viewport-screenshots/absolute-ios-4.PNG

Screenshots from Chrome@Android:

* https://ckeditor5.github.io/misc/viewport-screenshots/absolute-android-1.png
* https://ckeditor5.github.io/misc/viewport-screenshots/absolute-android-2.png
* https://ckeditor5.github.io/misc/viewport-screenshots/absolute-android-3.png
* https://ckeditor5.github.io/misc/viewport-screenshots/absolute-android-4.png

Again, all works as expected on Android and really bad in Safari.

## To sum up

The current behaviour of Safari is extremely problematic. I know there must have been some reason for it to be designed this way (with the additional scrollable layer). My guess is – performance. As I understand, there's no "resizing" happening when the keyboard slides up. However, performance is meant to ensure good UX. But right now the UX of all RTEs the I know is just bad (or worse) on Safari because of this behaviour. We've done quite a lot of research on this (https://github.com/ckeditor/ckeditor5-design/issues/149) and failed to find a solution.

I would also like to point out that the Android's behaviour is the one which was intuitive for me. Since I don't own an Android device myself I've been coding the above samples as I thought they should work and only later on I learnt that they work perfectly fine in Chrome.

Finally, the "scroll to show the caret" problem (https://github.com/ckeditor/ckeditor5/issues/1321#issuecomment-435330662) means that fixing e.g. just `position:fixed`'s behaviour will not solve all the problems – the `window.innerHeight` property and `window.scrollY` will also need to cooperate.
Comment 1 Radar WebKit Bug Importer 2018-11-04 12:42:57 PST
<rdar://problem/45794353>