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; henceconst midFold = header.nextElementSibling.nextElementSibling
. - In the
handleScroll
callback function, we are also checking to see ifmidFoldRect
(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 withinheader
and give it a class offade-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!