Website double-scrolling on Chrome using scroll-snap-type
Asked Answered
T

4

9

I want my sections to take the whole page and as soon as the user scrolls up or down, the previous/next section comes up. It works perfectly on Firefox and on Chromium-Edge, but when I tested it on Chrome, it always skips a section (goes from section1 to section 3 and from section 3 back to section 1). What can I do to solve this problem?

Here is the HTML:

<div class="page container">
    <div class="section section1">
       ...
    </div>

    <div class="section section1">
       ...
    </div>

    <div class="section section2">
       ...
    </div>

    <div class="section section3">
       ...
    </div>
</div>

And here is the CSS:

    .container{
  position: relative;
  width: 100%;
  height: 100vh;
  overflow: auto;

  /*  Scroll Snap  */

  scroll-snap-type: y mandatory;
}

.section{
  position: relative;
  width: 100%;
  height: 100%;
  scroll-snap-align: start;
  display: flex;
  align-items: center;
  justify-content: center;
}

here is the website if anyone wants to see by themselves : Open in Firefox and/or Chrome to see difference

Thorvald answered 28/10, 2020 at 20:52 Comment(1)
I think this has just been fixed in Chrome. At least it doesn't seem to be double scrolling for me in Chrome anymore. Here's a JSFiddleOstraw
V
6

Definitely a bug in Chrome. The offender seems to be background-color (!) property set on the container element.

For some inexplicable reasons its presence triggers overscrolling... BUT only on a wheel-kind scroll. The keyboard one (either with KeyUp/Down or PageUp/Down) works fine.

Here's SRE; try scrolling the page, then press 'Fix Chrome' button, then scroll one more time - and see the difference. In Chrome 86 (Version 86.0.4240.111 (Official Build) (64-bit), to be precise), at least.

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

.break-things {
  background-color: #f3f3f3;
}

.container {
  position: relative;
  width: 100%;
  height: 100vh;
  scroll-snap-type: y mandatory;
  overflow-y: scroll;
}

.item {
  scroll-snap-align: start;
  font-size: 7rem;
  height: 77vh; 
}

.item1 {
  background-color: blue;
}

.item2 {
  background-color: yellow;
}

.item3 {
  background-color: red;
}
<body>
  <header><button type=button>FIX CHROME SCROLL SNAP</button></header>
  <div class="container break-things">
    <div class="item item1">Hello World</div>
    <div class="item item2">Hello World</div>
    <div class="item item3">Hello World</div>
  </div>
  <script>
   let isChromeBroken = true;
   document.querySelector('button').onclick = (ev) => {
     isChromeBroken = !isChromeBroken;
     ev.target.textContent = `${isChromeBroken ? 'FIX' : 'BREAK'} CHROME SCROLL SNAP`;
     document.querySelector('.container').classList.toggle('break-things');   
   }
  </script>
</body>
Vernon answered 28/10, 2020 at 22:9 Comment(7)
Wow thnaks a lot! you are right, the problem seems to come from the background-color property. As soon as I remove that, everything works perfectly! Would never have thought of that myself. Thanks again! :)Garnettgarnette
Big thanks to you sir! It still isnt fixed it seems.Kissable
@Kissable No, it's not; the comment at the question is misleading. Not sure why one created a separate fiddle anyway: if the issue is fixed, it's fixed in that snippet as well. And yes, Canary v90 still has it (just checked).Vernon
@Vernon i got that bug in a project right now, setting the background-color to another container worked. Edge Chromium (Version 88.0.705.63) does not have that problem, but Chrome (Version 88.0.4324.150) and Brave (Version 1.19.92 Chromium: 88.0.4324.152) do. ps: i was not referring to that comment on the question but to the timeframe (I read 2017 somehow...)Kissable
@Kissable Well, two things about this bug seem to be true: it's relatively old and it's Chromium-specific. Just checked it with somewhat obsolete version of Opera (73.0.3856.344). I wouldn't be surprised if Edge team fixed it in their branch though.Vernon
Using Chrome 89.0.4389.90 and it appears to be working just fine now.Watkins
Just checked the snippet, it's still broken - on the same version of Chrome. How exactly you're trying to reproduce the issue?Vernon
T
0

I have the same problem in Chrome and Opera on Windows (not Mac). But if I make each block of the page scrollable horizontally, the problem is solved.

As raina77ow wrote in his answer to this case, the bug fires only on wheel events. But in my case it does not depend on any background parameters.

For now I have only found a solution based on this:

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

.page {
  position: relative;
  scroll-snap-align: start;
  height: 100vh;
  overflow-x: auto;
}

.page::-webkit-scrollbar {
    display: none
}

.page::before {
  content: "";
  position: absolute;
  width: calc(100% + 1px);
  height: 1px;
}
<div class="container">
  <div class="page">
    Page 1
  </div>
  <div class="page">
    Page 2
  </div>
  <div class="page">
    Page 3
  </div>
  <div class="page">
    Page 4
  </div>
</div>
Tasso answered 3/5, 2021 at 21:49 Comment(1)
An interesting idea, but I don't think horizontal scrolling has a real effect on the OP's problem. Just tried adding background-color to your snippet, got the same overscrolling behavior on wheel events. I can only guess here that presence of background for some reason triggers duplicate processing of this event in Chrome.Vernon
A
0

Below snippet solved the issue for me.

var canScroll = true;
    var scrollContainer = document.querySelector('html')
    scrollContainer.addEventListener('wheel', function(e) {
    if (canScroll) {
        scrollContainer.scrollBy(0, e.deltaY);
        canScroll = false;
        setTimeout(() => {
            canScroll = true;
        }, 800);
    }
    e.preventDefault();
    }, { passive: false });
html {
        height: 100%;
        scroll-snap-type: y mandatory;
          scroll-behavior: smooth;
        -ms-scroll-snap-type: mandatory;
    }

    div#section-1,div#section-2,div#section-3,div#section-4,div#section-5 {
        padding: 0;
        height: 100vh;
        display: flex;
        align-items: center;
        justify-content: center;
        font-family: 'LexiaLight';
        width: 100%;
    }

    div#section-1, div#section-2, div#section-3, div#section-4, div#section-5 {
      scroll-snap-align: start;
      scroll-snap-stop: always;
    }

    div#section-1 {
        background: #264653;
    }

    div#section-2 {
        background: #2a9d8f;
    }

    div#section-3 {
        background: #e9c46a;
    }

    div#section-4 {
        background: #f4a261;
    }

    div#section-5 {
        background: #e76f51;
    }

    div#section-1, div#section-2, div#section-3, div#section-4, div#section-5{
      scroll-snap-align: start;
        scroll-snap-stop: always;
    }
<div id="section-1"></div>
<div id="section-2"></div>
<div id="section-3"></div>
<div id="section-4"></div>
<div id="section-5"></div>
Acima answered 15/7, 2021 at 3:26 Comment(0)
R
0

This nearly broke me down :)

I simply removed the background property set on the container element and it was fixed.

Romance answered 19/7, 2021 at 15:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.