Vuetify: 1.0.15
Vue: 2.5.13
Browsers: Safari 11.1
OS: iOS
show a dialog with very long height. (NOT a full screen dialog)
the background should not scroll on IOS
the background scrolls sometimes
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
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.
https://vuetifyjs.com/en/components/dialogs
The last example "Overflowed" dialog would reproduce this issue on IOS safari.
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
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
The dialog is supposed to disable overflow when it's opened: https://github.com/vuetifyjs/vuetify/blob/dc9b296533debb5b2e493164149146986eb379f7/src/mixins/overlayable.js#L178-L181
I don't know how we can fix that if safari is somehow ignoring it.
The key point: The class needs to be added to the "body" tag.
And maybe we need the "position: fixed" in the style.
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);
}
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?
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>
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"
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.
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
@Pchianes Buy me an iphone and I'll have a look
Hello, Any news here?
I have the same problem with IOS 12 on my Iphone 5 SE.
They closed my similar issue (https://github.com/vuetifyjs/vuetify/issues/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"
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.
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.
Hmmmm. Having the content area scroll when I drag my finger off a navbar item (because I decided not to select it) does not seem like very good behavior. Native iOS and Android do not behave this way. I decided to move my toolbar and navbar outside the content area instead of being fixed inside of it. This fixes my issue because now the drags in those areas don’t bleed through.
Maybe a video will help describe the issue with the toolbar and navbar. Take a look at this.
As you can see, dragging in the toolbar and navbar both scroll the content. This is not how a native app would behave. This is using v-content and fixed toolbar and navbar.
<template>
<div>
<v-toolbar color="white" app>
<v-btn icon>
<v-icon>menu</v-icon>
</v-btn>
<v-toolbar-title>Title</v-toolbar-title>
</v-toolbar>
<v-content>
<div class="box red"></div>
<div class="box blue"></div>
<div class="box red"></div>
<div class="box blue"></div>
</v-content>
<v-bottom-nav value="true" app>
<v-btn color="#ae2573" flat>
HOME
<v-icon>home</v-icon>
</v-btn>
</v-bottom-nav>
</div>
</template>
<style scoped lang="scss">
.box {
margin: 20px;
width: 90%;
height: 200px;
display: block;
}
.red {
background-color: red;
}
.blue {
background-color: blue;
}
</style>
If I don't use v-content and a fixed toolbar or navbar, but instead create a flex container where the content area takes over the remaining space then it works.
<template>
<div class="app">
<v-toolbar color="white">
<v-btn icon>
<v-icon>menu</v-icon>
</v-btn>
<v-toolbar-title>Title</v-toolbar-title>
</v-toolbar>
<div class="content">
<div class="box red"></div>
<div class="box blue"></div>
<div class="box red"></div>
<div class="box blue"></div>
</div>
<v-bottom-nav value="true">
<v-btn color="#ae2573" flat>
HOME
<v-icon>home</v-icon>
</v-btn>
</v-bottom-nav>
</div>
</template>
<style scoped lang="scss">
.app {
height: 100vh;
display: flex;
flex-direction: column;
}
.content {
flex: 1;
overflow-y: scroll;
}
.box {
margin: 20px;
width: 90%;
height: 200px;
display: block;
}
.red {
background-color: red;
}
.blue {
background-color: blue;
}
</style>
However, now I feel like I've deviated from the Vuetify preferred way of overlaying the toolbar and navbar (although I'm not sure v-content or v-container are requirements like v-app is).
Hopefully this help. I appreciate the fix for dialogs, drawers, etc. that are overlays. That will be a big help. Ideally it would be good to understand why these events bleed through. BTW... my video was on Chrome on the desktop. So it's not Apple specific nor touch specific.
This is not how a native app would behave
It's how a web app does (because the scroll is on the body), #2132 is for that and is an entirely separate issue.
This bug is seriously affecting usability for our users, and it's so bad that our PM wants us to ditch Vuetify. I'd rather stay with Vuetify (it's overall very well-designed and engineered) so I figured I'd chime in and see if it can be bumped up in priority.
@egeersoz @tsh356 I'll merge #6280 if you can confirm that it works. There's a staging deployment here.
Following neo888888's comment above I went to the Dialogs page of the staging site on my iPhone and tested the Overflowed example, but it continues to scroll the background when you scroll up and down inside the dialog.
(Note that it's not just dialogs that are affected. The issue also affects navigation drawers.)
And bottom sheets. I think anything with an overlay is suppose to be setting the no scroll on the body.
The #6280 fix is not working for me either (iPhone iOS 12.x)
I have a video of an app I built that demonstrates the issue. This is recorded directly on the iOS device.
https://www.dropbox.com/s/6emopdr6pkpxbv1/ScreenRecording_02-22-2019%2009-27-33.MP4?dl=0
The v-content area is scrollable when dragging in the toolbar, the navbar, the drawer, the bottom sheet, and the overlay. This is using Vuetify 1.5.2.
I'd like to try this with the patch, but for the life of me I can't figure out how to npm install it from the repo. Any help? Once I can build the actual app with it I can do a better test of this.
Thanks to @daviesdoclc for writing about this issue. I suspected it was something with Vuetify when my fixed v-bottom-nav was behaving strangely on my iOS-device. This issue has never occured on my Android-devices. My problem manifests by the fact that sometimes, quite randomly, the buttons in my v-bottom-nav stops reacting to normal touch. If I am very sensitive and touch the top of the icons it will (sometimes) work when it is in this state. If I then play around with the app it will eventually work again as normal, and then eventually happen again. I haven't been able to pin-point how, why and when the issue exactly occurs. The issue explained by @daviesdoclc is closest to describing my problem. I'm still testing to understand more and will write again if I discover anything interesting.
I have the html build as follows with four main elements:
v-navigation-drawer with the app-prop
v-toolbar with the app-prop
v-content
v-bottom-nav with the app-prop
@egeersoz @blackfox00 thanks
@daviesdoclc it's a website, that's normal. The only bit that's a bug is when there's an overlay showing. You probably want #2132 for the toolbar thing.
@solojuve1897 safari blocks the bottom 44px of every page for its own menu bar.
Hi guys, any update on this? Dialogs on the Components page (https://next.vuetifyjs.com/en/components/dialogs) which have content higher than the window all have scrolling issues on iOS. I tried fixes all afternoon and was unsuccessful. It kind of makes the dialogs unusable for a lot of cases.
BTW: This issue does not only happen on Safari. Chrome on iOS does the same.
Agreed, our app is mobile-first and this issue holding up a major release for us.
We, too, have tried all kinds of tricks and haven't been successful.
Yes. This is very bad. I'm patient though, but when Ionic is completely Vue.js-ready I will sit down and think which framework to switch to for current and future applications. By then Vuetify 2 should be out and Quasar will be another contender. Mobile-first - focus on iOS and Android - will be the top priority. Vuetify today lacks alot on that department.
I managed to make the body scrolling by adding overflow: hidden and position: fixed to the body css when dialog= true but it still keeps scrolling in the dialog not fluent and makes the body scroll to the top of the page which is not user-friendly.
I tried finding JS fixes outside of vuetify but none of them seem to work. I'm unsure if this is a Vuetify issue. It seems the Bootstrap Modal has the same problem (check "Scrolling long content"): https://getbootstrap.com/docs/4.0/components/modal/
It may not be a Vuetify issue, but IMO we should keep this open since it affects lots of people and has a high negative impact on UX. Maybe someone will find a fix or a hack and post it here.
Could it be the people at Quasar found a solution? https://quasar-framework.org/quasar-play/apple/index.html#/showcase/popups/modal
It seems their modal "With Modal Layout" scrolls fluently. The others ("Basic" and "Basic with Events") seem to not scroll the body but are also not very fluent.
I talked to some-front end developers at my work and they verified it is a known iOS issue.
One solution could be:
This is rather hacky and will probably not make the scrolling in the dialog nice and fluent.
Another possible solution is to inject the dialog in an already existing wrapper which is already position fixed. This is based on the idea that iOS has a problem handeling programatically changes in position values combined with injected elements which are also position fixed. It's a theory, not even tried.
When I have the time I’d like to investigate how Quasar made their modal work but I only use Vuetify for private projects. It might be that I will not have the time before coming weekend.
@kwindo can you try these one at a time for me?
.overflow-y-hidden body {
overflow-y: hidden
}
.overflow-y-hidden {
position: fixed
}
@KaelWD
In that case the background will be fixed at the top (´・ω・`)
Yeah I know, just exploring options. Does the first one do the same thing?
My experience has been that this has to do with "-webkit-overflow-scrolling: touch". If you set this to "auto" while the dialog is up, then things work as they should.
I have a codepen that demonstrates this: https://codepen.io/funkyvisions/pen/JzNPbJ
Tap on a first BLUE box for a non-scrollable dialog. Tap on the first RED box for a scrollable dialog. Tap on the first GREEN box to see the broken scrolling behavior (it doesn't apply the class).
I have a noscroll class I apply when the dialog is up.
-webkit-overflow-scrolling: touch is a class you apply to get smooth (and bouncy) scrolling on an iOS device. Without it, scrolling is linear and acts like Android.
Hi @daviesdoclc , I tried your pen and on my iPhone it does not scroll smoothly. The body in your pen does not scroll but when I try to do the same thing in my project the body does scroll in the background. The "noscroll" class with "-webkit-overflow-scrolling: auto !important" has no effect.
@KaelWD
Your suggested CSS behaves as expected. It stops the body from scrolling in the background but fixes it on top. Scrolling in the dialog is not smooth.
Could you guys take a look at this: https://codepen.io/kimsanka/pen/XGexJy
It's based on @daviesdoclc 's pen on which I basically just commented out some stuff.
I added a toolbar and used a full screen dialog because my application needs one but even then it scroll smooth on my iPhone and keeps the body fixed.
It's a bit hard to believe the solution is this simple so I assume I'm overlooking something.
Eyes on https://vuetifyjscom-dnwzaqmfio.now.sh/components/dialogs please
@KaelWD looks good, except for fullscreen resetting the scroll position to the top.
After looking at the diffs however... I wonder how this is going to work for those of us not using a scrollable body, but instead a scrollable child div confined to the viewport bounds?
that already isn't affected afaik
Hmmmm... my demo does https://codepen.io/funkyvisions/pen/JzNPbJ. It has a container bound to a height of 100vh and scrollable. It's how my app is laid out currently. Or are you saying that is fixed in a commit I don't have on codepen yet?
@KaelWD's link seems to work fine for me on iOS 12.1.
@daviesdoclc Yes, I also noticed the fullscreen dialog resetting the scroll position.
I see one issue with this, if I close the dialog and immidiately start scrolling, my position is resetted to the top. If I wait a bit (1s, basically until the red circle action button appears again), then it's ok. (iOS 12.x)
I'm now using this with success:
.v-overlay ~ div .scrollable-y, .v-overlay ~ div .scrollable-x {
-webkit-overflow-scrolling: auto !important;
}
.scrollable-x {
overflow-x: scroll;
overflow-y: hidden;
-webkit-overflow-scrolling: touch;
}
.scrollable-y {
overflow-y: scroll;
overflow-x: hidden;
-webkit-overflow-scrolling: touch;
}
I add scrollable-x(y) to the DIVs I need to be scrollable. When the overlay comes up, this prevents the webkit-overflow-scrolling touch items to not be scrollable (which seems to be the root of the problem at least for me).
@daviesdoclc can you please elaborate? on what elements should I apply scrollable-x/y
class in case of v-dialog?
@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.
@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 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 🤷♂
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>
@jameshhood We are most definitely looking for some help on this one if you have any advice.
@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.
@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?
I also could not get @masay421 solution to work.
After spending a ridiculous amount of time trying various workarounds and hacks, the solution I came up with was "don't use v-dialog if you will have iOS users".
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
}
}
...
I have another issue similar to this with a <v-select>
component that has US States and when it is tapped open, you can not scroll down the list of states. The background scrolls instead. This is in a cordova app. #6353 brought me back here
Using vuetify for hybrid app projects is becoming quite difficult due to the lack of optimisation on iOS. We spent months on developing, only to find that in iOS there are a lot of bugs.
For example if we have a dropdown on a full screen popup, and someone clicks that, the background starts scrolling. At times if the dropdown does not close either. Requesting the makers of this fantastic platform to take a look at ios issues.
Any updates on this issue? Can it please be bumped in priority?
@egeersoz This has been open for 2 years now on a framework that gets updated pretty much weekly. Sad to say, but I don't think mobile is too much of a priority for them.
Ya, I am pretty much screwed by implementing this in my app. Now I cannot undo almost a year of work.
Any update on this guys?
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: https://github.com/vuetifyjs/vuetify/issues/3875#issuecomment-528440445 . 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.
@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.
I'm new to Vuetify and I was really pleased with it up to this point. This is the first major issue I've encountered... The fact that this ticket has been under the open state for over two years now, just makes me reconsider the framework for future projects. I'll try some of the workarounds given here. Thank you everyone for the tips.
I feel like issues like these should be posted/broadcasted by vue.js members in the discord under help or somewhere appropriate to inform people that these issues exist. The average persons' goals are not to surf the repo for "Help Wanted" flags and see if they can contribute to the project. They are to work on their own product and if they find a problem, check if someone else has a solution and drive on. @johnleider @KaelWD
@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 (https://github.com/vuetifyjs/vuetify/issues/3875#issuecomment-477148151) for quite a while in our iOS mobile app with success.
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.
Most helpful comment
@Pchianes Buy me an iphone and I'll have a look