iOS version: 15.4 iPhone: iPhone 12 Pro --- Steps: 1. Have a website that has a text input that is fixed to the bottom of the page 2. Add the website to the home screen 3. Open the web app on the home screen 4. Open JS console and run this: visualViewport.addEventListener('resize', () => console.log('viewport offsetTop, height:', visualViewport.offsetTop, visualViewport.height)) 5. Tap the text input, which should bring up the soft keyboard, then tap `Done` to close it, then tap the text input again. Do it a few times and observe the JS console logs --- Expected: Whenever the soft keyboard is open, the log should consistently look like: viewport offsetTop, height: 380 - 417 --- Actual: The log is sometimes correct, but other times I will see a 0 offsetTop, like: viewport offsetTop, height: 0 - 417 If I add setTimeout() to the event handler and log offsetTop with a 50ms delay, then offsetTop will be 380 even when it first reports 0 inside the event handler. Note that I have only seen it on the web app. I haven't reproed it on mobile Safari.
<rdar://problem/90364854>
Just ran into a similar issue, but in my case it's reliable for installed web apps but not in regular safari. Sadly, attempts to write a simplified testcase result in correct behavior so can't help in that regard. Wrapping the code in the resize listener in a 'before next paint' (double rAF) fixes it - so similar to the OP's setTimeout workaround. Is it possible that the visualViewport resize event sometimes fires too soon or the height calculation happens too late ?