skip to Main Content
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


  1. 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.

    const observer = new IntersectionObserver((entries) => {
        entries.forEach((entry) => {
            if (entry.isIntersecting) {
                document.body.classList.add('color-' + entry.target.parentElement.dataset.color)
                entry.target.classList.add('show');
            } else {
                document.body.classList.remove('color-' + entry.target.parentElement.dataset.color) 
                entry.target.classList.remove('show');
            }
        });
    });
    
    // ...
    hiddenElements.forEach((el) => observer.observe(el));
    

    Hope that should work. It works for me very well. But if it doesn’t replace document.body.classList with document.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, your main element will jump multiple panels & not land on the very next page. You can add scroll-snap-stop: always to your div to fix it

    Login or Signup to reply.
  2. Using jQuery:

    const observer = new IntersectionObserver((entries) => {
        entries.forEach((entry) => {
            if (entry.isIntersecting) {
                $('body').addClass('color-' + $(entry.target).parent().data('color'));
                $(entry.target).addClass('show');
            } else {
                $('body').removeClass('color-' + $(entry.target).parent().data('color'));
                $(entry.target).removeClass('show');
            }
        });
    });
    

    The upcoming :snapped pseudo selector should eliminate the need for JS:
    https://drafts.csswg.org/css-scroll-snap-2/#ref-for-selectordef-snapped

    Login or Signup to reply.
  3. 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

    Login or Signup to reply.
  4. <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Stackover</title>
        <style>
            .Akashkumar {
      scroll-snap-type: y mandatory;
      overflow-y: scroll;
    }
    
    .Akash {
      height: 100vh;
      scroll-snap-align: start;
      transition: background-color 0.5s, background-image 0.5s;
    }
    
    .Akash:nth-child(odd) {
      background-color: #f0f0f0;
      background-image: url('image1.jpg');
    }
    
    .Akash:nth-child(even) {
      background-color: #cccccc;
      background-image: url('image2.jpg');
    }
    
    .Akash:hover {
      background-color: #ff0000;
      background-image: url('image3.jpg');
    }
    
        </style>
    </head>
    <body>
        <div class="Akashkumar">
            <div class="Akash">
              <h2>Part 1</h2>
            </div>
            <div class="Akash">
              <h2>part 2</h2>
            </div>
            <div class="Akash">
              <h2>part 3</h2>
            </div>
          </div>
    
    
    </body>
    </html> 
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search