Closed (fixed)
Project:
Drupal core
Version:
11.x-dev
Component:
javascript
Priority:
Normal
Category:
Bug report
Assigned:
Reporter:
Created:
15 Apr 2016 at 17:35 UTC
Updated:
26 Aug 2025 at 07:58 UTC
Jump to comment: Most recent, Most recent file
Comments
Comment #2
droplet commentedYou do need some padding to left (or right) to avoid element shifting. Check bootstrap's modal as example :)
Comment #3
samuel.mortensonThanks @droplet, I'll look into that. I found another bug in my patch where some modals were not calling closeDialog() when closing, which means that the body remained locked even after a modal was closed. You can see this by going into WYSIWYG, changing the text format to "Full HTML", and agreeing to the alert about unsafe markup.
We'll probably need to subscribe to the jQuery UI Dialog events globally (on $(window)) and add a class instead of inline CSS, which would let specific themes override our assumptions about what CSS rules are best for accomplishing this.
Comment #4
samuel.mortensonHere's a new patch which uses classes instead of inline CSS, and adds a position: fixed rule to body to prevent shifting.
Comment #5
droplet commentedThanks.
but this trigger `body` scrolls back to the top.
were not calling closeDialog() when closingYeah, that's a case. We created our implement in Drupal.dialog and that's too easy to be overridden.
Comment #7
samuel.mortensonAh position: fixed was probably not needed then - I understand now that you meant shifting due to the scrollbar disappearing, which Bootstrap handles by adding an arbitrary margin when locking body down. I'm looking into solutions for this now.
Edit: See https://github.com/twbs/bootstrap/issues/9855 for the Bootstrap history of this
Comment #8
samuel.mortensonThis is going to make this issue harder to review, but the new patch prevents scrolling while dialogs are open as modals as well as preventing shifting of body elements due to the scrollbar disappearing. To accomplish this I copied code from https://github.com/twbs/bootstrap/blob/master/js/modal.js and https://davidwalsh.name/detect-scrollbar-width, as Bootstrap has iterated on this logic for awhile now.
I haven't specifically credited these sources in the patch, but am happy to do so if there's a standard comment in core for this. Also, if this added complexity is unwanted in core and people are happy with the body shifting when a modal is open, I can go back to the most simple patch (which is just the overflow: hidden rule).
Comment #9
droplet commentedGreat! I have a quick testing and it works as expected. I will run through the code review soon. and hope somebody able to have a 2nd review also :)
We don't support IE8 in D8.
Comment #10
wim leersIs it not enough to just cancel the bubbling of scroll events on the dialog?
Comment #11
Bcwald commentedTested in administration theme from dialogs prompted from both WYSIWYG, Views, and fields triggering a dialog. I also tested it on the frontend where the theme is calling the jquery UI Dialog, both worked as intended. I also tested manually closing and 'esc' key closing.
Comment #12
droplet commented@Wim,
I'm afraid not. You can't cancel `document` level scroll event. You can prevent mouseEvent, or touchEvent but can't disable native scrollbar scroll interactive.
You may able to set:
But it leads to performance & flickering issue I believed.
Alternative way is set `body` to
position: absolute;(It's slightly better thanposition: fixed;.) However, it really works for a pre-designed site only. Not scalable for a framework. eg. Facebook uses that technique. For all other sites, we can't predict how the body & inner elements styling, that would trigger more elements shifting & reflow.I hope I'm wrong because that would be less code :)
Comment #13
wim leersI figured that what I said in #10 would not be possible, because such an obvious, simple solution would of course have been tried first. Just wanted to double-check. Thanks!
Comment #14
yoroy commentedAdding #2672344: [UX] Open as Modal should not able to interact with other elements as related
Comment #15
nod_I don't agree with the issue.
The
<dialog>spec doesn't say scrolling should be disabled when a modal is open. And so far neither firefox nor chrome prevent scroll on modal open: http://demo.agektmr.com/dialog/ Since the dialog element was intended are more or less a polyfill for this element, I don't think we should add code for this.Comment #16
droplet commentedSounds right by reading the SPECS. Anyway, only Chrome supported `dialog`.
So now, the question is "Do we need it for Drupal? and any UX problems by this change?"
It's all about how we code and we think.
A. We can hook it into `dialog.beforecreate` event. In this way, we are changing other elements in the standard way, not the standard dialog itself.
B. We can think that Drupal.dialog is our custom API for dialog than a polyfill, we doing extra scripting before trigger `show` event. We doing that now, dialog.postion.js is an example. ( we also changing the A tag, Submit buttons ..etc ).
** the main point is all our changes should be adaptable to HTML 5.1+ standard in future.
Comment #17
yoroy commentedI don't see usability reasons to prevent scrolling in the underlying page.
Comment #18
droplet commentedThere's one little problem is,
in macbook like devices, that's no visible scrollbar. When you are using touchpad to scroll it in non-scrollable area, the bg will be moved. after closing the modal, you will get a different screen. that may confusing users if their actions inside the modal changed the main screen contents.
By HTML SPEC, dialog scrolling with the page by default .
Comment #19
Bcwald commentedI recommend trying the patch, it addresses the scroll bar issue.
Also, I recommend this be added as an option in appearance/settings (global settings) for the site administration to choose if they want to disable scroll or not. In most cases a scrolling background makes no logical sense. If the background page is greyed out, it means it's inaccessible to the user until an action is taken.
Comment #20
yoroy commentedThe patch works fine, and it does feel more natural to not have scrolling in the background. We do not want to make this a setting, that would just add clutter to the admin interface for a very minor feature that will be hard to explain what it even does. We should come to a decision and act on it. It seems better to me to follow relevant specs than fix a potential usability problem that we don't even know it exists.
Comment #21
Bcwald commentedfair point on the checkbox being confusing.
I am having a hard time understanding how it's not a usability problem. The modal applies an overlay over the entire site outside it's contents, making anything behind it unusable. having something scroll behind suggests that actions can be taken on the page outside the modal (like browsing the page, for example) which is not true.
Comment #22
droplet commentedRecall for UX feedback before my code reviews and improvement. Thanks
Comment #27
brooke_heaton commentedThis does not patch clean against 8.6.x-dev.
Comment #28
brooke_heaton commentedComment #30
dubcanada commentedUpdated patch for 8.6
Comment #31
sasanikolic commentedHere's the updated patch for 8.6 based on @samuel.mortenson changes.
Comment #32
idebr commentedComment #34
sasanikolic commentedAlso to note, I just figured that there is a bug on iOS that makes the body scrollable when the keyboard is opened - in a case when we have a form inside the modal. Somehow, in this case, the fix with overflow: hidden does not apply. I didn't find a proper solution to this yet.
Comment #35
kostyashupenkoWe can't just set "overflow: hidden;" for body tag, because it doesn't work on Safari browser on all devices (iphone, ipad, mac, whatever) -> for such devices "position: fixed;" works good.
So need to think how to implement only one fix, but globally. This is common issue with dialog popups, for now to fix such issues i use additional js that calculates offset between top of page and top of your current window position, then "position: fixed;" for body tag + "top" property with negative value, like
But need to be careful when you are under admin user and you have toolbar on the top + default padding-top for body coz this toolbar. So need to find simple solution for all cases.
Comment #36
hj-b commented@sasanikolic thnx! #31 works fine for me against 8.6.2
Comment #37
kostyashupenkohttps://github.com/willmcpo/body-scroll-lock works perfect in all browsers
How we can put it in drupal?
Comment #38
droplet commentedEnjoy it, my friend:
https://www.drupal.org/project/body_scroll_lock
Comment #41
indrajithkb commentedComment #42
indrajithkb commentedThese all fixes are done with this module ( https://www.drupal.org/project/modal_page ) except ipad, iphone.
replace this
with
will fix the issue.
Comment #44
indrajithkb commentedComment #45
komalk commentedComment #46
komalk commentedComment #48
Vidushi Mehta commentedAdded a patch which pointed #42.
Comment #51
dieterholvoet commentedRe-rolled for 9.2.x.
Comment #52
ankithashettyFixed custom command failures in #51 patch, thanks.
Comment #53
suresh prabhu parkala commentedTried to solve the custom command failures.
Comment #54
ranjith_kumar_k_u commentedTried to fix the custom command failure
Comment #55
ranjith_kumar_k_u commentedanother try
Comment #57
wellsConfirming patch in #51 (misnamed as #49) applies and still resolves this issue in 9.2.0.
Comment #59
dwisnousky commentedTried to solve the command failures.
Comment #60
dwisnousky commentedTried solving command failures again
Comment #61
dwisnousky commentedComment #62
gauravvvv commentedRe-rolled patch #61, Attched interdiff for same. Added missing dialog.es6.js file and re compiled. please review
Comment #63
gauravvvv commentedIgnore above patch, it consists yarn update changes.
Comment #64
nod_We have a css property that can help because this seems like a lot of code.
https://css-tricks.com/almanac/properties/o/overscroll-behavior/ it doesn't work on safari thought. I would try to go this way and find a safari-specific polyfill.
Comment #65
droplet commented@nod_
both are diff cases I think. CSS one is prevent accidental scroll, this patch is prevent intended scroll (you have no way to scroll the body anymore) also.
both may also be needed.
(and needs mobile touching testings)
Comment #66
droplet commentedalso,
even more code is needed
https://www.drupal.org/project/body_scroll_lock
Comment #67
megha_kundar commentedFix for jenkins build
Comment #68
megha_kundar commentedComment #70
anybodyRe #64
Update:
Safari is green now from v16 on!
Shouldn't we at last add a body class, indicating the modal is open and go on with everything else then? I guess that would be helpful in many projects and perhaps we can already agree on that? (This is open since 2016 ...)
Comment #71
berliner commentedAdding a body class would be great. That's not intrusive and still allows each site to have a fixed background with minimal effort.
Comment #73
darvanen#68 since I had to ask about the error it stands to reason that others here probably would have to as well. It's not a very well worded error.
effectively means: dialog.js should match the output of
yarn build dialog.es6.jsAlso, #67 and #68 are missing the new css file.
#64 I've done some testing and sadly overscroll-behavior doesn't completely block the body from scrolling AND it ONLY works if there's a scrollbar inside the modal /sadface
A colleague suggested the new
inertattribute but that only blocks clicks, not scrolling.Comment #74
darvanenHere's a patch against 9.4.x.
I can't provide an interdiff because I used bits and pieces of different prior patches and effectively rewrote it by hand. The .js file is now properly compiled from the .es6.js file.
I found the 'position: fixed' CSS reset the scroll position of the body so I used 'overflow: hidden' instead.
Comment #75
darvanenScrollbar measurement doesn't work yet.
Comment #76
darvanenThis should do the trick. I note that it leaves a strip of transparent space in place of the scrollbar. Not sure if that's the best thing to do.
Comment #77
darvanenForgot to remove the unnecessary CSS. Third time's the charm?
Comment #79
darvanenReally don't need a library just for one line of CSS.
Comment #80
darvanenArgh, apologies for the spam, found another issue with the patch. Overflow style should only be applied for modals, not all dialogs.
Comment #82
darvanenManual testing of the first failure shows it's working fine. I think there may be a quirk in how the test driver looks for visible content?
Comment #83
darvanenAsked around in #bugsmash on Slack and @ambermatz and @mstrelan both agree with me that this is a usability bug, not just a feature request.
Comment #84
darvanenDiscovered a small issue with removing the body padding style.
Comment #85
darvanenThanks to @mstrelan for the chat on slack where they pointed out that getText() is intended only for visible text as per the documentation
This means that it should not be used for the live-announce system which is where these tests are failing.
For illustration purposes I'm uploading a patch which passes those tests locally.
I assume this is a big enough scope creep to warrant a separate issue so I'm going to go make one now and then postpone this issue on it.
Comment #86
darvanenHahaha, of course. As soon as I finish with that comment I discover via #3087213: Create a test trait for assertAnnounceContains and assertAnnounceNotContains that there's already a standard for
assertAnnounceContains.New patch uploaded which alters the failing tests to use that instead.
I'm no longer sure this needs a separate issue for the test updates.
Comment #88
msuthars#86 patch re-rolled for core 9.5.x.
Comment #89
msutharsPatch #86 re-rolled again for core 9.5.x, forgot to add tests.
Comment #90
bosmaen commentedFor 9.5.x going off what #51 created.
Comment #91
bosmaen commentedComment #92
matroskeenWhat was the reason to create a patch in #90? It doesn't have tests, and more importantly - it's not working because if this line:
bodyshould be prefixed with$I'm hiding the patch anyway because it should not be applied.
Comment #93
robin.houtevelts commentedOthers seeing this: Dont apply #90
As said by Matroskeen: It breaks dialogs.
Comment #94
gauravvvv commentedUpdating attributions
Comment #95
bnjmnmTagging field UX as those efforts will likely increase the use of dialogs.
Comment #96
eugene.britRe-roll #89 for 10.0.x
Comment #97
lauriiiComment #101
utkarsh_33 commentedComment #105
narendrarI was not able to test this MR until I removed if condition from
`
if (scrollBarWidth > 0) {
document.body.style.paddingRight = `${bodyPad + scrollBarWidth}px`;
}
`
as I was getting scrollBarWidth == 0.
Comment #107
hooroomooComment #108
smustgrave commentedHiding the patches as they aren't relevant anymore
Testing MR 4131
Confirmed the issue by opening up Media Library in the ckeditor and placing my cursor outside the modal and I can scroll
Applying the MR and that issue has gone away.
Seems a few committers have been on this thread but to me seems the changes for assertAnnounceContains were out of scope of this issue.
Comment #109
lauriiiThere's a regression with Android Chrome as a result of this change. Added screenshots for before and after.
Comment #110
lauriiiIt looks like the module mentioned in #66 is using https://github.com/willmcpo/body-scroll-lock. Maybe we should consider adopting that too?
Edit: Looks like the that library is abandoned. We could consider adopting one of the forks, e.g. https://github.com/tuax/tua-body-scroll-lock or https://github.com/rick-liruixin/body-scroll-lock-upgrade. It seems a fairly small UI library so even if we had to fork it ourself, wouldn't probably be the worst thing.
Comment #111
utkarsh_33 commentedComment #112
utkarsh_33 commentedComment #113
smustgrave commentedNow that we are adding a new vendor asset. Think the issue summary could be updated to include that. Also do we need a change record that a new asset is being added?
Comment #114
utkarsh_33 commentedTested it for IOS in safari browser.The body level scrolling is locked for IOS.Attached the screenshots which i tested.
Comment #115
utkarsh_33 commentedTested it for android.The body level scrolling is locked for android also.Attached the screenshots which i tested.
Comment #116
utkarsh_33 commentedUpdated issue summary.
Comment #117
utkarsh_33 commentedComment #118
utkarsh_33 commentedComment #119
smustgrave commentedFor change record.
Comment #120
nathan tsai commentedLatest diff:[Ah shucks, the latest diff doesn't apply to Drupal 10 :(]
Comment #121
nathan tsai commentedComment #122
lauriiiDiscussed with @catch on Slack to confirm that from release management standpoint it would be acceptable to use one of the libraries proposed in #110. Since we are not 100% confident about any of the libraries, @catch recommended that we add the library as an asset of the dialog library to reduce the risk of someone using this as an API.
Discussed with @bnjmnm to get his take on which of the libraries we should use from #110, and he recommended that we compare the more-current but less-used https://github.com/rick-liruixin/body-scroll-lock-upgrade against the original library and verify the changes are fine. This would help rule out issues that might have been already-discovered if it had more usage. Also, since the library doesn't break BC, it might provide us an option of going to one of the other forks if this one doesn't work out well.
Comment #124
hooroomooLooked at https://github.com/rick-liruixin/body-scroll-lock-upgrade with @lauriii and concluded that we currently can't use that library since we can't import from esm files in Drupal, there is no UMD release provided, and bundling it ourselves to make it compatible feels like overkill for this issue. I filed an issue requesting a UMD file.
But for now we can probably just move forward with the original MR4131 that uses tua-body-scroll-lock.
Comment #125
needs-review-queue-bot commentedThe Needs Review Queue Bot tested this issue. It no longer applies to Drupal core. Therefore, this issue status is now "Needs work".
This does not mean that the patch needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.
Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.
Comment #128
lauriiiI don't know what is going on with the MR's since neither of them seems to have the right commits 🤔. I guess we need to start from the patch in #120 again?
Comment #129
smustgrave commentedCould the changes from the 2 MRs be documented to be added to the patch?
Comment #130
lauriiiOne of the remaining feedback here is that we need to move the asset from its own library to be loaded directly as part of
drupal.dialoglibrary.Comment #132
hooroomooComment #133
smustgrave commented#130 appears to be addressed
Comment #134
lauriiiPosted feedback on the MR
Comment #135
utkarsh_33 commentedComment #136
smustgrave commentedAll threads appear to be addressed so think this can be moved back to RTBC.
Comment #137
lauriiiAdding dependency evaluation.
Comment #138
lauriiiTested the behavior with @penyaskito on iOS and Android to confirm that the latest solution works with both platforms.
Comment #140
lauriiiTested the behavior on the latest version with @penyaskito on iOS and Android 👍
Comment #142
longwaveGreat to finally solve this. Discussed additional testing with @lauriii at Drupal Dev Days but due to the fact this mostly affects mobile browsers only and specifically Safari, that adding JS testing is somewhat pointless for Chrome - we should revisit this if one day we have explicit mobile tests via Browserstack or similar.
Also discussed the copy-paste of
assertAnnounceContains()which we should consider moving to WebAssert in a followup.Committed and pushed 6cfd0670af to 11.x. Thanks!
Comment #143
dieterholvoet commentedIsn't this being backported to 10.1?
Comment #144
penyaskitoAs this requires a new dependency, those are usually only added to minor releases, not patch releases. See https://www.drupal.org/about/core/policies/core-change-policies/allowed-...
Comment #146
quietone commentedPublished the change record. Should a usage example be added?
Comment #147
larowlanSorry to be late to the issue here, but did we consider using overflow:clip here
We should be able to use the has selector and that to achieve this with a few lines of CSS
Comment #148
larowlanI made https://codepen.io/larowlan/pen/QWzMzgo for a demo - works in Chrome but unfortunately Firefox doesn't support :has yet.
I wonder if we should mark this library as internal/deprecated knowing that when Firefox supports has we can drop it?
Comment #149
roromedia commentedIn response to the previous comment from @larowlan, I conducted a preliminary test on a desktop setup (no mobile testing yet), utilizing Gin as the backend theme. I integrated the following CSS adjustments:
The results were perfect. Both the Media modals and the Layout Paragraph Modal functioned seamlessly. Kudos for these insights!
Comment #150
smustgrave commentedSince this wasn't reverted should anything be done @larowlan?
Comment #151
longwaveI think this could be explored in a followup but we should leave the original issue as fixed.
Comment #152
larowlanfollow up: #3388408: Remove tua-body-scroll-lock in favor of a CSS :has()
Comment #154
edmoreta commentedPatch for 10.2.x branch
Comment #155
eugene.britre-roll for 10.3.x
Comment #156
liquidcms commentedThis seems to be "fixed" in 10.4. Can someone suggest how to revert this back to the way it was in D9 (despite everyone saying no one would want to scroll the background when a modal is open, my client is pretty annoyed this is now broken).
Comment #157
bnjmnm@liquidcms A true revert would either be a patch or overriding the two JS files updated but the quickest way to go back to the earlier behavior is probably to disable the scroll lock immediately after it is activated.
in a custom module add a jQuery event listener on
'dialog:aftercreate', which is triggered immediately after the scroll lock is added.In the callback, run the same code that is run when the modal dialog closes
This might not be it line-for-line, I didn't actually try it, but this approach should work - fortunately an event is dispatched right after the scroll lock so it's quite available for disabling.
Comment #158
acYou can disable it like this. In our experience having this enabled has created major issues in IOS with users unable to scroll dialogs that are larger than the viewport. It might be specific to our use case and we have not look at it beyond this yet.