1

The problem is shown here:

https://codepen.io/team/css-tricks/pen/yLLqqgP

This is the important part:

    html {
        scroll-snap-type: y mandatory;
    }
    section {
        height: 100vh;
        scroll-snap-align: start;
    }

When setting height of section > 120, or similar this issue can get fixed, but this is a hack.

When I start scrolling, with a scroll wheel, then it always scrolls two sections, which makes the whole logic unusable.

I am using Chrome: 86.0.4240.183.

This codepen example is from: https://css-tricks.com/practical-css-scroll-snapping/ which is a very well known ressource for css examples.

Simon S.
  • 563
  • 4
  • 21
  • Here there are some more ressources that show the same problem: https://codepen.io/michellebarker/full/PowYKXJ – Simon S. Nov 08 '20 at 21:43
  • Funnily enough it works in Microsoft Edge Version 86.0.622.63 which also has Webkit engine. This makes the whole situation even stranger. – Simon S. Nov 08 '20 at 21:46

1 Answers1

3

This is a known bug in Chrome unfortunately, caused by using either html or a container with a background-color property for the scroll container. It only affects scroll wheels and not trackpads or touch scrolling on mobile. See this thread for a demonstration of the problem.

The simplest solution is to just use a nested container to hold the scroll, although, bizarrely, you may notice that the scroll-snap now has a small delay on it. This is the best that can be done with the current implementation:

* {
  padding: 0;
  margin: 0;
  box-sizing: border-box;
}

html {
  overflow: hidden;
}

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

h1 {
  width: 100%;
  height: 100vh;
  scroll-snap-align: start;
  border: 2px solid black;
  display: flex;
  justify-content: center;
  align-items: center;
}
<div class="container">
  <h1>1</h1>
  <h1>2</h1>
  <h1>3</h1>
  <h1>4</h1>
</div>

The problem is unfortunately compounded once you realise that 100vh is also non-static (read: extremely janky) on some mobile browsers due to the implementation of retracting UI, potentially leading to unstyled gaps as the html layer shows through before the container fills up the remaining space. I've spent hours wrestling with this issue this year and have yet to come up with a totally satisfactory solution, settling for media queries to reset back to html in most cases and targeting any edge cases with JS.

Here's one possible media query you could add for that:

@media (hover: none) and (pointer: coarse) {
  html {
    overflow: auto;
    scroll-snap-type: y mandatory;
  }

  .container {
    height: auto;
    display: contents;
    scroll-snap-type: unset;
  }
}
lawrence-witt
  • 8,094
  • 3
  • 13
  • 32
  • What do you think about JS solutions like Fullpage JS? – Simon S. Nov 09 '20 at 17:19
  • I try to avoid JS for any styling unless absolutely necessary. Fullpage seems to have solved the `100vh` issue by blocking UI retraction entirely which isn't great IMO, and the performance can also be a bit sluggish on mobile. Maybe I was too pessimistic in my answer; I'd still much rather use the native scrolling API in this state than revert to a full JS solution and take a performance hit. When *really* I want to stop `vh` sized elements jumping on mobile I overwrite `100vh` with a `window.innerHeight` CSS Var and just accept that they will not always line up perfectly with the screen. – lawrence-witt Nov 09 '20 at 21:59