skip to Main Content

Seems to me like a pretty basic scroll-snapping setup, but it allow for boundless scrolling in Google Chrome (desktop):

Screenrecording of Google Chrome scroll-snap overscroll bug demo

In the above you can see that from the top of the page, you can still scroll up further. Equally, from the bottom of the page you can still scroll down further.

demo here and code here

(bug observed in Google Chrome 131.0.6778.86 on MacOS)


Simplified code:

HTML:

<html>
  <body>
    <div class="a"></div>
    <div class="b"></div>
  </body>
</html>

CSS:

  html {
    scroll-snap-type: y mandatory;
  }

  .a {
    scroll-snap-align: start;
    height: 100vh;
  }

  .b {
    scroll-snap-align: start;
    height: 33.3vh;
  }

I’ve tried a multitude of approaches and haven’t managed to find a fix that doesn’t also inadvertently remove scroll-snapping. I’m hoping one of you wizards has some obscure CSS-property that forces Google Chrome into honoring the scroll-boundaries of the document.

2

Answers


  1. Add overflow-y: scroll to both the html and body elements, and set height: 100% on the body. This combination creates a proper scroll container that respects document boundaries. Here’s the enhanced css:

    styles.css

    html {
        scroll-snap-type: y mandatory;
        overflow-y: scroll;
    }
    
    body {
        height: 100%;
        margin: 0;
        overflow-y: scroll;
    }
    
    .a {
        scroll-snap-align: start;
        height: 100vh;
    }
    
    .b {
        scroll-snap-align: start;
        height: 33.3vh;
    }
    

    This approach works by explicitly defining the scrollable area and ensuring the browser has clear boundaries for the scroll container. The height: 100% on the body element ensures proper content containment, while overflow-y: scroll on both html and body elements creates a well-defined scrolling context that prevents the overscroll behavior you’re experiencing.

    Login or Signup to reply.
  2. Use a wrapper instead of setting it into the :root like so.
    Found on this reddit post.
    https://www.reddit.com/r/css/comments/i9kkiw/scroll_snap_bug_chrome_on_mac/.

    .wrapper {
      scroll-snap-type: y mandatory;
      max-height: 100vh;
      overflow: scroll;
    }
    
    body {
      padding: 0;
      margin: 0;
    }
    
    code {
      background-color: rgba(0, 0, 0, 0.15);
      padding: 0.2em;
    }
    
    li {
      line-height: 2em;
    }
    
    .hero,
    .footer {
      scroll-snap-align: start;
      box-sizing: border-box;
      padding: 40px 32px;
    }
    
    .hero {
      background-color: #daf;
      height: 100svh;
    }
    
    .footer {
      background-color: #afd;
      height: 260px;
    }
    <div class="wrapper">
        <div class="hero">
          <strong>Steps to reproduction:</strong>
          <ol>
            <li>Open page in Google Chrome (possibly only in MacOS)</li>
            <li>
              <code>&lt;html&gt;</code> with CSS
              <code>scroll-snap-type:y mandatory</code>
            </li>
            <li>
              <code>&lt;body&gt;</code> has 2 children, each with CSS
              <code>scroll-snap-align:start</code>
            </li>
            <li>Scroll up and down document (scroll-snapping works)</li>
            <li>From top of document, scroll further up (using trackpad)</li>
            <li>
              (alternatively) From bottom of document, scroll further down (using
              trackpad)
            </li>
          </ol>
      
          <br /><strong>Expected results:</strong><br />
          <ul>
            <li>
              The scroll-viewport is allowed to go beyond the document’s
              scroll-boundary (relative to scrolling-velocity) but should bounce
              back to the scroll-boundary right after.
            </li>
          </ul>
      
          <br /><strong>Actual results:</strong><br />
          <ul>
            <li>
              The scroll-viewport allows scrolling beyond the document’s
              scroll-boundary and does not bounce back to the scroll-boundary.
            </li>
          </ul>
      
          <br />
          (bug observed in Google Chrome 131.0.6778.86 on MacOS)
        </div>
        <div class="footer"></div>
      </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search