Sam
Sam

Reputation: 525

Scroll snap CSS skipping elements

Long story short, on Chrome (81.0.4044.138) scroll snapping skips the middle <div class="item2"> for some reason. On Firefox (76.0.1) it works fine. Any idea why?

 html {
      scroll-snap-type: y mandatory;
    }
    
    body {
      margin: 0;
      padding: 0;
      overflow-x: hidden;
      overflow-y: scroll;
    }
    
    div {
      height: 100vh;
      scroll-snap-align: center;
    }
    
    .item1 {
      background-color: blue;
      font-size: 5rem;
    }
    
    .item2 {
      background-color: yellow;
      font-size: 5rem;
    }
    
    .item3 {
      background-color: red;
      font-size: 5rem;
    }
<body class="container">
        <div class="item1">Hello World</div>
        <div class="item2">Hello World</div>
        <div class="item3">Hello World</div>
    </body>

Upvotes: 4

Views: 5272

Answers (3)

GDur
GDur

Reputation: 59

Here is a workaround with which I came up after quite some time tinkering. Hope this helpes!

const scrollContainer = document.querySelector('.container')

// don't forget to add "scroll-behavior: smooth;" to the .container CSS

scrollContainer.onwheel = function(event) {
  // use scrollBy using the deltaY just as a direction
  // the exact value is not important because of "scroll-snap-type: y mandatory;"
  scrollContainer.scrollBy(0, event.deltaY);

  // this will stop the original scroll event.
  return false;
};
body {
  margin: 0;
  padding: 0;
  overflow: hidden;
}

.container {
  scroll-snap-type: y mandatory;
  scroll-behavior: smooth;
  overflow-y: scroll;
}

div {
  height: 100vh;
  scroll-snap-align: center;
}

.item1 {
  background-color: blue;
  font-size: 5rem;
}

.item2 {
  background-color: yellow;
  font-size: 5rem;
}

.item3 {
  background-color: red;
  font-size: 5rem;
}
<body>
  <div class="container">
    <div class="item1">Hello World</div>
    <div class="item2">Hello World</div>
    <div class="item3">Hello World</div>
  </div>
</body>

Upvotes: 4

Danish Khan
Danish Khan

Reputation: 39

Use scroll-snap-stop: always; on the child Element.

Upvotes: 1

SMAKSS
SMAKSS

Reputation: 10520

Actually, there is a bug about it in chrome browsers (The reason behind it, is not clear until now so no one knows why). So you cant apply scroll-snap-type to your html (whilst applying it to body won't work either) tag directly. So instead of it, in order to make it work, you should create another div and wrap your element inside it.

So try this instead:

body {
  margin: 0;
  padding: 0;
  overflow: hidden;
}

.container {
  scroll-snap-type: y mandatory;
  overflow-y: scroll;
}

div {
  height: 100vh;
  scroll-snap-align: center;
}

.item1 {
  background-color: blue;
  font-size: 5rem;
}

.item2 {
  background-color: yellow;
  font-size: 5rem;
}

.item3 {
  background-color: red;
  font-size: 5rem;
}
<body>
  <div class="container">
    <div class="item1">Hello World</div>
    <div class="item2">Hello World</div>
    <div class="item3">Hello World</div>
  </div>
</body>

NOTE: Same problem in CSS-tricks.

Upvotes: 4

Related Questions