htmlcssscrollscroll-snapscroll-snap-type

Scroll snap type behaving like proximity when mandatory is selected


I want to have the hero of the site be take up the full screen and then when you scroll down, you jump to main content with the top being at the top and the hero no longer visible then you can scroll like normal throughout the rest of the page. When I do a 'normal' sized scroll down, the effect works fine, but when I do a 'smaller' scroll, I get the hero partially on the screen and the main content on the other portion. I can scroll through the main content with there hero staying in it's halfway in position. I am using a trackpad on a laptop and it seems like the snapping effect can also be 'overwritten' by a more controlled scroll(hard stop) vs a more free scroll(soft stop like sweeping my fingers).

TL;DR - Basically the scroll snap type it sometimes behaving like proximity when I have it set to mandatory.

I have many combinations of containers for my sections and changing up values for properties with no succcess. I want the user to either only see the hero taking up the full viewport OR I want them to only see the main content so when you scroll between the hero and the main content, it snaps to either and no partial view of either. Below is what related HTML structure and CSS I have so far that is working 'best'.

HTML

<body>
     <div class='hero'>
         HERO HTML
     </div>
     <div class='maincontent'>
         MAIN CONTENT HTML
     </div>

</body>

CSS

body {
    width: 100%;
    height: 100vh;
    position: relative;
    scroll-behavior: smooth;
    overflow-y: scroll;
    scroll-snap-type: y mandatory;
    scroll-snap-stop: always;
}

.hero {
    width: 100%;
    height: 100vh;
    scroll-snap-align: start;
}

.maincontent {
    width: 100%;
    height: 100vh;
    scroll-snap-align: start;
    overflow: scroll;
}

Solution

  • You can try this:

    body {
      margin: 0;
      padding: 0;
      overflow: hidden;
    }
    
    .container {
      display: flex;
      flex-direction: column;
      height: 100vh;
      scroll-snap-type: y mandatory;
      overflow: auto;
    }
    
    section {
      width: 100%;
      height: 100vh;
      scroll-snap-align: start;
      display: flex;
      justify-content: center;
      align-items: center;
      font-size: 2rem;
      border: 1px solid #ccc;
    }
    
    .hero {
      background: #0074D9;
      color: white;
    }
    
    .maincontent {
      background: #FFDC00;
    }
    
    /* Optional: Customize styles for each section */
    <body>
      <div class="container">
        <section class="hero">
          HERO HTML
        </section>
        <section class="maincontent">
          MAIN CONTENT HTML
        </section>
      </div>
    </body>