Popper-core: Measure viewport properly on iOS

Created on 12 Apr 2020  Β·  17Comments  Β·  Source: popperjs/popper-core

CodePen demo

https://6z5bu.csb.app/
https://codesandbox.io/s/loving-feather-6z5bu

Steps to reproduce the problem

  1. open demo in xcode simulator
  2. hardware -> keyboard -> toggle software keyboard
  3. click on input
  4. scroll page up
  5. flip happens only when input is overlapped by keyboard

What is the expected behavior?

Flip should happen when without overlapping by software keyboard

What went wrong?

Mobile browsers decided to not consider software keyboard in window height and instead overlap part of viewport. At some point this prevents junking of measured layout. Though the problem comes when we try to implement custom autocomplete.

Any other comments?

I tried to fix this problem in our popup with many ways and end up with hardcoded keyboard size took from article. Though I searched for the problem again and found probably new api which may solve the problem.
https://developer.mozilla.org/en-US/docs/Web/API/Visual_Viewport_API

This solved maxSize plugin for me and prevented overlapped items.

const keyboardHeight = window.innerHeight - window.visualViewport.height

Perhaps popper could use this api for viewport measuring and fallback to window when it does not exist. Solution does not require any iOS detection.

# BUG 🐞 medium medium browser compat

All 17 comments

Is this hack related?

https://github.com/popperjs/popper-core/blob/04c9e40b99fe7b17a1e9dac0be88a3674e7fc018/src/dom-utils/getDecorations.js#L18-L28

We found that the bottom address bar in Safari (when scrolling up for example) was a problem.

Looks very similar. Perhaps will be solved with VisualViewport api too.

I replaced getViewportRect with this code and both flip and maxSize started work perfectly in simulator with enabled software keyboard

import getWindow from './getWindow.js';
export default function getViewportRect(element) {
  var win = getWindow(element);
  var visualViewport = win.visualViewport;
  if (visualViewport) {
    return {
      width: visualViewport.width,
      height: visualViewport.height,
      x: 0,
      y: 0,
    };
  } else {
    return {
      width: win.innerWidth,
      height: win.innerHeight,
      x: 0,
      y: 0,
    };
  }
}

iOS 10-12 are still widely used, this API is only available on iOS 13. Is there a decent fallback technique we can use?

I didn't find any way before. I mentioned above that I ended with hardcoded keyboard height and ios detection.

https://blog.opendigerati.com/the-eccentric-ways-of-ios-safari-with-the-keyboard-b5aa3f34228d
const assumedKeyboardHeight = isIOS() ? 294 : 0;

Great! We should recommend users to import the polyfill for iOS <= 12 support then?

Edit: I just saw this

TODO: Doesn't work on iOS Safari yet.

πŸ˜† πŸ™„

Our current hack only works for the small bottom bar, not for the keyboard.

Could we add support for this new API, and fallback the the current hack?

I suppose this should be enough? The fallback hack is still in place, but we also handle the visualViewport thing

The hack is unrelated to this; as you said, it only fixes the bottom bar issue, not the keyboard. Rather we'd need to hardcode a keyboard height as fallback, likely the largest possible height so that, although there'll be extra padding for flip/preventOverflow/maxSize on <= iOS 12 in cases where the hardcoded height doesn't match the actual height, the popper will at least still be visible at all times and not hidden. Also detecting when the keyboard is open on iOS doesn't seem easy...

So my PR shouldn't introduce any new issue right? At worst, it will not improve the situation for the devices that don't support that API.

Yes it's fine by itself, it will only improve the situation for all the newest browsers β€” the problem is finding a decent solution for older browsers

Thanks, guys!

It's not fully fixed yet πŸ˜‚ there are some problems I found. I'll work on it soon and make a PR

is this fixed? i still see issues with the keyboard open in ios

We merged a PR to properly fix this yesterday, but I haven't yet released it.

We merged a PR to properly fix this yesterday, but I haven't yet released it.

Cool! When’s the release? Should the issue still be open?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

kerf007 picture kerf007  Β·  3Comments

Madhu94 picture Madhu94  Β·  3Comments

cixonline picture cixonline  Β·  5Comments

Sawtaytoes picture Sawtaytoes  Β·  5Comments

DawnWright picture DawnWright  Β·  4Comments