angular / components

Component infrastructure and Material Design components for Angular
https://material.angular.io
MIT License
24.35k stars 6.74k forks source link

bug(cdk/overlay) on iOS: FlexibleConnectedPositionStrategy + BlockScrollStrategy results in wrong overlay position when scrolled down #18890

Open derzwen opened 4 years ago

derzwen commented 4 years ago

Bug, feature request, or proposal:

When FlexibleConnectedPositionStrategy + Bottom placing + BlockScrollStrategy are used together, the overlay is positioned wrong. At least on an iOS device.

In the example linked below, the link opens an overlay with FlexibleConnectedPositionStrategy connected to an anchor

just right above the link. The overlay is configured to be displayed on the bottom via "withPositions" (see code). A long fake content is added before the link so that it's possible to scroll down.

In Desktop browsers (Chrome, FF, Safari, Edge), the overlay is positioned fine, even when scrolled down.

In Safari on iOS, the position is ok when NOT scrolled down. But if you scroll down, an open the overlay, it's not positioned directly over the link anymore, but way too high. If you open a 2nd overlay via the link, this one is positioned correctly though.

If you don't use BlockScrollStrategy, the positioning always works as expected.

What is the expected behavior?

The overlay should be displayed directly above the "open overlay" link.

What is the current behavior?

Overlay position is wrong, it's displayed way too high. The further you scroll down, the higher it is displayed.

What are the steps to reproduce?

https://stackblitz.com/edit/angular-cyzulh

  1. Open https://angular-cyzulh.stackblitz.io on an iOS device
  2. Scroll down until you see "open overlay" link
  3. click link -> overlay should be shown directly above the text BUT it is not
  4. click link again -> 2nd overlay is created which is positioned correctly above the text

What is the use-case or motivation for changing an existing behavior?

Seems just a bug...

Which versions of Angular, Material, OS, TypeScript, browsers are affected?

  • Browser: Safari on iOS 13.3 or iPadOS 13.3
  • Angular 9.x without Ivy, Material 9.1.x (see project dependencies)

Is there anything else we should know?

malathi-ck commented 4 years ago

This issue is present in Android (used chrome) as well without using BlockScrollStrategy. When the address bar is visible, positions are fine, but when it is hidden tool tip is positioned below the actual point.

michaill commented 4 years ago

This issue is present in Android (used chrome) as well without using BlockScrollStrategy. When the address bar is visible, positions are fine, but when it is hidden tool tip is positioned below the actual point.

this is known bug caused by setting height to 100vh. not related to original issue (witch occures with and without addressbar and ONLY in iphones - even not in emulators)

we had exactly the same problem on iphones. if you scroll down the site, you had broken overlays

michaill commented 4 years ago

I found a problematic point. iOS gives wrong number in window.innerWidth and window.innerHeight.

here is a fix for scrolling/viewport-ruler.ts just replace window.innerHeight with document.documentElement.clientHeight and window.innerWidth with document.documentElement.clientWidth

I do not want to contribute on PR, but somebody who is used to that, can do this and check all the occurances of innerWidth and innerHeight to make them iOS compliant

mfishma commented 3 years ago

Hi! I see above this was determined to be specifically about the iOS bug, would like to bubble this up as it's rearing its head in our production stack. Thanks!

wellwind commented 2 years ago

Share my quick workaround:

Just create a new class like CustomViewportRuler, content is same as ViewPortRuler but correct the wrong code, then using DI container to replace it.

providers: [
  {
    provide: ViewportRuler,
    useClass: CustomViewportRuler
  }
]

Should solve the problem before new fix released.