metafizzy / flickity

:leaves: Touch, responsive, flickable carousels
https://flickity.metafizzy.co
7.53k stars 602 forks source link

Flickity Interaction Causes mobile chrome viewport height to stop recalculating when URL bar shows and hides #725

Closed eugenecyckowski closed 5 years ago

eugenecyckowski commented 6 years ago

The Issue There is an issue on mobile Android Chrome where after interacting with Flickity, the viewport height stops recalculating when the browser url bar shows and hides.

Steps to Reproduce

  1. After loading the page on mobile chrome browser with the url bar shown, in the console check viewport height by running window.innerHeight.
  2. Without touching the carousel, scoll the page down so that the mobile browser URL bar hides.
  3. Run window.innerHeight again and observe that the innerHeight has increased.
  4. Interact with the carousel by swiping the cells.
  5. Now run window.innerHeight with the URL bar showing and with it hiding. Observe that this value is no longer updating when the URL bar shows and hides.

The Impact After interacting with Flickity, elements that are expected to fill 100% of the screen height will not update when the URL bar shows and hides. This results in either empty space at the bottom of the screen when the calculated height is smaller than the current actual height, or elements that should be positioned on the bottom of the screen being pushed off screen and unaccessible when the calculated height is larger than the current actual height.

Demo See the Codepen demo below to test the issue. https://codepen.io/eugenecyckowski/pen/jzYJBm?editors=1100

theenoahmason commented 6 years ago

@eugenecyckowski @desandro I can confirm this issue! I was just about to post this exact problem.

This causes any elements that are fixed to the window with height 100% to behave improperly.

A simple example of the behavior: If the first swipe on flickity happens when Chrome mobile's address bar is in view, then all full height fixed elements will not reach the end of the viewport. If the first swipe happens when Chrome mobile's address bar is hidden, then all full height fixed elements will pass the viewport.

The reason this is happening is because Chrome is not able to recalculate the height of the window.

I have not looked at the source code, but intuition tells me this has to do with a touch event not ending. It seems chrome waits for the touch event to end before it does the recalculation.

Is it possible it has something to do with https://github.com/metafizzy/flickity/issues/723?

desandro commented 6 years ago

Thanks for reporting this issue. I'll have to take a look.

theenoahmason commented 6 years ago

@desandro thanks!

It is affecting all our modals, and nav drawers, etc. A fix, or even a small hack snippet would be extremely appreciated!

I am going to try messing with the drag threshhold property to see if that does anything, just a hunch. will post update in a few.

eugenecyckowski commented 6 years ago

I second @theenoahmason that its effecting all modals, nav drawers etc.

Still no luck on our end fixing the issue. We're going to try a couple things this week too and will share if we find a solution.

@desandro if you do find any solution please share!

theenoahmason commented 6 years ago

@eugenecyckowski This may not be ideal, but here is what we did for now (CSS Only):

CSS Hack (note caveats below)

We made all full height elements (dialog backdrops, drawers, etc.) use height: 100vh; (device height).

This is the height of the viewport without Chrome's URL bar (everything under the notification bar), and does not get recalculated when Chrome's URL bar is hidden/shown.

The reason this was more desirable

Now, no drawers, dialogs are ever shorter than the viewport.

The reason this is not ideal

Now, To reach the bottom of a drawer, for example, you must scroll and hide the URL bar. This also bumps down dialogs that should be centered vertically by the same height as the URL bar. However, All elements are still fully accessible.

Note: this is not a fix to the underlying problem for sure, but got rid of some pretty ugly side effects.

Also @eugenecyckowski, are you using Material Components Web by chance?

desandro commented 6 years ago

Sorry, haven't had a chance to dig into this one. Considering that Flickity v2.1 just launched, have you tried falling back to v2.0 and seeing if this issue persists? See demo: https://codepen.io/desandro/pen/GxBxZy

theenoahmason commented 6 years ago

@desandro I just tried downgrading to 2.0 (latest is 2.0.11). Unfortunately now flickity is broken as this is being bundled with browserify in gulp, and it seems the same problem still exists from https://github.com/metafizzy/flickity/issues/724 under this circumstance.

Console Error

Uncaught TypeError: this._dragPointerDown is not a function
    at h.r.pointerDown (drag.js:129)
    at h.i._pointerDown (unipointer.js:128)
    at h.i.onpointerdown (unipointer.js:107)
    at h.i.handleEvent (unipointer.js:77)

The fix for this was released @ 2.1.1 according to the above thread.

shaylevi2 commented 6 years ago

Complete showstopper, what an horrendous bug.

Did anyone find a solution?

theenoahmason commented 6 years ago

@shaylevi2 unfortunately no. At this point, Flickity is affecting nearly all cool interactions we have.

theenoahmason commented 6 years ago

@desandro I don't know if this helps pinpoint the issue, but I can confirm that this is only affecting chrome.

Samsung internet app has a similar recalculation of the viewport for their address bar/bottom bar on scroll. This issue does NOT appear in this app.

This appears to be isolated to chrome mobile. Interested in knowing if this happens on chrome in ios?

theenoahmason commented 6 years ago

@shaylevi2 @eugenecyckowski

What device/browser is this affecting for you? can you confirm if this issue persists on chrome for ios? We are an ocean of Androids here.

eugenecyckowski commented 6 years ago

@theenoahmason

we're also seeing the issue on iOS Chrome (confirmed on a few different iPhone devices), and have the issue on all the android devices running chrome that we've tested on. Looks like the issue is happening on both iOS and Android Chrome.

theenoahmason commented 6 years ago

@eugenecyckowski Thanks for checking that out.

I can confirm this issue does not persist in Firefox for android.

This is clearly only a chrome bug. At this point I'm lost.

mleone commented 6 years ago

This was a complete showstopper for my team; we ended up having to switch to https://github.com/nolimits4web/swiper/ . Nonetheless, props to flickity contributors for all the hard work! We'd be open to trying out flickity again if this issue gets addressed.

theenoahmason commented 6 years ago

@desandro I just experienced this issue with another script, not using flickity on said project at all.

For reference: Using Google's MDC Web (Material Design Components for the Web). The drawer (MDCTemporaryDrawer) is slideable on touch devices; interacting with that slideable drawer, then scrolling the viewport causes the same artifacts as described in this issue.

What this means for me is that this is a chrome issue.

Note: also uses touch-action css prop.

@mleone can you confirm you were only seeing this issue in chrome mobile?

joeytrout commented 6 years ago

I've been on this bug for a while with a different plugin and have pin pointed it to Android Chrome not being able to handle the css "touch-action: pan-y". If you put this css on ANY element on the page and swipe left or right, it will cause this issue.

theenoahmason commented 6 years ago

@desandro This issue is fixed as of latest chrome android update. It seems touch-action prop is now safe to use.

Party on, party people.

desandro commented 5 years ago

@theenoahmason Thanks so much for following & updating this issue.