0

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

Justin
  • 367
  • 2
  • 14
  • Does this answer your question? [Fixed gradient background with css](https://stackoverflow.com/questions/18094134/fixed-gradient-background-with-css) – GucciBananaKing99 Jul 28 '21 at 08:23
  • @GucciBananaKing99 no it doesn't. I also just realized that the overscroll behavoir does not occur on android or windows chrome. It is probably specific to MacBook (or laptop) touchpad scrolling – Justin Jul 28 '21 at 15:41

4 Answers4

2

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;
  }
Justin
  • 367
  • 2
  • 14
1

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;
    }

});
Bryant
  • 46
  • 3
  • Your solution works for me when I removed the isCeiling variable. Due it to it your second if-statement is always false. I will give you the answer, if you remove it. – Justin Mar 08 '22 at 08:34
  • 1
    Ah, sorry I wrote this without double checking – I've edited the code block to change the isCeiling variable after the background is set which should work now. This just prevents the script from changing the background color when it is already set. The 'wheel' event fires quite often and manipulating the DOM that often could slow the page down. – Bryant Mar 09 '22 at 13:29
0

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/

KletskovG
  • 520
  • 4
  • 10
  • This gives me the same result as the simple fix. The top overscroll is black, but the overscroll on the bottom as well. Creating the same contrast at the bottom. The overscroll should be black on the top and white at the bottom – Justin Jul 28 '21 at 16:08
0

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.

Tommy
  • 95
  • 1
  • 9