-
Notifications
You must be signed in to change notification settings - Fork 27
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
Extend Scrolling to cover Body Scroll Issues #84
Comments
@mtom55 part of this sounds very familiar, can you confirm if this is the same issue as the "body-scroll-lock" issue in https://insights.developer.mozilla.org/reports/mdn-browser-compatibility-report-2020.html#findings-scrolling? |
Yes, I can confirm that the 4.1 and 4.3 section above refer to the same issue as mentioned in the comment about "body-scroll-lock" in the MDN report. It should be noted that some people have complained that the "body-scroll-lock" script doesn't work anymore since iOS 15 (probably because the UI collapsing now relies on touchmove events and not scroll events anymore). So you need to tweak the script for it to work, or use another one. Also, note that scripts that try to handle all the edge cases are not lightweight as the comment says. As an example, react-remove-scroll weighs 10kb even after its minified. Besides, these scripts aren't perfect, they usually break the rubber-banding effect for instance. |
I see, thanks for confirming @mtom55! I would say that your best bet to get this class of problems included in Interop 2023 is to map each problem to a specific part of a spec, and to check if there are tests for this. It could be that testing this in WPT is impossible, as we don't run the tests on mobile browsers and I'm not sure if you can do all of the required scroll gestures using WebDriver. If that's the case, manual tests (that end with |
We've all individually developed extensive & complex work-arounds for these issues + produced a very comprehensive bug report, so I think beyond reporting this bug and reporting it as a major compat issue (also confirmed by the mdn report) at this point it's for Interop and/or the Safari/Webkit team to address the issues. From the developers/companies we have talked to this was their number one issue (excluding new functionality). In relation to not running tests on mobile browsers, this is probably something that the WPT should look at, as there are many bugs/issues that only occur on mobile but work fine on desktop browsers. |
Description
Inability to reliably block body scroll in Safari/Webkit. Note that this is a very significant long-standing issue which greatly increases the difficulty of building UIs and is a significant compatibility issue between browsers.
Bug reports
https://bugs.webkit.org/show_bug.cgi?id=237961
https://bugs.webkit.org/show_bug.cgi?id=240859
https://bugs.webkit.org/show_bug.cgi?id=240860
Specification
https://drafts.csswg.org/css-overflow/#overflow-properties
Tests
None as yet (As far as we know)
DETAILED DESCRIPTION
Safari/WebKit - Body Scroll Issues
A Deep Dive into a Key Developer Pain Point
4.1. Incomplete Fix of the Initial Bug
4.2. “overflow: hidden” purposefully made ineffective when the visual viewport is smaller than the layout viewport
4.3. “overflow: hidden” purposefully made ineffective in Safari iOS when the browser UI is collapsed
1. Introduction
For more than 6 years, one of the biggest issues Web Developers have had to deal with in Safari and other WebKit-based browsers on iOS (and in a lesser extent on macOS), is the inability to reliably block body scroll, or, said in other words, to remove the ability to scroll the current page in certain situations.
2. Use Cases
Such behaviour is needed in many situations where the user should not be able to scroll the page, whether on purpose, or by accident. It is essential when producing specific types of User Interfaces.
Specific examples of when it is needed include:
As you can see, there are plenty of use cases where such feature is required. Yet, over the past 6 years, WebKit has not allowed developers to safely rely on it, as it has been broken in many ways. A search with the terms “disable body scroll safari” will reveal that a large number of developers have been grappling with this issue.
3. Technical Details
Blocking body scrolling is achieved by setting the value “hidden” to the CSS property “overflow” on the HTML element.
Doing so should prevent further manual scrolling by the user, while maintaining the current scroll position, and still allowing programmatic scrolling.
This is per the “CSS Overflow Module Level 3” draft (https://drafts.csswg.org/css-overflow/#overflow-properties):
And had been validated by Simon Fraser from WebKit here: w3c/csswg-drafts#666 (comment)
The recently added “overflow” value “clip” should also allow to prevent manual scrolling, as well as any programmatic scrolling.
When setting back the value of “overflow” to “auto” or “scroll”, body scrolling should be re-enabled.
Although there was some initial concerns about making content overflowing the body inaccessible when this behaviour was introduced, the behaviour is now widely known and accepted by web authors. It is all the more an issue since this works as intended in Firefox and all Chromium-based browsers since 2016, and has been an interoperability issue between them and Safari since then.
4. When and Why this doesn’t Work
Over the years, several bugs have prevented developers from disabling body scrolling. Some have been fixed, some haven’t and some new ones have appeared.
The oldest WebKit issue related to this problem dates back to February 2016:
Many other issues related to this problem have been filled after that:
The situations where this works and where it doesn’t have changed several times over past WebKit/Safari versions, and these situations depend on multiple factors so it is hard to list them.
However, the reasons why this doesn’t work properly have been outlined over time in the aforementioned WebKit issues. Problems are related to either:
In addition to these three reasons, bugs related to them make things even worse.
Let’s dig into each problem:
4.1. Incomplete fix of the initial bug
Considering the fix to Bug 153852, excluding the situations where the two other problems come in, body scroll should be prevented. However, as we can see with Bug 214781, Bug 220908 and Bug 237961, in standalone mode on iOS (that is when a website is added to the homescreen), the fix doesn’t work.
Bug 220908 has been fixed recently, but not shipped yet. It is unknown whether it covers all situations: body scrolling might still not be blocked with all possible meta tags for instance.
Bug 237961 has yet to be fixed, and although it is only “overscrolling” which is experienced here, and not actual scrolling, it should not happen if “overflow: hidden” was working effectively.
4.2. “overflow: hidden” purposefully made ineffective when the visual viewport is smaller than the layout viewport
As indicated by Simon Fraser:
https://bugs.webkit.org/show_bug.cgi?id=236561#c3
To our knowledge, this exception to the correct behaviour for “overflow: hidden” materialises in two situations:
In both these situations, making “overflow: hidden” ineffective to block body scrolling is not the correct behaviour.
The correct behaviour would be to stop making that exception, and indeed block body scrolling when the visual viewport is smaller than the layout viewport. Therefore, when a virtual keyboard is shown, no scrolling would be possible, as expected.
However, as mentioned by Simon Fraser above and by David Bokan in the initial bug report, if the page is zoomed, the user should be able to scroll around inside the area which would be visible if the page was not zoomed, without scrolling the page further.
Implementing this would not only help solve the body scroll blocking problem, it would also fix an interoperability issue, as both Firefox and all Chromium-based browsers behave that way, on all platforms (mobile and desktop).
4.3. “overflow: hidden” purposefully made ineffective in Safari iOS when the browser UI is collapsed
This exception concerns Safari on iOS and is the one causing the most problems as it is the most frequent situation for users to be in.
In Safari on iOS, the browser UI can be in two possible states: collapsed, or revealed. To go from collapsed to reveal, you can either scroll up, or tap on the collapsed UI. To go from revealed to collapsed, you can either scroll down, or go through Safari’s settings and use the option “Hide toolbar”. Note that in the latter case the only option to then reveal the UI is to tap on it.
In order to always allow the browser UI to be revealed by a scroll up (except when it has been collapsed through the “Hide toolbar option”), the decision has been made to not allow “overflow: hidden” to prevent body scrolling when the browser UI is collapsed. As mentioned by Simon Fraser in the initial bug report:
https://bugs.webkit.org/show_bug.cgi?id=153852#c34
(Note that “overflow: hidden” is also made ineffective as a consequence of this exception when the browser UI has been collapsed through the “Hide toolbar” option, although it then cannot be revealed by a scroll up.)
As mentioned in the WebKit issue, other solutions would allow Safari’s UI to collapse/reveal without interfering with body scrolling. Specifically:
Fortunately, the first of these solutions has already been adopted in Safari 15 (possibly to eventually fix the body scrolling issue as was suggesting Simon Fraser?). Therefore, this exception is not required anymore, and could be removed.
As a side note, know that this solution has created another problem: the viewport can now be resized in situation where developers don’t want it to, and the property “touch-action” doesn’t reliably allow to prevent it. See bug Bug 240861 - Scrolling over horizontal scroll containers triggers Safari iOS UI shift and Bug 233417 - touch-action doesn't prevent the Safari UI from collapsing.
5. How to fix: summary
To summarise, here is what needs to be done to fully fix the body scroll issue in Safari/WebKit:
Fix Bug 237961 and other specific bugs that could arise.
Remove the exception preventing body scroll blocking when the visual viewport is smaller than the layout viewport and, only when the page is zoomed, implement scrolling inside the layout viewport clipped to its scroll position.
→ WebKit issue: https://bugs.webkit.org/show_bug.cgi?id=240860 (New)
Remove the exception preventing body scroll blocking when Safari’s UI is collapsed.
→ WebKit issue: https://bugs.webkit.org/show_bug.cgi?id=240859 (New)
6. Conclusion
This issue has been mentioned countless times by web developers as one of the major issues with Safari over the past 6 years. Fixing it would bring many benefits to web developers, web users and Safari. Specifically, it would eventually allow developers to drop heavy JavaScript libraries and build good user experiences for very common patterns, such as sidebars, dialogs, bottom sheets and many others.
The text was updated successfully, but these errors were encountered: