Repair the masthead background during overscroll

The Dilemma

At the top of my webpage, I have a sleek masthead with a captivating background image that scrolls along with the page. However, there is an issue when users overscroll upwards, causing an undesirable white overflow to appear. To rectify this situation, my goal is to anchor the background in place when users engage in overscrolling, allowing the content to move downward while maintaining the fixed background.

An Example of Code

index.html

<div class="masthead">
  </div class="container">
    <h1>Hello, World</h1>
    <p>Lorem ipsum dolor</p>
  </div>
</div>

main.scss

/*...*/
.masthead {
  display: block;
  text-align: center;
  color: white;
  background-image: url('http://via.placeholder.com/1900x1250/ff6666/000000');
  background-repeat: no-repeat;
  background-attachment: scroll;
  background-position: center center;
  background-size: cover;
}
/*...*/

Reasons for Not Using overscroll-behavior-y: none

While some may recommend using overscroll-behavior-y: none, this solution lacks support from Safari/WebKit and can come off as overly harsh. I appreciate the natural overscroll effect and would like to maintain it while ensuring a clean user interface.

Challenges Faced

My attempts at resolving this included implementing the background-attachment: fixed property, which ended up slightly altering the image positioning. Furthermore, despite fixing the background, the masthead fails to extend into the overflow, leaving its background white.

Technologies Utilized

  • SCSS
  • jQuery
  • bootstrap

Answer №1

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:

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Unable to properly bind events onto a jQuery object

I have been attempting to attach events to jquery objects (see code snippet below), but I am facing challenges as it is not functioning properly. Can someone provide me with a suggestion or solution? Thank you! var img = thumbnail[0].appendChild(document. ...

block the UI when a certain amount of time has passed

When I click on a button, I implement the following code: $(document).ready(function () { $('.find').click(function () { $.blockUI({ message: '<table><tr><td><img src="images/pleas ...

What is the typical approach of JavaScript frameworks towards the 304 not-modified response?

Wondering about the inner workings of Jquery and web development in general. When a JavaScript file is requested and the server sends a 304 not-modified response, how does a framework handle it: Does it load the JS file from cache and run it? Or does it ...

Transforming data from a JSON format into a JavaScript array

I'm trying to convert a JSON string into an array containing the values from the JSON. When I use json.stringify(jsonmybe) and alert it, I see [{"role":"noi_user"},{"role":"bert_user"}] (which is in JSON format). My goal is to extract `noi_user` and ` ...

"Exploring the process of transferring an ID from one service to another using the select feature in Angular

I need to store the ID I receive from one service into another using the select element. Here is my approach: <select class="form-control" id="select_fac" [(ngModel)]="rep.idfac"> <option selected disa ...

If the user decides to change their answer, the current line between the two DIVs will be removed

After clicking on two DIVs, I created two lines. Now, I am facing an issue with resetting the unwanted line when changing my answer. To reset the line, you can refer to the code snippet below: var lastSelection; ...

Troubles arise when trying to convert a schema using Normalizr

Is there a way to efficiently convert a JSON array containing travel expenses into a format that allows for easy retrieval of expenses by travelExpenseId and tripId? [ { "travelExpenseId":11, "tripId":2, "paymentPurpose":"some payment ...

Jquery debugger keeps getting triggered multiple times by checkbox interactions

I've encountered an issue while working on Mvc.Grid that involves the onclick event of a checkbox. Within the grid, each row represents a Profile and contains a checkbox for selection. My goal is to retrieve a list of IDs corresponding to the checked ...

Unable to get CSS First Child Pseudo Element to Work Properly

I'm having trouble with this code in CSS and would appreciate any help. I can't figure out why the margin-left won't apply to the first i element. Below is the CSS I'm using: header.site-header .right_side_menu i:first-child { marg ...

The makeSVG function from GoJS is failing to generate the correct HTML SVG object

I have been utilizing the Diagram.makeSVG() method to create an SVG from my diagram. Subsequently, I appended the SVG to a new empty tab using this script (diagram represents my Diagram Object): function print() { var newTab = window.open(), svg ...

Issues with the background color of the bootstrap 'card' when implementing a QR code

How can I customize the background color for a Bootstrap card, specifically filling the entire card including the card text section? <div class="content"> <div class="card"> <img src="images/qr-code.png&q ...

Can AJAX Delete requests be executed without using jQuery?

Is it possible to use AJAX delete request without using jQuery? My JSON object at localhost:8000 appears like this: { "Students":[{"Name":"Kaushal","Roll_No":30,"Percentage":94.5}, {"Name":"Rohit","Roll_No":31,"Percentage":93.5}, {"Name":"Kumar ...

New properties are not being successfully added to Passport Profiles

I am currently utilizing Passport OAuth2.0 with Google as my provider and encountering an unusual syntax issue. The structure of my authentication setup is as follows: passport.use(new GoogleStrategy({ clientID: GOOGLE_CLIENT_ID, clientSecret: GO ...

If the mouse hovers over again, implement this action using jQuery

Check out my code snippet here: http://jsfiddle.net/sZKeM/1/ I have created a functionality where a box is displayed when hovering over a button and hidden when the mouse leaves the box. However, I am looking to tweak it so that the box hides when hoverin ...

How can I make an image tag perfectly fit a CSS grid cell without using object-fit?

In this Vue component, the parent element displays 8 instances of these components in a 2x4 grid layout. The issue arises when the image within each component is larger than its container, causing it to not shrink to fit while maintaining the aspect ratio ...

Is it possible to create a multi-page single-page application using Vue js SSR?

It may appear contradictory, but I struggle to find a better way to express it. When using vue server-side rendering, it seems you are limited to single page applications. However, for various reasons, I require an application with multiple real server-s ...

Sending asynchronous requests to handle data within various functions based on different links

I'm currently facing a major roadblock when it comes to resolving my issues with callbacks. I've gone through resources like How to return value from an asynchronous callback function? and How to return the response from an Ajax call?, among seve ...

Using PHP and jQuery to create an autocomplete feature with data retrieved from a

Despite extensive research and review of past questions and answers on this subject, I am still facing confusion. My goal is to access the database that contains a user's contact list. To start off simply, I'm currently only allowing reference by ...

Tips for retrieving a value from a callback function?

How do I return a value from a callback function? The following code snippet is what I have: function storeData(data) { const id = "5f354b7470e79f7e5b6feb25"; const body = { name: "john doe" }; bucket.insert(id, body, (error, r ...

Looking for assistance with updating a JavaScript Object Array and embedding it into a function

Below is the code snippet I am working with: $("#map4").gMap({ markers: [ { address: "Tettnang, Germany", html: "The place I live" }, { address: "Langenargen, German ...