I am working on this project where I need both scroll listeners and scroll-snapping, so I can make some cool transition effects between section changes.
I could get both of these to work separately, but not together. Scroll snapping requires a container element (main
element) to have a height, but when I give it a height: 100%
, JavaScript scroll listener stops working.
I tried everything I know, tried changing other containers' height/overflow properties and tried targeting other elements than body
or window
. What would be the best workaround be?
The snippet here is adjusted to work with listener at the moment. If you go ahead and add height: 100%
to main
, you will see that scroll snapping starts working, but the event listener breaks.
const scrollEvent = () => {
const main = document.querySelector('#main');
const section1 = document.querySelector('#sect1');
const section2 = document.querySelector('#sect2');
if (main.scrollTop > 50) {
section1.style.backgroundColor = "red";
} else {
section1.style.backgroundColor = "pink";
}
if (main.scrollTop > window.innerHeight / 2) {
section2.style.backgroundColor = "blue";
} else {
section2.style.backgroundColor = "purple";
}
}
window.addEventListener('scroll', scrollEvent);
* {
padding: 0;
margin: 0;
}
html,
body {
height: 100%;
width: 100%;
}
body {
scroll-behavior: smooth;
}
main {
display: flex;
flex-direction: column;
width: 100vw;
overflow: auto;
scroll-snap-type: y mandatory;
}
section {
flex-basis: 100vh;
flex-grow: 1;
flex-shrink: 0;
width: 90vw;
border: 1px solid red;
margin: 0 auto;
}
main section {
scroll-snap-align: start;
}
<!DOCTYPE html>
<html lang="en">
<head>
</head>
<body>
<main id="main" dir="ltr">
<section id="sect1">
<h1>content1</h1>
</section>
<section id="sect2">
<h1>content2</h1>
</section>
</main>
</body>
</html>
I am working on this project where I need both scroll listeners and scroll-snapping, so I can make some cool transition effects between section changes.
I could get both of these to work separately, but not together. Scroll snapping requires a container element (main
element) to have a height, but when I give it a height: 100%
, JavaScript scroll listener stops working.
I tried everything I know, tried changing other containers' height/overflow properties and tried targeting other elements than body
or window
. What would be the best workaround be?
The snippet here is adjusted to work with listener at the moment. If you go ahead and add height: 100%
to main
, you will see that scroll snapping starts working, but the event listener breaks.
const scrollEvent = () => {
const main = document.querySelector('#main');
const section1 = document.querySelector('#sect1');
const section2 = document.querySelector('#sect2');
if (main.scrollTop > 50) {
section1.style.backgroundColor = "red";
} else {
section1.style.backgroundColor = "pink";
}
if (main.scrollTop > window.innerHeight / 2) {
section2.style.backgroundColor = "blue";
} else {
section2.style.backgroundColor = "purple";
}
}
window.addEventListener('scroll', scrollEvent);
* {
padding: 0;
margin: 0;
}
html,
body {
height: 100%;
width: 100%;
}
body {
scroll-behavior: smooth;
}
main {
display: flex;
flex-direction: column;
width: 100vw;
overflow: auto;
scroll-snap-type: y mandatory;
}
section {
flex-basis: 100vh;
flex-grow: 1;
flex-shrink: 0;
width: 90vw;
border: 1px solid red;
margin: 0 auto;
}
main section {
scroll-snap-align: start;
}
<!DOCTYPE html>
<html lang="en">
<head>
</head>
<body>
<main id="main" dir="ltr">
<section id="sect1">
<h1>content1</h1>
</section>
<section id="sect2">
<h1>content2</h1>
</section>
</main>
</body>
</html>
Share
Improve this question
edited May 7, 2022 at 19:26
Peter Mortensen
31.6k22 gold badges110 silver badges133 bronze badges
asked May 12, 2020 at 20:36
Özenç B.Özenç B.
1,0383 gold badges10 silver badges28 bronze badges
2
-
The specific problem is
overflow: auto;
on main. getting rid of that allows it to work. – imvain2 Commented May 12, 2020 at 20:57 -
I don't see how. With
overflow: auto
gone scroll snaps do not work – Özenç B. Commented May 12, 2020 at 21:00
1 Answer
Reset to default 12In another topic @lawrence-witt stated that I had to add the event listener to main
, instead of whole window
. With main.addEventListener('scroll', scrollEvent);
both scroll snap and scroll event listener work fine.
const scrollEvent = () => {
const main = document.querySelector('#main');
const section1 = document.querySelector('#sect1');
const section2 = document.querySelector('#sect2');
if (main.scrollTop > 50) {
section1.style.backgroundColor = "red";
} else {
section1.style.backgroundColor = "pink";
}
if (main.scrollTop > window.innerHeight / 2) {
section2.style.backgroundColor = "blue";
} else {
section2.style.backgroundColor = "purple";
}
}
main.addEventListener('scroll', scrollEvent);
* {
padding: 0;
margin: 0;
}
html,
body {
height: 100%;
width: 100%;
}
body {
scroll-behavior: smooth;
}
main {
display: flex;
flex-direction: column;
width: 100vw;
height: 100%;
overflow: auto;
scroll-snap-type: y mandatory;
}
section {
flex-basis: 100vh;
flex-grow: 1;
flex-shrink: 0;
width: 90vw;
border: 1px solid red;
margin: 0 auto;
}
main section {
scroll-snap-align: start;
}
<!DOCTYPE html>
<html lang="en">
<head>
</head>
<body>
<main id="main" dir="ltr">
<section id="sect1">
<h1>content1</h1>
</section>
<section id="sect2">
<h1>content2</h1>
</section>
</main>
</body>
</html>