Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug Report] IOS: when long dialog scroll, background should not scroll issue #3875

Closed
Neo888888 opened this issue Apr 18, 2018 · 77 comments
Closed
Assignees
Labels
C: VDialog VDialog C: VNavigationDrawer VNavigationDrawer help wanted We are looking for community help platform specific The issue only occurs on a specific platform T: bug Functionality that does not work as intended/expected
Milestone

Comments

@Neo888888
Copy link

Versions and Environment

Vuetify: 1.0.15
Vue: 2.5.13
Browsers: Safari 11.1
OS: iOS

Steps to reproduce

show a dialog with very long height. (NOT a full screen dialog)

Expected Behavior

the background should not scroll on IOS

Actual Behavior

the background scrolls sometimes

Reproduction Link

https://github.com/

Other comments

To fix this issue:

beforeCreate Dialog
    document.getElementsByTagName("body")[0].className="noscroll";

beforeDestroy Dialog
    document.body.removeAttribute("class","noscroll");

STYLUS:
.noscroll
position: fixed
overflow-x: hidden
overflow-y: hidden

@johnleider
Copy link
Member

Please follow the guidelines on how to report an issue. In particular, provide an example on www.jsfiddle.net (or a similar service) that reproduces the problem. If necessary, create a repository for us to clone with a minimal reproduction. repositories of actual projects will generally not be accepted .

Thank you.

@Neo888888
Copy link
Author

https://vuetifyjs.com/en/components/dialogs
The last example "Overflowed" dialog would reproduce this issue on IOS safari.

@chewy94
Copy link
Contributor

chewy94 commented Apr 23, 2018

I have confirmed on iOS 11 that this does happen in safari. It seems to occur when the browser items like the url bar and forward/back buttons appear. Happens on Chrome iOS as well. I think it has something to deal with the dialog reaching the top or bottom of its content and therefore scrolling/focusing the actual page below it to keep scrolling

@Neo888888
Copy link
Author

Neo888888 commented Apr 23, 2018

Here is the way how I "fix" it:

beforeCreate Dialog
document.getElementsByTagName("body")[0].className="noscroll";

beforeDestroy Dialog
document.body.removeAttribute("class","noscroll");
STYLUS:

.noscroll
  position: fixed
  overflow-x: hidden
  overflow-y: hidden

@KaelWD
Copy link
Member

KaelWD commented Apr 29, 2018

The dialog is supposed to disable overflow when it's opened:

hideScroll () {
if (this.$vuetify.breakpoint.smAndDown) {
document.documentElement.classList.add('overflow-y-hidden')
} else {

I don't know how we can fix that if safari is somehow ignoring it.

@KaelWD KaelWD added T: bug Functionality that does not work as intended/expected help wanted We are looking for community help platform specific The issue only occurs on a specific platform labels Apr 29, 2018
@Neo888888
Copy link
Author

Neo888888 commented May 2, 2018

The key point: The class needs to be added to the "body" tag.
And maybe we need the "position: fixed" in the style.

@Neo888888
Copy link
Author

Neo888888 commented May 2, 2018

stylus:
.noscroll
position: fixed
overflow-x: hidden
overflow-y: hidden

code:
hideScroll: function hideScroll() {
if (this.$vuetify.breakpoint.smAndDown) {
document.documentElement.classList.add('noscroll');
document.getElementsByTagName("body")[0].classList.add('noscroll');
} else {
window.addEventListener('wheel', this.scrollListener);
window.addEventListener('keydown', this.scrollListener);
}
},
showScroll: function showScroll() {
document.documentElement.classList.remove('noscroll');
document.getElementsByTagName("body")[0].classList.remove('noscroll');
window.removeEventListener('wheel', this.scrollListener);
window.removeEventListener('keydown', this.scrollListener);
}

@oscar-gardiazabal
Copy link

It happens to me on iOS when dialog opens over stepper.
Maybe 'overflow-y-hidden' could be in all outside dom elements while dialog is open?
The attribute 'attach' should block scroll of attached element?

@TheRatG
Copy link

TheRatG commented Oct 9, 2018

It works for me

https://stackoverflow.com/questions/26046373/iframe-scrolling-ios-8

<div style="overflow:auto;-webkit-overflow-scrolling:touch">
    <iframe style="width:100%;height:600px" src="www.iframe.com"></iframe>
</div>

@efriedli
Copy link

Can also the issue as diagnosed by @Neo888888 and @chewy94, issue is specific to v-dialog on iOS+Safari and applying the below on v-dialog should fix it:

style="overflow:auto;-webkit-overflow-scrolling:touch"

@tsh356
Copy link

tsh356 commented Nov 16, 2018

I have confirmed on iOS 11 that this does happen in safari. It seems to occur when the browser items like the url bar and forward/back buttons appear. Happens on Chrome iOS as well. I think it has something to deal with the dialog reaching the top or bottom of its content and therefore scrolling/focusing the actual page below it to keep scrolling

To expand on this, regarding the Dialog Form example, scrolling in the dialog works fine if you touch exactly between two v-text-fields, but when you touch on any v-text-field, the actual page focuses and scrolling occurs there instead of in the dialog.

Is there any way to increase the priority of this bug? This is likely effecting a large percentage of the user base since it occurs across all iOS devices. I haven't been able to get any of the proposed solutions above to work properly.

@Pchianes
Copy link

Hello,

Any news about this issue ?
I'm having the same problem and the ticket is open since a while now.
It could be great if you can give us a dead line for solution

Thank you in advance

@KaelWD
Copy link
Member

KaelWD commented Dec 19, 2018

@Pchianes Buy me an iphone and I'll have a look

@iKoru

This comment has been minimized.

@natxocc

This comment has been minimized.

@daviesdoclc
Copy link

daviesdoclc commented Feb 5, 2019

They closed my similar issue (#6353), so I thought I'd comment over here. v-toolbar and v-bottom-navbar also cause scrolling of the content area if those components are "fixed" . In that case there is no opportunity to turn off scrolling on the body because they don't become active. They are always active.

I just wonder what the root problem is? What did Apple change that is causing this to happen? I had to resolve this in a similar way in a non-Vue/Vuetify app as well. Seems very janky.

Oh... and maybe I missed it, but the navigation drawer does the same thing too.

In fact, you can go to vuetifyjs.com on your iOS browser and the overlay area is scrollable when the menu drawer is open.

@KaelWD
Copy link
Member

KaelWD commented Feb 5, 2019

Can some more of you iOS guys check if #6280 solves the problem?

@daviesdoclc Scrolling on toolbars and bottom nav is meant to happen, your issue was closed because the navigation drawer uses the same mechanism as dialogs to prevent scroll on the body. As I noted in my previous comment, we do set overflow to hidden on mobile, so I have no idea why this is happening.

@daviesdoclc

This comment has been minimized.

@KaelWD

This comment has been minimized.

@daviesdoclc

This comment has been minimized.

@KaelWD

This comment has been minimized.

@jameshhood
Copy link

I have been reading through the comments and it sounds like this still hasnt been figured out yet. I've been working on getting my app up to speed with 2.0 and getting it into a cordova app and the first thing I noticed that was 110% broken was dialogs. I wrap the dialog component up in my own component so I can add a "scrollable" area for the default slot so the actions are always visible. As several have mentioned, if I touch/scroll from white space on the dialog, it works just fine, but initiating it from a text field or the actions area causes the whole body to scroll as well. I'm currently looking into using something like https://www.npmjs.com/package/body-scroll-lock but I would almost assume that vuetify should have issues like this handled natively 🤷‍♂

@masay421
Copy link

masay421 commented Sep 5, 2019

Hi,
This is my solution using body-scroll-lock.

<template>
  <v-dialog v-model="dialog" persistent scrollable>
    <v-card class="dialogCard">
      <v-card-title>
        Dialog Title
      </v-card-title>
      <v-divider />
      <v-card-text class="modal">
        Dialog Contents (e.g. v-text-field)
        ...........
        ...........
      </v-card-text>
      <v-divider />
      <v-card-actions>
        <v-row justify="center px-5" align="center">
          <v-col cols="6">
            <v-btn block  @click="close">
              No
            </v-btn>
          </v-col>
          <v-col cols="6">
            <v-btn  block  @click="close">
              Yes
            </v-btn>
          </v-col>
        </v-row>
      </v-card-actions>
    </v-card>
  </v-dialog>
</template>
import { disableBodyScroll, clearAllBodyScrollLocks } from 'body-scroll-lock'

export default {
  data: ()=>({
    dialog: false
  }),
  methods: {
    open(){
      const modal = document.querySelector('.modal')
      disableBodyScroll(modal)
      this.dialog = true
    },
    close(){
      clearAllBodyScrollLocks()
      this.dialog = false
    }
  },
  beforeDestory() {
    clearAllBodyScrollLocks()
  }
}
<style lang="sass" scoped>
.modal
  -webkit-overflow-scrolling: touch

.dialogCard
  ovarflow-y: hidden 
</style>

@johnleider
Copy link
Member

@jameshhood We are most definitely looking for some help on this one if you have any advice.

@jameshhood
Copy link

@johnleider I'm not sure I'd be the best person to ask about framework architecture lol but I'd almost recommend to pass a prop to v-content to allow your user base to determine whether or not they want to auto-apply these iOS only fixes. I mean obviously a framework cannot meet everyones expectations but with this being a very common css problem on iOS platforms, I would either add a 3rd party solution with documentation on how to use it or wrap up css functionality sort of like the print css classes y'all added. Mobile development is very tricky but a very demanding platform these days. I'd almost recommend having documentation section dedicated to how y'all recommend using your components on a mobile platform.

@Ju66ernaut
Copy link

@BlackFox00 check out my demo at https://codepen.io/funkyvisions/full/drBbYW (open on iOS device)

The box list should be scrollable in the y direction. Tap any of the boxes and a dialog should come up.

With the .v-overlay rule commented out, you'll see the background is scrollable behind the dialog. Add it back in and the .v-overlay rule prohibits this. On Android it makes no difference.

The root of the problem is that if you mark your scrollable areas as touch (to give a more natural feel), iOS seems to have an issue with touch events bleeding through.

Hope that helps.

I could not get this to work in an older (v1) cordova app with the above solution.
Has there been any movement on this? Or maybe an alternative?

@Ju66ernaut

This comment has been minimized.

@egeersoz

This comment has been minimized.

@SmelayaPanda
Copy link

SmelayaPanda commented Dec 6, 2019

I use such a mixin for the full-screen dialogs that opens during scrollable content.

dialog-save-scroll.js

import smoothscroll from 'smoothscroll-polyfill'

smoothscroll.polyfill()

export default {
    watch: {
        dialog(open) {
            if (open) {
                document.body.style.top = `-${window.scrollY}px`
                document.body.style.position = 'fixed'
            } else {
                const scrollY = document.body.style.top
                document.body.style.position = ''
                document.body.style.top = ''
                window.scrollTo({top: parseInt(scrollY || '0') * -1})
            }
        }
    }
}

MyDialog.vue

    import dialogSaveScroll from '../../../mixins/dialog-save-scroll.js'

...
        mixins: [dialogSaveScroll],
        data() {
            return {
                dialog: false
            }
        }
...

@Ju66ernaut

This comment has been minimized.

@theavijitsarkar

This comment has been minimized.

@egeersoz

This comment has been minimized.

@jameshhood

This comment has been minimized.

@theavijitsarkar

This comment has been minimized.

@zachu90

This comment has been minimized.

@johnleider
Copy link
Member

I understand the frustration with something you want resolved not being on the list of actionable items. Ideally we would be able to keep up with issues but this year has thrown a wrench into the plans.

The last time I was in this thread, I asked for advice/help in solving the issue: #3875 (comment) . In addition, this issue has been marked as help wanted for a very long time and I really meant it when I selected that label.

Rest assured, we will get this issue addressed; I appreciate everyone's patience and thank you for using Vuetify.

@egeersoz
Copy link

@johnleider That is of course understandable, but this isn't merely something we "want resolved" — the message many of us have been trying to convey is that this bug makes v-dialog and v-navigation-drawer completely unusable in iOS, especially in devices with small screens, or when held in landscape mode. I know you asked for help, but that was more than a year ago, and since then not a single member of the Vue.js team has commented on this issue or made any other indication that they started working on it. In the meantime, issues that should be viewed as much, much lower priority continue to get resolved with each minor patch. I'm not even frustrated anymore, I just stopped using Vuetify in any app that I know will have mobile users, which is a shame because I love everything else about the framework.

@hobbsi

This comment has been minimized.

@jameshhood

This comment has been minimized.

@daviesdoclc
Copy link

@daviesdoclc Your solution only works when the dialog contents are just text. More complex dialogs (such as those containing v-text-field components) get their scroll behavior broken.

Example here: https://codepen.io/ersoz/full/zXOzVP

You'll note that the first dialog doesn't have background scrolling (as per your fix) but the second dialog's scrolling behaves oddly. Specifically, scrolling inside the dialog works only if you "grab" one of the green boxes and drag up/down. If you happen to grab one of the text fields, no scrolling occurs.

I'm not sure what issue you are seeing. Your example seems ok on iOS to me. I've been using my solution (#3875 (comment)) for quite a while in our iOS mobile app with success.

@MentalGear
Copy link

MentalGear commented Nov 22, 2020

Indeed, it's strange that this hasn't been fixed yet. For my use case, I was able to fix the long dialog over scroll with the following css:

  /* v-dialog overflow fix */
  .v-dialog {
    overflow: hidden;
  }

  .v-dialog .v-card {
    overflow: scroll;
    height: 100%;
  }

Keep in mind that this isn't exhaustively tested, but feel free to check it out and it might work for you as well.

@kierendev
Copy link

I was able to prevent this issue by setting touch-action to none on .v-overlay--active

.v-overlay--active {
  touch-action: none;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C: VDialog VDialog C: VNavigationDrawer VNavigationDrawer help wanted We are looking for community help platform specific The issue only occurs on a specific platform T: bug Functionality that does not work as intended/expected
Projects
None yet