javascripthtmlcssscrollscroll-snap-type

How to make vertical scrolling like Instagram Reel or Youtube Shorts


I have implemented a vertical scroll feature on my website using scroll-snap-type. The problem is, when scrolling quickly, DIVs are skipped. Can I prevent this?

It works pretty well with normal scrolling, on smartphones the scroll movement is quicker than on desktops, so its mainly a mobile friendly problem.

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Scrolling</title>
  <style>
    html {
      background-color: #f5f5f5;
    }

    /* Der Header bleibt immer oben sichtbar */
    .header {
      position: fixed;
      top: 0;
      left: 0;
      width: 100%;
      background: rgba(255, 255, 255, 0.9);
      padding: 15px;
      text-align: center;
      font-size: 1.5rem;
      font-weight: bold;
      z-index: 1000;
    }

    .videos {
      margin-top: 60px; /* Platz für den fixierten Header */
    }

    .video-box {
      display: flex;
      align-items: center;
      scroll-snap-align: start;
    }

    .video-box .inner {
      box-sizing: border-box;
      padding: 8px;
      margin: 0 auto;
      height: 100vh;
      max-width: 100%;
    }
  </style>
</head>

<body>

  <div class="header">Das ist ein Beispiel für den Header</div>

  <section class="videos">
    <div class="video-box">
      <div class="inner">Hallo 1</div>
    </div>
    <div class="video-box">
      <div class="inner">Hallo 2</div>
    </div>
    <div class="video-box">
      <div class="inner">Hallo 3</div>
    </div>
    <div class="video-box">
      <div class="inner">Hallo 4</div>
    </div>
  </section>

  <script>
    document.documentElement.style.scrollSnapType = "y mandatory";
  </script>

</body>

</html>


Solution

  • You can adjust the sensitivity of the snapping using the scroll-snap-stop property.

    scroll-snap-stop: always;
    

    This will make it more difficult to skip things while scrolling. It is not a perfect solution but it will help.

    html, body {
      height: 100%;
    }
    
    body {
      margin: 0;
      background-color: #f5f5f5;
      display: grid;
      grid-template-rows: auto 1fr;
    }
    
    .header {
      background: rgba(255, 255, 255, 0.9);
      padding: 15px;
      text-align: center;
      font-size: 1.5rem;
      font-weight: bold;
    }
    
    .videos {
      overflow: auto;
      scroll-snap-type: y mandatory;
      scroll-snap-stop: always;
    }
    
    .video-box {
      display: flex;
      justify-content: center;
      align-items: center;
      scroll-snap-align: start;
      border: 5px solid blue;
      height: 100%;
      box-sizing: border-box;
    }
    
    .video-box:nth-child(even) {
      border: 5px solid orange;
    }
    
    .video-box .inner {
      border: 5px solid red;
      padding: 8px;
    }
    <div class="header">Das ist ein Beispiel für den Header</div>
    
    <section class="videos">
      <div class="video-box">
        <div class="inner">Hallo 1</div>
      </div>
      <div class="video-box">
        <div class="inner">Hallo 2</div>
      </div>
      <div class="video-box">
        <div class="inner">Hallo 3</div>
      </div>
      <div class="video-box">
        <div class="inner">Hallo 4</div>
      </div>
    </section>