How To: Fade In Animation On Scroll

Gina Lee
2 min readJan 20, 2020

First to introduce the components, we have:

  • The sticky header <header>
  • The hero section <div class="hero"> (the top fold).
  • And the details section <div class="details"> (the mid fold).

Desired result:

We want to make the button in the header appear with a fade-in effect as soon as the user scrolls past the top fold. (Please note that I’ve only added the crucial parts to the fade-in effect and left out all other code).

HTML:

<header>
<a href="#" class="logo><img src="logo.svg"></a>
<a href="#" class="button">Get started</a>
</header>
<div class="hero">
.
.
</div>
<div class="details">
.
.
</div>

Javascript:

window.addEventListener('DOMContentLoaded', function() {
window.addEventListener('scroll', handleScroll)
})
function handleScroll() {
const header = document.querySelector('header')
const midFold = header.nextElementSibling.nextElementSibling
const midFoldRect = midFold.getBoundingClientRect()
if (Math.ceil(midFoldRect.top) <= 0) {
header.querySelector('.button').className += ' fade-in'
window.removeEventListener('scroll', handleScroll)
}
}
  • We wait for the page to load with the DOMContentLoaded event listener.
  • Once loaded, the callback function runs, which adds another event listener. This second event listener listens for when the user is scrolling.
  • The handleScroll callback function gets invoked every time the user is scrolling. In it, we grab the header, mid-fold section, and a DOMRect object based off the mid-fold section and store them into constants. In this solution, I assume that the mid-fold section is going to be two siblings down from the header; hence const midFold = header.nextElementSibling.nextElementSibling.
  • In the handleScroll callback function, we are also checking to see if midFoldRect (the DOMRect object, which contains information about the size of the mid-fold section and its position relative to the viewport) rounded up hits zero (or less).
  • If midFoldRect's top value is equal or less than zero, then find the element with class .button from within header and give it a class of fade-in. The top value represents how far the top of the element is from the top-left corner of the viewport.
  • Then, remove the scroll event listener.

CSS:

header {
position: sticky;
top: 0;
width: 100vw;
}
header .button {
opacity: 0;
transition: background-color .3s, color .3s, opacity .5s ease-in;
}
.fade-in {
opacity: 1;
}

Once fade-in gets applied to the header’s <a href="#" class="button">, the button will go from zero opacity to one opacity in a duration of 0.5 seconds. This is due to the transition property applied to header .button, specifically the opacity .5s ease-in. That entire line is a short hand way of combining which specific css styles you would like to transition, as well as its duration.

Please let me know if you have any questions!

--

--