give different color to top and bottom of the webpage body overscroll

1.7k Views Asked by At

My portfolio has a black background color at the top and a white one at the bottom. When you overscroll at the top the white background of the body shows for a brief moment, creating an unwanted contrast like this: white background showing on scroll up when at the top

So I want black overscroll for the top and white for the bottom. A simple fix for the top is to set the background-color of the body to black, but then I get the reverse problem for the bottom. I tried using linear-gradient on the body and html-page or putting colored containers with negative margins at top or bottom, but that did not work. Is there a way to have different colors for top and bottom overscroll?

Example Code Sandbox: https://codesandbox.io/s/overscroll-color-ns9yd

Example Code Sandbox Live (you can't test the overscroll in the sandbox): https://ns9yd.csb.app/

Addition: Today when I used chrome on android and on windows with a mouse I realized that the described overscroll effect does not appear there. Therefore the effect is likely specific to touchpad scrolling. I have been using a MacBook when I asked the question. So it might only occur on MacBooks when scrolling with the touchpad

Youtube Demonstration of overscrolling: https://youtu.be/Ec1D6KNlhIM

Overscrolling with body background black (the simple fix): https://youtu.be/zYITinXs6OY

4

There are 4 best solutions below

2
Bryant On BEST ANSWER

I understand this question is outdated, but I had a similar issue and came up with a fix.

By putting a listener on the window's wheel event, we can check the delta of the scroll. With that information we can change the documentElement background color to match the page's (black)"ceiling" or (white)"floor":

let isCeiling = false;

window.addEventListener('wheel', (e) => {

    const delta = e.deltaY;

    if (delta < 0 && !isCeiling) {
        document.documentElement.style.background = 'black';
        isCeiling = true;
    } else if (delta > 0 && isCeiling) {
        document.documentElement.style.background = 'white';
        isCeiling = false;
    }

});
1
KletskovG On

You can wrap whole website in wrapper and linear gradient to this wrapper And make background: #000 for body

You can check solution here (Example Code Sandbox)

https://codesandbox.io/s/youthful-dewdney-9l5p6?file=/index.html:95-149

Or Here (Live sandbox)

https://9l5p6.csb.app/

0
Justin On

Since this overscroll effect did not appear on an android phone and windows pc, I assume it is (macos?) touchpad scrolling specific and browsers with the dom and CSS just do not provide an api for this rare behaviour.

But if you want to prevent the overscroll effect use:

  html,
  body {
    height: 100%;
    overscroll-behavior-y: none;
  }
0
Tommy On

Similar to Bryant's solution, this CodePen exposes the window's scrollY property to the page by setting it as an attribute on the page's HTML tag, allowing any CSS styles to easily reference the value:

// ... assuming some debounce function ...

// Store scroll position in page's data attribute
const storeScroll = () => {
  document.documentElement.dataset.scroll = window.scrollY;
}

// Listen for new scroll event
document.addEventListener('scroll', debounce(storeScroll), { passive: true });

Now, the CSS can be intelligent about its styling:

/* Applies to top of page */
html[data-scroll="0"] body {
  background-color: black;
}

/* Applies to bottom of page */
html:not([data-scroll="0"]) body {
  background-color: white;
}

Reflected in the HTML as:

<html data-scroll="{ scrollY }">
 ...
</html>

Unfortunately, if someone is using a newer version of Safari with theme-color support, then the color of the browser bar will change with the body's background-color. Moreover, setting <meta name="theme-color" content="#ffffff"> will override the overscroll color completely.


Of course, this all assumes that the user of your website has JS enabled. A simpler, non-JS solution could potentially be like this answer, where the body's background-color is set to one value and its full-size background-image is set to a single colored pixel. Other solutions involve adding fixed off-screen pseudo-elements with the desired color above and below the page.