Reputation: 50
I'm using mandatory scroll snapping, and that works when the section isn't bigger than the page. It doesn't work when the section needs to be bigger than the page.
I basically need to use scroll snap mandatory for a few sections, around 5, and then I need it to kind of ignore the mandatory, so I get smooth scrolling later.
I would like a no-js approach.
I've tried separating the snapping part into one div, and the non snapping part into another, but I want it to snap to the top of the non-snapping part, then scroll smoothly.
Here's the code:
body {
padding: 0;
margin: 0;
font-family: sans-serif;
overflow: hidden;
width: 100%;
height: 100%;
}
.scroller {
max-height: 100vh;
min-height: 100vh;
overflow-y: hidden;
}
.blue {
background-color: blue;
}
.red {
background-color: red;
}
.snapper {
flex-basis: 100vw;
min-height: 100%;
overflow-y: scroll;
scroll-snap-type: y mandatory;
max-height: 100vh;
}
.longer {
min-height: 500vh;
}
.snapper > div {
min-height: 100vh;
scroll-snap-align: start;
display: flex;
flex-flow: column;
justify-content: center;
}
<body>
<div class="scroller">
<div class="snapper red">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div class="longer blue">8</div>
</div>
</div>
</body>
Upvotes: 0
Views: 712
Reputation: 50
OK. I found a fix, albeit javascript, but it works really well. What it does is when it gets to the target point, it adds a no-scroll-snapping class, and the scroll snapping targets a :not(.smooth)
.
var snapper = document.getElementsByClassName("snapper")[0];
all = Array.from(snapper.children);
all.forEach(element => {
element.addEventListener("wheel", function(e) {
if (snapper.scrollTop >= window.innerHeight*7 && e.deltaY > 0) {
snapper.classList.add("smooth");
} else if (snapper.scrollTop <= window.innerHeight*7) {
snapper.classList.remove("smooth");
}
})
})
body {
padding: 0;
margin: 0;
font-family: sans-serif;
overflow: hidden;
width: 100%;
height: 100%;
}
.scroller {
max-height: 100vh;
min-height: 100vh;
overflow-y: hidden;
}
.blue {
background-color: blue;
}
.red {
background-color: red;
}
.snapper {
flex-basis: 100vw;
min-height: 100%;
overflow-y: scroll;
&:not(.smoothsnap) {
scroll-snap-type: y mandatory;
}
max-height: 100vh;
}
.longer {
min-height: 500vh;
}
.snapper > div {
&:not(.longer) {
min-height: 100vh;
}
scroll-snap-align: start;
display: flex;
flex-flow: column;
justify-content: center;
}
<body>
<div class="scroller">
<div class="snapper red">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div class="longer blue">8</div>
</div>
</div>
</body>
Upvotes: 0