Issue: https://bugs.webkit.org/show_bug.cgi?id=191204
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
andposition: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.
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:
Demo: https://ckeditor5.github.io/misc/viewport-fixed.html
Screenshots from Safari@iOS:
Screenshots from Chrome@Android:
As you can see, on Android the green and red boxes are always fully visibile. Even when the software keyboard is visible.
Demo: https://ckeditor5.github.io/misc/viewport-absolute.html
Screenshots from Safari@iOS:
Screenshots from Chrome@Android:
Again, all works as expected on Android and really bad in Safari.
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 and failed to find a good 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 means that fixing e.g. just position:fixed
will not solve all the problems – the window.innerHeight
property and window.scrollY
will also need to cooperate.