Closed rgthree closed 3 years ago
@rschmukler
+1
+1
@rgthree can you please check if it's still happening on HEAD?
@EladBezalel I don't know about @rgthree, but I just checked against HEAD and the issue is still very much there for me. Happy to provide as many details as I can/you require.
Can you please post a codepen(not jsfiddle)?
Couldn't reproduce this with a codepen (including it anyway, in case it might prove useful). I'll keep trying to reproduce the issue, but in the meantime, here are a couple screenshots of the problem taken from the app I'm working on. The pictures include the position of the scrollbar when it works (only at the very top) and when it doesn't (anywhere when scrolled down).
This could be an isolated issue. Maybe someone else can shout out if they've experienced the same problem so you don't waste time tracking something that might be due to my individual config?
@ngasst all you had to do is adding disableParentScroll: false
to reproduce it
http://codepen.io/EladBezalel/pen/OyvdBN
the question is, why you wouldn't like to disable parent scroll
Very strange. The behavior is indeed reproduced by setting the disableParentScroll to false in the codenpen. But I didn't set it in my actual code, and my understanding is it defaults to true when not set. Here's the options definition from my ModalService. It's in TypeScript, but essentially not much changes:
export class ModalService implements IModalService {
static $inject: Array<string> = ['$mdDialog'];
options: ng.material.MDDialogOptions;
constructor(
private $mdDialog: ng.material.MDDialogService
) {
//
}
open(template: string, controller:string, event?: MouseEvent, data?:any, animcb?:any, ctlAs?:string) {
this.options = {
templateUrl: template,
targetEvent: event,
controller: controller,
locals: {
data: data
},
bindToController: true,
controllerAs: ctlAs ? ctlAs : 'vm',
onComplete: animcb
};
this.$mdDialog.show(this.options)
.then(() => {}, () => {});
}
A little bit more information about this:
For whatever reason, when the dialog is triggered after a scroll, the body receives a top positioning equivalent in pixels to the scrolled distance (if that makes sense -- i.e.: I scroll 889 pixels down, the body receives {[...]; top: -889px}
). Now, I see that this comes from the scrollTop function on the $mdUtil service. I have enough to manage a dirty fix, but not the right contextual experience with the implementation to offer a permanent solution.
And I still don't know why I seem to be the only one affected by this. Will dig some more and report back if I have something worth sharing.
Hi,
I have the same problem. After a scroll, the top property of body is set to a negative value when the modal is shown, thus hiding some content of the body. @ngasst can you share your temp workaround?
@bampakoa,
Please find a sample of the code below. Maybe it'll be useful in finding a more universal fix? I'll walk through what the code does because, like I said above, it's TypeScript, and I know that not everyone uses that, so...
My fix implies having a wrapper service that takes responsibility for opening all modals in your app. If that service has an open function, you use it to get the value of the scroll position and store it (you actually need to store it, because it'll change as soon as the modal is invoked). To get that value, you can use the useful but undocumented $mdUtil service. Then you select the body and set its style to {position:fixed; top: 0; height:100%; width:100%;}
. I use D3 because I'm already using it for other stuff in the app and it's already loaded, but you can use JQuery or even plain JS for this.
That corrects the issue and lets the modal be positioned correctly. But you need to cleanup once you close the modal. That's where the onRemoving
event comes in. You give it a callback and use whatever method you want to set the body style to {height:100%;}
and just to be fancy, you can get the scroll position, which you stored earlier, and use $window.scrollBy()
to go back to whereverfrom you triggered the modal, otherwise it'll default to the top of your app -- which may or may not be what you're going for.
Here's the code.
export class ModalService implements IModalService {
static $inject: Array<string> = ['$mdDialog', '$mdUtil', '$document', '$window'];
options: ng.material.MDDialogOptions;
scrollAmount: number;
constructor(
private $mdDialog: ng.material.MDDialogService,
private $mdUtil: any,
private $document: ng.IDocumentService,
private $window: ng.IWindowService
) {
//
}
open(template: string, controller:string, event?: MouseEvent, data?:any, animcb?:any, ctlAs?:string) {
this.scrollAmount = this.$mdUtil.scrollTop(this.$document[0].body);
d3.select('body').style({
position: 'fixed',
height: '100%',
width: '100%',
top: '0'
});
this.options = {
templateUrl: template,
targetEvent: event,
controller: controller,
locals: {
data: data
},
bindToController: true,
controllerAs: ctlAs ? ctlAs : 'vm',
onComplete: animcb,
onRemoving: () => {
d3.select('body').attr({style: 'height: 100%;'});
console.log(this.scrollAmount);
this.$window.scrollBy(0, this.scrollAmount);
}
};
this.$mdDialog.show(this.options)
.then((scAmount) => {}, () => {});
}
close() {
this.$mdDialog.hide();
}
}
@ngasst thanks for your tip!
I don't see it much of an issue, disableParentScroll
default value is true and the developer should be aware of disabling this.
@robertmesserle @topherfangio can you guys say your thoughts about it?
Just to share a workaround on this, through css:
.md-dialog-is-showing {
max-height: none;
}
I do not know if it can be applied globally, but it seems to work in my occasion.
I am experiencing this and looking at the demo, it is exactly what I get. When opening a dialog after scrolling the view a white bar shows up at the bottom of the view. The size of the bar is equivalent to how much the view was scrolled. This is especially troublesome because, just like the demo, I do not have disableParentScroll set to false. However, setting the overflow to initial for the app body did indeed fix this issue.
@rgthree where you able to solve the issue.
Also having this problem within my entire project
Also having this issue, able to solve it by overriding css positioning which seems like a hack . Will be good to get a permanent fix. I am using v1.0.6. Thanks.
@animesh1987 - Are you able to provide some code that solves this issue?
Has anyone been able to solve this. I am having the same issue
@zilions were u able to find a fix for this issue?
not sure if this is a true fix, but this seemed to do the trick for me:
body { overflow-x: visible; }
@lexyfeito - No fix from me yet. Tried everything in this thread and nothing seems to work well.
@zilions same here this is getting really annoying
@zilions hey so after reading @abouillon comment i set the body overflow: initial;
and it seems to fixed the problem.
@lexyfeito That's what I was going to suggest, but I was also trying to see if there was a workaround if someone was using the parent option and setting the parent container of the dialog to something other than the document body. So far I haven't found a quick workaround if a user sets the parent to something other than body. Luckily, in my use case, we just let material set the parent container to the document body, but it would be nice if there was a workaround for those who need the parent to be something else.
I managed to solve my issue today, after hours of digging into code and work arounds. Thought I'd share for anyone else that is struggling with the same problem.
.md-dialog-container { height: 100vh !important; top: 0 !important; position: fixed !important; }
@zilions did setting body overflow to initial didnt do the work for you? This seems like a lot of more work
@lexyfeito - It did not work in my case unfortunately. Most of my content is absolute positions, so it's probably a different layout to most other sites. The code I posted above is the only way I could get it to work for me.
@zilions oh well i am glad you found a fix/workaround at least :)
@akashjarad, @abouillon, @zilions: FWIW, you can isolate the workaround by using .md-dialog-is-showing
which is appended to the body when a dialog is showing. This seems to fix it for me while still allowing me to use overflow-y: scroll
when a dialog is not shown.
body.md-dialog-is-showing {
overflow: visible !important;
}
You should keep in mind that this and the other fixes mentioned, while fixes our problems right now, could introduce issues going forward. Clearly, Angular is expecting body to be overflow hidden.
@rgthree you are right and it does work it my case thank you so much for your suggestion.
@rgthree hey man this fixed/workaround doesn't seem to work on IE. Does it happen to you to?
I'm having this bug too. Thank you @rgthree for the fix.
@rgthree Sir, you are such a big help! Thanks for the fix!! I have been digging the internet for hours to get this fix.
Just ran into this bug with codes on master branch. It's really wired.
thanks @rgthree fixed my issue !
This was closed but still seems to be an issue on master. Using the suggestions above @rgthree & @zilions helped fix it for me. I'd just like to know if there is going to be an official solution for this? Thanks.
@rgthree Your solution helped me so much! Can't thank you enough!
@rgthree the solution is very helpful. Thank you. On top of this solution, in my case, I have some navigation bars that are not scrollable and the rest of the page has {overflow-y: scroll}. To completely make it work, I added {top: 0px !important;} to those navigation bars.
thanks @caradong this bit was missing in my case. apply explicit top value to all fixed elements
I don't see any specific version that this was reported against here in the issue report. I also don't see any mention of this being browser-specific.
I guess it was seen in a version around v1.0.0. I tried http://codepen.io/EladBezalel/pen/OyvdBN with master
(1.2.1+), 1.0.0
, and 0.11.0
on macOS with Chrome 87 and I wasn't able to see any strange behavior or the dialog appearing partially off screen.
I'm going to close this. If you are still seeing this issue in AngularJS Material 1.2.1, please open a new issue with an updated StackBlitz or CodePen reproduction.
Fiddle: http://jsfiddle.net/rgthree/9m7z8cqy/
If body has any
overflow
applied by the app, angular overrides its style tohidden
when the dialog is open. This clashes with the other styles added to body, particularly,position: fixed; top: -XXpx;
andmax-height: 100%
from themd-dialog-is-showing
class which ends up cutting off the body content or completely hiding it when the window has scrolled more than 100% the height.Note, we use
body {overflow-x:scroll;}
to force a scrollbar and reduce horizontal jitter when page content height changes due to navigation.