w3c / virtual-keyboard

VirtualKeyboard API
https://w3c.github.io/virtual-keyboard/
Other
16 stars 3 forks source link

Still can't implement iOS-style VK behavior with the API #14

Closed AshleyScirra closed 2 years ago

AshleyScirra commented 2 years ago

One of the key use cases for this API was for us to implement the same kind of VK behavior as we have on iOS. That means when you tap an input element, the VK appears, and the visual viewport is moved to show the input element you're entering text in to.

Unfortunately the current design of the VirtualKeyboard API still makes this very difficult. The problem is if you have a non-scrolling full page view (in our case for a HTML5 game), there is no way to control the visual viewport, so setting overlaysContent to true means the keyboard just overlaps the input element with no way to scroll the input element back in to view.

Here's a small test case: vk-test.zip Tested in Chrome 94 beta on Android.

Notice there is an input element at the bottom of the screen. Tap it to enter text and the VK appears. However the VK covers up the input element so you can't see what you're typing.

Calling scrollIntoView() on the input element does not seem to help, presumably because the page cannot scroll, and it does not change the visual viewport. The entire Visual Viewport API appears to be read-only, so there's no API we can call to change it and move the input element in to view.

Changing overlaysContent to false means the VK changes the size of the window which is what we wanted to avoid in the first place.

It all works fine on iOS. That's the behavior we're trying to recreate in Android with the Virtual Keyboard API.

So it seems the Virtual Keyboard API still does not support a key use case of what we wanted to use it for. This would probably affect other use cases too like chat apps. Should the API be changed? Or am I missing something? It can probably be worked around with a really awkward hack like making the page taller by the height of the virtual keyboard so then we can scroll it, but it seems like a pretty ugly solution.

AshleyScirra commented 2 years ago

I thought I'd try doing the offset with CSS transforms, but document.body.style.transform = `translateY(${-vkHeight}px)`; doesn't move the view up enough... is Chrome reporting the correct VK height?

snianu commented 2 years ago

@AshleyScirra You can also use the CSS environment variables to fetch the boundingRect of the keyboard that is just an intersection of the actual VK rectangle and the layout viewport. You can then use this boundingRect's height to adjust the position of the input element in your page without affecting other contents of the page. Here is an example.

snianu commented 2 years ago

Also can you try to set the scrollTop property instead of calling scrollIntoView? scrollIntoView would only work if the visual viewport resizes in response to the VK visibility that occludes the element that you are trying to call scrollIntoView on.

AshleyScirra commented 2 years ago

I think the problem is the page doesn't scroll at all, making scrollTop, scrollInToView etc. all useless in this case. The VK doesn't make the page scrollable when it overlays content.

I also tried using CSS transforms, but it looks like the keyboard height is wrong in Chrome, so I filed this issue: https://bugs.chromium.org/p/chromium/issues/detail?id=1250380

So I still can't find any way to achieve this. I don't want to move elements around or change the layout of the page; just shift everything up so the input element is visible, like Safari does.

snianu commented 2 years ago

Tracking this in the crbug so closing this issue.