While attempting to address the masthead issue caused by overscrolling, a rubber-band effect is observed on the body. To investigate this further, testing was conducted on an iPhone 5C as desktop browsers do not exhibit overscroll behavior unless running on OSX. It is important to note that these findings are limited to an older version of iOS (10.something). Here are the conclusions drawn:
Avoid this approach: modifying CSS on window scroll
To handle the situation where the user scrolls over the top and the masthead needs fixing, you can attach an event listener to the window scrolling event:
CSS
body {
margin: 0;
padding: 0;
}
.masthead {
overflow: auto;
/* move this div to a gpu-processed layer */
-webkit-transform: translate3d(0, 0, 0); /* for iOS <8.1 */
transform: translate3d(0, 0, 0);
}
.fixed-top {
position: fixed;
top: 0;
width: 100%;
}
JavaScript
var masthead = document.querySelector(".masthead");
var mastheadHeight = masthead.clientHeight;
var topContentMargin = 16;
mastheadHeight += topContentMargin;
window.addEventListener("scroll", function(e) {
fixMastheadOnOverscroll();
});
function fixMastheadOnOverscroll() {
let overscrollingTop = window.scrollY < 0;
if (overscrollingTop) {
masthead.classList.add("fixed-top");
document.body.style.marginTop = mastheadHeight + "px";
} else {
masthead.classList.remove("fixed-top");
document.body.style.marginTop = "0px";
}
}
Analysis of the code
This code snippet serves to keep the masthead fixed at the top during overscroll. Some key points to consider include:
overflow: auto
on the masthead avoids collapsing margins when not overscrolling;
- adding
transform
is a well-known workaround to optimize an element's rendering using GPU acceleration. Will it enhance the positioning of the masthead during overscrolling? This remains uncertain and warrants further exploration.
- applying a margin to the body during overscroll prevents content from appearing under the fixed masthead; failing to do so will result in content being rendered beneath the masthead.
- to prevent the body content from shifting abruptly when returning to its original position after overscrolling, the height of the content is added to the body's margin.
Why isn't it ideal?
It is widely recognized that executing a DOM-altering function upon scrolling can be resource-intensive. According to insights shared by Twitter's development team:
Attaching handlers to the window scroll event is highly discouraged.
The event listener triggers the function frequently, potentially leading to erratic behavior. Additionally, peculiarities may arise on iOS platforms due to the callback firing solely at the end of the scroll event, as pointed out by Apple engineers.
An alternative approach
¯\(ツ)/¯
In all honesty, devising an effective strategy without relying on overscroll-behavior-y
poses a challenge. Employing the aforementioned workaround exclusively for iOS users based on browser detection is one possibility. Several performance enhancements worth considering include:
- throttling the callback, albeit possibly resulting in sluggish responsiveness;
- manually specifying the masthead's height in a separate CSS class for
margin-top
and apply said class to the body instead of directly altering the body's style. However, this method offers reduced flexibility.