const observer = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
entry.target.classList.add('show');
} else {
entry.target.classList.remove('show');
}
});
});
$(window).scroll(function() {
// selectors
var $window = $(window),
$body = $('body'),
$panel = $('.panel');
// Change 33% earlier than scroll position so colour is there when you arrive.
var scroll = $window.scrollTop() + ($window.height() / 3);
$panel.each(function () {
var $this = $(this);
// if position is within range of this panel.
// So position of (position of top of div <= scroll position) && (position of bottom of div > scroll position).
// Remember we set the scroll to 33% earlier in scroll var.
if ($this.position().top <= scroll && $this.position().top + $this.height() > scroll) {
// Remove all classes on body with color-
$body.removeClass(function (index, css) {
return (css.match (/(^|s)color-S+/g) || []).join(' ');
});
// Add class of currently active div
$body.addClass('color-' + $(this).data('color'));
}
});
}).scroll();
const hiddenElements = document.querySelectorAll('.hidden');
hiddenElements.forEach((el) => observer.observe(el));
body {
margin: 0;
padding: 0;
font-family: sans-serif;
background-color: rgb(36, 164, 138);
transition: background-color 1s ease;
}
div {
place-items: center;
align-content: center;
min-height: 100vh;
color: white;
position: relative;
scroll-snap-align: start;
}
.panel {
min-height: 100vh;
display: flex;
justify-content: space-around;
align-items: center;
font-family: sans-serif;
}
main {
scroll-snap-type: y mandatory;
overflow-y: scroll;
/* When I remove the height, the color transition works, but the scroll-snap breaks */
height: 100vh;
}
.color-green {
background-color: rgb(36, 164, 138);
}
.color-red {
background-color: rgb(211, 79, 79);
}
.color-blue {
background-color: rgb(67, 91, 175);
}
.color-salmon {
background-color: lightsalmon;
}
.hidden {
opacity: 0;
filter: blur(5px);
transform: translateX(-100%);
transition: all 1s;
}
.show {
opacity: 1;
filter: blur(0);
transform: translateX(0);
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>CSS SNAP EFFECT</title>
<link rel="stylesheet" href="styles.css">
<script defer src="app.js"></script>
<script
src="https://code.jquery.com/jquery-3.7.0.js"
integrity="sha256-JlqSTELeR4TLqP0OG9dxM7yDPqX1ox/HfgiSLBj8+kM="
crossorigin="anonymous">
</script>
</head>
<body>
<main>
<div class="panel" data-color="green">
<h1 class="hidden">First</h1>
</div>
<div class="panel" data-color="red">
<h1 class="hidden">Second</h1>
</div>
<div class="panel" data-color="blue">
<h1 class="hidden">Third</h1>
</div>
<div class="panel" data-color="salmon">
<h1 class="hidden">Last</h1>
</div>
</main>
</body>
</html>
I am new to programming and this is the beginnings of what will be my biggest project so far. I want to have my website have a scroll-snap feature, and I want the background color to have a fade-transition as you scroll. I noticed that it seems like I can only have one feature at a time though.
I have found some source of the problem. Whenever I delete the height property within the main element in my css file, my background transition works but my scroll-snap doesn’t. And when I put it back, my scroll-snap works but my background doesn’t. Can someone help me to figure out a way to use both features at once?
4
Answers
I don’t know much about jQuery but I wonder why you didn’t change the color of the body right inside the IntersectionObserver, if you could use that to get your elements transition working correctly.
Hope that should work. It works for me very well. But if it doesn’t replace
document.body.classList
withdocument.querySelector("main").classList
& the thing would be fixed for sure.Reading you code I found another minor problem (different from what you asked) that I would like to inform you that is with the
scroll-snap
behaviour you have implemented. In mobile view if any user scrolls rigorously a very long distance, yourmain
element will jump multiple panels & not land on the very next page. You can addscroll-snap-stop: always
to yourdiv
to fix itUsing jQuery:
The upcoming :snapped pseudo selector should eliminate the need for JS:
https://drafts.csswg.org/css-scroll-snap-2/#ref-for-selectordef-snapped
Certainly! scroll-snap and background transitions can be used together to create engaging and visually appealing web designs. Scroll-snap provides a way to control the scroll behavior and create snap points, while background transitions allow smooth transitions b/w diff background style or images. By different two techniques