DEV Community

Nick Ciliak
Nick Ciliak

Posted on • Originally published at coolcssanimation.com on

How to make an element fade out on scroll

Fading an element out on scroll is a subtle effect that helps draw attention away from what is exiting the viewport and towards whatever is below.

It works like this: as the user scrolls down the page, when the given element reaches the top of the viewport, it begins to fade out depending on how much the user has scrolled. By the time the element exits the viewport, it has completely faded out.

Take a look at this demo.

To make the effect, we need the trigger and action. The trigger is the user scrolling. When a user scrolls, the scroll event is fired. We can then call a function, our action. The action in this case is updating the opacity of the element. The more the user scrolls, the less opaque the element should become.

Here's how it works. Start with adding a scroll event listener and a handler method:

function scrollHandler() {
    // this runs every time the user scrolls
}

window.addEventListener('scroll', scrollHandler);
Enter fullscreen mode Exit fullscreen mode

Now whenever the user scrolls, the scrollHandler function will be called. (Note: it will run a lot if the user is continuously scrolling!)

Now we need to update the element's opacity based on how much the user has scrolled. This will involve a calculation using the distance scrolled, the distance from the element to the top of the page (if there is any), and the element's height.

var distanceToTop = window.pageYOffset + element.getBoundingClientRect().top;
Enter fullscreen mode Exit fullscreen mode

We need the distance from the top of the element to the top of the page (note: the top of the page, not the top of the viewport) because we want to start fading out when the user has scrolled that amount of distance. If the user has scrolled that amount, it means the user has scrolled enough so that the element is just at the top of the viewport.

var elementHeight = element.offsetHeight;
Enter fullscreen mode Exit fullscreen mode

Then we need the height of the element. We want the element to fade out evenly from the start of its exit to the end of its exit. To do that, we need to compare the amount scrolled to the height of the element.

var scrollTop = document.documentElement.scrollTop;
Enter fullscreen mode Exit fullscreen mode

Finally, we need the amount that the user has scrolled. This is the magic number that powers our calculations.

Here's the calculation. If the scrollTop > distanceToTop, that means we should start fading out. The opacity should be 1 minus the difference of the amount we've scrolled and the distance of the element to the top of the page, divided by the element's height. As the scrollTop or amount scrolled increases, this result will increase. Since we're subtracting it from 1, the more it increases, the closer to 0 the final opacity comes.

var opacity = 1;

if (scrollTop > distanceToTop) {
  opacity = 1 - (scrollTop - distanceToTop) / elementHeight;
}
Enter fullscreen mode Exit fullscreen mode

If the opacity is not greater than or equal to 0, we don't need to set it on the element. (A negative opacity value will do nothing.)

Here's what it looks like all together:

function scrollHandler() {
  var element = document.getElementById('header');

  var distanceToTop = window.pageYOffset + element.getBoundingClientRect().top;
  var elementHeight = element.offsetHeight;
    var scrollTop = document.documentElement.scrollTop;

    var opacity = 1;

    if (scrollTop > distanceToTop) {
        opacity = 1 - (scrollTop - distanceToTop) / elementHeight;
    }

    if (opacity >= 0) {
        element.style.opacity = opacity;
    }}

window.addEventListener('scroll', scrollHandler);
Enter fullscreen mode Exit fullscreen mode

Element fade out on scroll code example

Here's what the full code looks like for this demo. Please note, using the scroll event to perform DOM updates in this way can be resource-intensive and should be used sparingly. If you need to create this effect on one or two elements on the page, you'll be fine. But if you have to do it to many, it's likely you'll want to make some additional optimizations.

var header = document.getElementById('header');

function fadeOutOnScroll(element) {
    if (!element) {
        return;
    }

    var distanceToTop = window.pageYOffset + element.getBoundingClientRect().top;
    var elementHeight = element.offsetHeight;
    var scrollTop = document.documentElement.scrollTop;

    var opacity = 1;

    if (scrollTop > distanceToTop) {
        opacity = 1 - (scrollTop - distanceToTop) / elementHeight;
    }

    if (opacity >= 0) {
        element.style.opacity = opacity;
    }
}

function scrollHandler() {
    fadeOutOnScroll(header);
}

window.addEventListener('scroll', scrollHandler);
Enter fullscreen mode Exit fullscreen mode

Feel free to take a look at the CodePen demo.

Top comments (0)