August 24, 2024, (about 2 months ago) 1K page views

Hide underlaying HTML background on inertia bounce

How to prevent HTML background color from showing behind content when scrolling with inertia

ux
scroll
css
hacks

Browsers default background is white, so when we change our <body> or <main> background color, when scrolling and you hit the top or bottom of a page, the intertia bounce feature in modern OS' can lead to showing the <html> background color behind these elements.

This is easily circumvented by setting the background color of the <html> to the same color as the our element.

html {
  background-color: ruby;
}
// Ensure the body has the same background color
body {
  background-color: ruby;
}

But in scenarios where matching the content to the <html> background color isn't possible, we can use a simple trick;

::before/::after pseudo-element

Let's imagine a scenario where we have a darkmode website, but we can't change the <html>'s background color. We can use a ::before or ::after pseudo-element positioned just right.

<html>
  <body>
    <main>
      <!-- content -->
    </main>
  </body>
</html>
main:before {
  content: "";
  position: fixed;
  left: 0;
  right: 0;
  width: 100vw;
  background-color: black;
  z-index: -1;

  // You can play with these values
  top: -30vh;
  height: 50vh;
}

This adds a pseudo-element which will sit behind our element, full width and offset above the top edge!

Also, for iOS, don't forget the theme-color meta tag, which will change the color of the top bar in Safari when scrolling.

<meta name="theme-color" content="#000000" />

Acheived with the following viewport configuration in nextjs:

export const viewport: Viewport = {
  themeColor: "black",
};