Created attachment 270621 [details] Testcase demonstrating the problem Applying `overflow: hidden` to the `<body>` should make it non-scrollable. This works correctly on OS X Safari, but doesn't work correctly on iOS Safari. Original Bootstrap issue: Lost to the sands of time, but https://github.com/twbs/bootstrap/issues/14839 is relevant & popular. See also http://getbootstrap.com/getting-started/#overflow-and-scrolling Steps to reproduce: 1. Open the attached testcase in iOS Safari. 2. Tap the "Launch demo modal" button. 3. A yellow box with text appears. 4. Scroll the yellow box to its bottom, where there are "Close" and "Save changes" buttons, and lift your finger off the screen to ensure that the scroll gesture ends. 5. Attempt to scroll the yellow box further downward (which is to say, apply a "fling upward" gesture to the yellow box). Actual result: The <body> underneath the yellow box scrolls downward. Expected result: The <body> should not scroll (just like on OS X Safari).
Created attachment 270644 [details] GIF video demonstrating the bug
I would be concerned about changing behavior here, because it would cause content which has been reachable on earlier iOS versions to become unreachable.
Android Chrome already made the behavior change and blazed the trail here: https://bugs.chromium.org/p/chromium/issues/detail?id=175502 They tracked broken sites in https://bugs.chromium.org/p/chromium/issues/detail?id=444581 (and its dupes). They communicated with several sites and got some to fix their CSS. In comments 24-25 & 28, they acknowledge some breakage, but don't think there's enough of it to justify switching back: https://bugs.chromium.org/p/chromium/issues/detail?id=444581#c24 https://bugs.chromium.org/p/chromium/issues/detail?id=444581#c28 I couldn't find any signs of any subsequent revert. ---- If WebKit were to disagree with Chrome's analysis and fear too much breakage, what would be the path forward? A new "yes, I really truly want 'hidden' here!" value for the CSS 'overflow' property?
This bug has recently become a problem for a project I'm working on where we are trying to implement a chat interface, with a header element that acts like a navigation bar, and a footer element that includes a text field, with a chat container which includes the chat messages that should be able to scroll. I know this isn't a reduced test case but we have put together a stripped down version of the chat on JSBin which demonstrates this problem too: http://jsbin.com/ruyito/edit?html,css,output
(In reply to comment #2) > I would be concerned about changing behavior here, because it would cause > content which has been reachable on earlier iOS versions to become > unreachable. Based on https://github.com/w3c/csswg-drafts/issues/666#issuecomment-257889984 , should I assume your opinion has changed?
After https://trac.webkit.org/changeset/194667 I am cautious about changing iOS <body> overflow:hidden behavior.
Hi guys, do you have any new about this issue? I am facing similar behavior and I would like to know if is there any solution or workaround!
I'm having same issue. I have find solution with adding class to body with the style position:fixed. But doing that page scroll to the top. Any other solutions?
smfr@, do you have a list of pages you saw affected by this we could check again? I believe iOS WebKit is the only engine that doesn't respect `overflow: hidden` on body so it'd be great for interop if this could be fixed. FWIW, Chrome has had this behavior for several years now and I haven't heard of it causing issues lately. Perhaps sites have been fixed to take it into account by now.
We saw this with Google translate: https://translate.google.dk/translate?hl=da&sl=en&u=http://www.wikihow.com/&prev=search Apple developer documentation, http://archives.nyphil.org/index.php/artifact/63041fe8-4b51-4f96-ae82-e40bccf152cd/fullview#page/1/mode/2up https://books.google.com.mx/books?id=vCMIOfrbYrAC&pg=PA83&dq=Funciones+inyectivas,+suprayectivas+y+biyectivas&ei=AiCHSvDONqbKyQTEhO2fDg#v=onepage&q&f=false http://www.arnb.org/Festivals.php desktop version of live.com/hotmail.com/outlook.com https://support.eadocsoftware.com 1. Open http://output.jsbin.com/sagowo in iOS 9 Safari. 2. Tap the blue button to make the Bootstrap modal dialog appear. Pages on https://surf.miracosta.edu https://mobility.agbar.net/mobility-server/
Thanks smfr@, I've looked into each case. It seems they fall into one of three buckets (mainly using 6S iOS 9): No overflow: hidden today - site was fixed: https://translate.google.dk/translate?hl=da&sl=en&u=http://www.wikihow.com/&prev=search Pages on https://surf.miracosta.edu (Apple developer documentation) https://developer.apple.com/documentation/ appears fixed Overflow(-x): hidden still there but site works correctly in both Chrome and Safari (if overflow: hidden were respected). https://books.google.com.mx/books?id=vCMIOfrbYrAC&pg=PA83&dq=Funciones+inyectivas,+suprayectivas+y+biyectivas&ei=AiCHSvDONqbKyQTEhO2fDg#v=onepage&q&f=false - Appears intentional and correct - scrolling should occur only on the subscroller - Safari allows scrolling main frame a little which actually feels wrong since it shifts the UI out of view - Respecting overflow: hidden would actually improve the UX here https://mobility.agbar.net/mobility-server/ - There doesn't appear to be any scrolling on the page. - Page loads fully zoomed out - overflow: hidden commented out but would work regardless, there's no scrolling on the page http://www.arnb.org/Festivals.php - overflow-x: hidden - there should be no horizontal scrolling - Works correctly, all page content is reachable Problematic on Safari (all work correctly in Chrome): http://archives.nyphil.org/index.php/artifact/63041fe8-4b51-4f96-ae82-e40bccf152cd/fullview#page/1/mode/2up - No viewport meta - Chrome loads the page zoomed out fully so everything is visible - Safari iOS 9 locks the page to zoomed in if overflow: hidden is on. When I turn it off using inspector I can zoom out desktop version of live.com/hotmail.com/outlook.com - Works correctly in Chrome Android - There is overflow-x: hidden - I'm guessing Safari loads zoomed in because, even in request desktop site, it respects the viewport <meta> which has initial|min|max-scale: 1? Or perhaps related to overflow: hidden as above. https://support.eadocsoftware.com - No viewport meta - Better on Chrome because Chrome sizes layout viewport to match content width, loads zoomed out - the rest is just pinch zoom - Why doesn't Safari allow zooming out? - iOS 9 loads zoomed in - iOS11 loads zoomed out like Chrome 1. Open http://output.jsbin.com/sagowo in iOS 9 Safari. 2. Tap the blue button to make the Bootstrap modal dialog appear. - Works correctly in Chrome - Chrome shows the page zoomed out - No viewport meta tag - Why is safari zoomed in so much? Doesn't allow zoom... - iOS 11 works, loads zoomed out In all the problematic cases it looks like the issue is that Safari loads the page zoomed in and then can't scroll because of overflow: hidden. Was this tried before Safari shipped the visual/layout viewport model? Having the split viewport makes these issues quite tractable; Chrome seems to handle these cases rather gracefully so let me explain what we do: The layout viewport is sized to cover the entire content width. In the case of a desktop page where we fallback to the 980px initial containing block, the layout viewport will be 980px wide. When the page loads, Chrome zoomes out to the minimum possible scale so the visual viewport will match the layout viewport on load. overflow: hidden applies only to the layout viewport scrolling. If the user zooms in, they can still pan around but the layout viewport will not scroll from it's original position. This matches the behavior on desktop. If a page is broken in Chrome Android, it's likely also broken on a desktop browser because the layout viewport operates analogously to the browser window. When you shipped this did you already have a visual/layout viewport? Did overflow: hidden apply only the the layout viewport. Safari on iOS11 loads all the problematic cases zoomed out just like Chrome so just marking the layout viewport overflow: hidden wouldn't break any of them.
I don't think we had layout/visual viewports when we tried this before.
<rdar://problem/38715356>
bokan@chromium.org thanks for all your help in urging a way forward for compat. As for a work around, eric@tinymatter.co.uk, marcelopf@ciandt.com, & supun.sameera@live.com, feel free to analyze this setup using sticky positioning, offset margins, and cross axis overflow: https://vault.jonjohnjohnson.com/examples/cssripstop/
Honestly this seems like a situation where making iOS Safari work like every other browser would fix a lot more issues than it would break. As David pointed out, iOS as it is now seems well positioned for finally eliminating this odd behavior. Whatever tiny fraction of sites that might have a problem are likely very old, already broken on every other browser, and not frequented by almost anyone. So many people trying to work around this bug have led to a terrible mess of javascript and css hacks that: 1) Frequently don't actually resolve the issue entirely 2) Sometimes appear to expose other iOS Safari issues that complicate things further Resolving this issue would instantly make modal popups far easier to implement in a simple, cross-platform way. Thanks to all (especially David) for the work in fleshing this out.
Completely agree dlong@nextgentech.net, just trying to offer the only actually clean non js workaround I know, while we wait for compatibility.
Created attachment 369132 [details] patch
Comment on attachment 369132 [details] patch View in context: https://bugs.webkit.org/attachment.cgi?id=369132&action=review > Source/WebKit/UIProcess/RemoteLayerTree/RemoteScrollingTree.h:61 > +#if PLATFORM(IOS_FAMILY) > + void rootScrollingNodeScrollabilityDidChange(bool scrollable); > +#endif Shouldn't this be state on a FrameScrollingNode? I would think that iframe have similar logic?
> Shouldn't this be state on a FrameScrollingNode? I would think that iframe > have similar logic? State is in FrameScrollingNode. This is just to pass things to the main UIScrollView (which is only accessible via PageClient etc).
Created attachment 369135 [details] patch
(In reply to Antti Koivisto from comment #19) > > Shouldn't this be state on a FrameScrollingNode? I would think that iframe > > have similar logic? > > State is in FrameScrollingNode. This is just to pass things to the main > UIScrollView (which is only accessible via PageClient etc). Oh right, I didn't see it was in the params already. Yay.
Comment on attachment 369135 [details] patch Attachment 369135 [details] did not pass win-ews (win): Output: https://webkit-queues.webkit.org/results/12121416 New failing tests: svg/repaint/remove-border-property-on-root.html
Created attachment 369263 [details] Archive of layout-test-results from ews215 for win-future The attached test failures were seen while running run-webkit-tests on the win-ews. Bot: ews215 Port: win-future Platform: CYGWIN_NT-10.0-17763-3.0.5-338.x86_64-x86_64-64bit
Created attachment 369267 [details] patch
Attachment 369267 [details] did not pass style-queue: ERROR: Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.h:70: Inline functions should not be in classes annotated with WEBCORE_EXPORT. Remove the macro from the class and apply it to each appropriate method, or move the inline function definition out-of-line. [build/webcore_export] [4] Total errors found: 1 in 13 files If any of these errors are false positives, please file a bug against check-webkit-style.
Created attachment 369268 [details] patch
Attachment 369268 [details] did not pass style-queue: ERROR: Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.h:70: Inline functions should not be in classes annotated with WEBCORE_EXPORT. Remove the macro from the class and apply it to each appropriate method, or move the inline function definition out-of-line. [build/webcore_export] [4] Total errors found: 1 in 11 files If any of these errors are false positives, please file a bug against check-webkit-style.
Comment on attachment 369268 [details] patch Clearing flags on attachment: 369268 Committed r245006: <https://trac.webkit.org/changeset/245006>
All reviewed patches have been landed. Closing bug.
Am I reading this correctly that with the issue resolved WebKit will now no longer allow the body to scroll if overflow: hidden is set? If so that is awesome! How long does it typically take a patch in WebKit to land in an official iOS release?
Correct. We don't make statements about future releases.
The patch seems to have landed in iOS 13, but there are cases where it doesn't work. Scroll on the body is prevented when: - in Safari in portrait mode when the browser UI is fully visible (i.e. both the address bar and the toolbar bar are visible) - in Safari in landscape mode (whether the browser UI is fully visible or not) - in "in-app browsers" (whether the browser UI is fully visible or not) Scroll on the body is not prevented when: - in Safari in portrait mode when the browser UI is not fully visible (i.e. the address bar is retracted, and the toolbar bar fully collapsed), whether it is due to a scroll down or with the new "Hide toolbar" feature activated - in "standalone mode", i.e. when the web page is added to homescreen and no browser UI is displayed. These two cases are quite common and the behaviour not being consistent is problematic.
(In reply to Bruno Stasse from comment #33) > Scroll on the body is not prevented when: > - in Safari in portrait mode when the browser UI is not fully visible (i.e. > the address bar is retracted, and the toolbar bar fully collapsed), whether > it is due to a scroll down or with the new "Hide toolbar" feature activated This is by design; scrolling is necessary to reveal the browser UI. This could be improved in future. > - in "standalone mode", i.e. when the web page is added to homescreen and no > browser UI is displayed. Please file a new bug on this case.
(In reply to Simon Fraser (smfr) from comment #34) > > Please file a new bug on this case. I don't mean to be disagreeable, but I think this is *extremely* unfortunate. It's taken so long already to get any action accomplished on this, and the end result doesn't appear to actually fix the issue at all. Setting overflow:hidden on body should prevent scrolling. Period. No exceptions. There needs to be other mechanisms to deal with special browser UI situations--not overriding standard rendering engine mechanics. Why can't tapping on the header suffice for revealing the other UI components? If progress were being made rapidly I'd be more forgiving, but it just feels very defeating because this likely means we'll still not see a true resolution for years to come given the history of this issue. At the very least until this issue is actually resolved there needs to be a way for a site to easily disable any hiding of the browser UI components (so as to prevent the possibility of body scrolling at all). This is very important for a variety of situations like menu bars, modals, etc. Can we please make progress quickly on this? While I understand the need to file a new bug from a technical perspective, I feel there should be some continuity here because this bug really isn't resolved if scrolling can happen at all.
I agree with Davison. How about this: overflow: hidden disabled scroll, when user tries to scroll - page doesn't react to it, but UI reacts to scroll gesture, not to page scroll. Everybody happy: users can reveal UI by usual scroll gesture, developers have page without scrollbar
While trying to create testcases to show when body scroll is not prevented in standalone mode, I noticed that the behaviour is not the same depending on the viewport meta-tag (`width`, `user-scalable`, `viewport-fit`, `shrink-to-fit`, etc) added to the HTML, even in Safari. Even more problematic and surprising, I was able to get different behaviours *with the same code*. Depending on where you come from, or the time of the day — I have no idea —, in Safari in portrait mode, I was able to: - totally prevent body scrolling, even when the UI is hidden - have scroll prevented only when the UI is visible - have scroll not prevented at all whether the UI is visible or not. I would like to be able to be more precise and provide testcases, but unfortunately the results of my tests were changing for no apparent reasons and therefore cannot. Creating a simple HTML page where you can scroll the body and switch overflow auto/hidden on the body and change the viewport metatag should give you a sense of what it is like. The situation is therefore even more chaotic and unpredictable than before, as depending on situation the scroll might or might not be prevented. I understand the will to let the user reveal the browser UI with scroll at all time, as this is the primary way to make that happen, and the user is used to it. However, this cannot be done at the prejudice of the UX within web pages. Not being able to able to block the body scroll reliably in all situations makes websites and web applications look buggy, and ruin Safari's users experience, making Safari look bad. For the reasons mentioned before, the current patch cannot be considered as solving the bug, since unfortunately it doesn't even match the design decision that you mention, Simon Fraser. To recapitulate, we have: In Safari: - in portrait mode: scroll might or might not be prevented, whether the UI is fully visible or not, depending on the viewport meta-tag - in landscape mode: scroll is totally prevented, whether the UI is fully visible or not In in-app browser (tested in Twitter's): - Scroll is totally prevented, whether the UI is fully visible or not (I haven't tested with different meta-tags here, the results might change) In standalone mode: - Scroll might or might not be prevented, depending on the viewport meta-tag Different options are available here, which allow to preserve the browser UI experience as well as web pages experience. Here are those I think the best and most simple: 1) Prevent body scrolling at all time when the body is set to `overflow: hidden` and, as suggested by Davison, consider that making the browser UI appear by tapping the address bar or the bottom of the viewport is enough *just like it is in the new "hide toolbar" feature which landed in iOS 13*. 2) Prevent body scrolling at all time when the body is set to `overflow: hidden` and, *as it is the case when the body is set to `position: fixed`*, display the browser UI fully as soon as the body is set to `overflow: hidden`, and leave it that way til it is set to something else. This is what Chrome on iOS does, and it works very well. Instead of blocking the browser UI collapsed (which you want to avoid), it blocks it open when the body cannot be scrolled. 3) Prevent body scrolling at all time when the body is set to `overflow: hidden` and, as suggested by shrpne, show and hide the browser UI on the user swipes without scrolling the page. Not sure how this would feel however. The best and fastest to implement solution is probably the second one. Doing that should resolve all problems for everyone.
As I said before, please file new bugs on issues you see in iOS 13. This bug is in the FIXED state and reports of new issues here will be ignored.
Simon, with all due respect, can you please clarify your intent with your recent posts? Are you simply saying we need to open a new bug report because Bugzilla is unable to reopen this bug? I think it is pretty clear from the recent reports that this bug isn't actually fixed at all, and IMO the proper solution would be to reopen this bug so everyone has the proper context of what has occurred so far. If that is not technically possible then fine, we can open a new bug, but it would be nice to get some acknowledgement from developers that this issue really isn't resolved. Since end users can't do production testing to see if a bug really is fixed until an unspecified iOS release occurs it seems odd to close out the issue without production testing. How are we even supposed to know what bug fixes end up in a particular iOS release?
(In reply to Davison from comment #39) I haven't read the details on this bug, but it is quite common that complex issues covering similar but slightly different cases are handled in different bug entries & landed as separate patches. IIUC one of the aspect is now fixed but there are remaining related issues, so Simon is just suggesting to follow the usual workflow and to open separate bugs. The best way to help would be to split report into issues that are as isolated as possible, and for each of them provide short description and a minimal test case so that the bug can be easily reproduced and converted into non-regression test. Regarding testing and releases, I know it's frustrating but the FAQ is quite clear [1]. The best you can do is to try the latest iOS public beta. Hope that helps. [1] https://trac.webkit.org/wiki/FAQ#Releases
(In reply to Frédéric Wang (:fredw) from comment #40) > Regarding testing and releases, I know it's frustrating but the FAQ is quite > clear [1]. The best you can do is to try the latest iOS public beta. Thanks for your reply, and I'll proceed with opening new bugs as I have time to test specific cases (assuming others don't already do so). However, I'm still not sure how we are supposed to know whether to comment on an existing bug or open a new one if we aren't even given the information about which patches have been applied in a given iOS release. Are we just supposed to assume that the next minor iOS release includes bug fixes that have been marked as resolved before hand? Can we at least get the new bug reports mentioned here so people can easily know if another bug report has been made?
(In reply to Davison from comment #41) > Thanks for your reply, and I'll proceed with opening new bugs as I have time > to test specific cases (assuming others don't already do so). Thanks, please cc' me on new bugs and I can check their status with a trunk build or help where/when I can. > However, I'm > still not sure how we are supposed to know whether to comment on an existing > bug or open a new one if we aren't even given the information about which > patches have been applied in a given iOS release. I guess it's fine to open new entries, they can be resolved as "duplicate" or as "fixed" by developers (again fixed means in trunk build). > Are we just supposed to > assume that the next minor iOS release includes bug fixes that have been > marked as resolved before hand? I don't think you can assume anything unfortunately. The closer you can get is to test a beta. > Can we at least get the new bug reports mentioned here so people can easily > know if another bug report has been made? Sure, you can also use "see also" to connect bugs together.
Here's a work around for iOS Safari. Since iOS Safari prevents attaching the overflow property to the body tag, you can use the position: fixed attribute. Trouble with position: fixed is that when you want to remove the attribute (or make the body scrollable again) the page jumps back up to the top. To fix this, you can use window.scrollTo() to scroll the page back to where the user last scrolled to. Below is the code: lockBackground = ({menuOpen}) => { if (menuOpen) { const offsetY = window.pageYOffset; document.body.style.top = `${-offsetY}px`; document.body.classList.add('js-lock-position'); } else { const offsetY = Math.abs(parseInt(document.body.style.top || 0, 10)); document.body.classList.remove('js-lock-position'); document.body.style.removeProperty('top'); window.scrollTo(0, offsetY || 0); } } .js-lock-position { position: fixed; overflow: hidden; }
@c#33: I've filed a new bug for the scrolling in standalone web app issue: https://bugs.webkit.org/show_bug.cgi?id=220908