In this JavaScript Tutorial you will create a website with scroll animation using HTML CSS and JavaScript Intersection Observer API.

The main object of this tutorial is to demonstrate how the intersection Observer API works
Getting started with the tutorial project
down below you can find the complete HTML for the project which you need to copy in your index.html file.
Just a quick NOTE!
I have added a navigation for demonstration purposes only, this part is not covert in this tutorial but in a previous one. Please fell free to check out the previous tutorial for more information.
Blog Post :
YouTube Video
Now lest got over our HTML file quickly.
After the navigation bar comes a section for the header, then multiple section tags witch all have the class=”hide”. This class will be targeted later using JS to toggle the section visible or not using the intersection observer API.
One of the section also containes a list of
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.0/css/all.min.css"
integrity="sha512-xh6O/CkQoPOWDdYTDqeRdPCVd1SpvCA9XXcUnZS2FmJNp1coAFzvtCN9BmamE+4aHK8yyUHUSCcJHgXloTyT2A=="
crossorigin="anonymous"
referrerpolicy="no-referrer"
/>
<link rel="stylesheet" href="style.css" />
<script defer src="animate.js"></script>
<title>Scroll animated website</title>
</head>
<body>
<!-- Navigation -->
<nav id="main-nav" class="navbar bg-color">
<div class="navbar-logo">
<a class="navbar-brand" href="#">Navbar</a>
<button class="btn navbar-toggler">
<i class="nav-icon fa-solid fa-bars"></i>
</button>
</div>
<div class="navbar-collapse">
<ul class="navbar-nav me-auto">
<li class="nav-item">
<a class="nav-link active" href="#">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">About</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Contact</a>
</li>
</ul>
</div>
</nav>
<!-- Header -->
<section class="hide">
<h1 class="title">
Scroll <br />
Animation
</h1>
</section>
<section class="hide">
<h2>Learn Web development</h2>
<ul>
<li class="hide"><i class="fa-brands fa-html5"></i></li>
<li class="hide"><i class="fa-brands fa-css3-alt"></i></li>
<li class="hide"><i class="fa-brands fa-js"></i></li>
</ul>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Illo possimus
cupiditate ducimus eveniet in! Inventore iusto explicabo possimus rem
deleniti illum quis expedita obcaecati incidunt. Quibusdam totam illum
adipisci iusto.
</p>
</section>
<section class="hide">
<h2>Section 2</h2>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Illo possimus
cupiditate ducimus eveniet in! Inventore iusto explicabo possimus rem
deleniti illum quis expedita obcaecati incidunt. Quibusdam totam illum
adipisci iusto.
</p>
</section>
<section class="hide">
<h2>Section 3</h2>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Illo possimus
cupiditate ducimus eveniet in! Inventore iusto explicabo possimus rem
deleniti illum quis expedita obcaecati incidunt. Quibusdam totam illum
adipisci iusto.
</p>
</section>
<section class="hide">
<h2>Section 4</h2>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Illo possimus
cupiditate ducimus eveniet in! Inventore iusto explicabo possimus rem
deleniti illum quis expedita obcaecati incidunt. Quibusdam totam illum
adipisci iusto.
</p>
</section>
<section class="hide">
<h2>Section 5</h2>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Illo possimus
cupiditate ducimus eveniet in! Inventore iusto explicabo possimus rem
deleniti illum quis expedita obcaecati incidunt. Quibusdam totam illum
adipisci iusto.
</p>
</section>
<section class="hide">
<h2>Subscribe Like & Share</h2>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Illo possimus
cupiditate ducimus eveniet in! Inventore iusto explicabo possimus rem
deleniti illum quis expedita obcaecati incidunt. Quibusdam totam illum
adipisci iusto.
</p>
</section>
<script src="nav.js"></script>
</body>
</html>
Navigation CSS
/*Navigation*/
@import url("https://fonts.googleapis.com/css2?family=Aboreto&display=swap");
* {
margin: 0;
padding: 0;
list-style: none;
text-decoration: none;
font-family: "Aboreto", cursive;
}
header {
margin-top: 30vh;
}
.title {
text-align: center;
margin: 4rem 0;
font-size: 6rem;
text-shadow: 1px 3px 4px rgba(0, 0, 0, 0.45);
}
h2 {
text-align: center;
margin: 2rem 0;
font-size: 3rem;
text-shadow: 1px 3px 4px rgba(0, 0, 0, 0.45);
}
.navbar {
display: flex;
justify-content: center;
align-items: center;
background-color: #333;
color: #eee;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
justify-content: space-between;
align-items: center;
padding: 1rem;
user-select: none;
}
.navbar-logo {
width: 100%;
display: flex;
justify-content: center;
align-items: center;
justify-content: space-between;
margin-right: 1rem;
font-weight: 900;
}
.navbar-brand {
margin-left: 1rem;
color: inherit;
}
.btn {
margin: 0.25rem 0.125rem;
padding: 0.35rem 1.25rem;
font-family: inherit;
font-weight: 400;
font-size: 1rem;
letter-spacing: 0.6px;
border-radius: 0.3rem;
color: #fff;
background-color: #000;
border: none;
box-shadow: 0 2px 5px rgba(51, 51, 51, 0.3);
transition: 0.3s ease;
transform: scale(0.8);
}
.btn:hover {
cursor: pointer;
box-shadow: none;
transition: 0.3s ease;
background: rgba(0, 0, 0, 0.75);
}
.navbar-toggler {
display: none;
margin-left: auto;
}
.navbar-nav {
display: flex;
justify-content: center;
align-items: center;
}
@media screen and (max-width: 768px) {
.navbar-toggler {
display: block;
margin-right: 1rem;
}
.navbar-nav {
display: none;
}
.title {
font-size: 3rem;
}
}
/* @media screen and (max-width: 768px) {
} */
.navbar-nav .nav-item {
margin-right: 1rem;
transition: 0.3s ease-in-out;
}
.navbar-nav .nav-item:hover {
text-shadow: 1px 3px 4px rgba(0, 0, 0, 0.45);
transition: 0.3s ease-in-out;
}
.navbar-nav .nav-link {
color: inherit;
}
.navbar-nav.showNavbar {
display: flex;
align-items: flex-start;
flex-direction: column;
gap: 15px;
margin: 15px;
width: 100%;
animation: navFadeIn 0.4s ease-in-out;
}
.navbar.showNavbar {
display: flex;
align-items: flex-start;
flex-direction: column;
}
@keyframes navFadeIn {
0% {
opacity: 0;
transform: translateY(-30%);
}
100% {
opacity: 1;
transform: translateY(0);
}
}
.fadeIn {
animation: navFadeIn 0.4s ease-in-out;
}
.closeNav {
animation: navFadeOut 0.4s ease-in-out;
}
@keyframes navFadeOut {
0% {
opacity: 1;
transform: translateY(0);
}
100% {
opacity: 0;
transform: translateY(-30%);
}
}
.nav-link.active {
font-weight: 900;
color: red;
}
Navigation JS
const navbar = document.querySelector(".navbar");
// resize the navigation
window.addEventListener("resize", () => {
let WindowWidth = window.innerWidth;
if (WindowWidth > 768) {
navbarCollapse.classList.remove("showNavbar");
navbar.classList.remove("showNavbar");
if (navbarTogglerIcon.contains("fa-times")) {
navbarTogglerIcon.remove("fa-times");
navbarTogglerIcon.add("fa-bars");
}
}
});
const navbarToggler = document.querySelector(".navbar-toggler");
const navbarCollapse = document.querySelector(".navbar-nav");
let navbarTogglerIcon = navbarToggler.querySelector(".nav-icon").classList;
navbarToggler.addEventListener("click", function () {
navbarCollapse.classList.toggle("showNavbar");
navbar.classList.toggle("showNavbar");
if (navbarTogglerIcon.contains("fa-bars")) {
navbarTogglerIcon.remove("fa-bars");
navbarTogglerIcon.add("fa-times");
} else {
navbarTogglerIcon.remove("fa-times");
navbarTogglerIcon.add("fa-bars");
}
});
const navLinks = document.querySelectorAll(".nav-link");
navLinks.forEach((navLink) =>
navLink.addEventListener("click", function (e) {
// remove .active from all nav links
navLinks.forEach((navLink) => navLink.classList.remove("active"));
// add .active to target element
console.log(e.target);
classToggler(e.target, "active");
})
);
const title = document.querySelector(".title");
function classToggler(element, className) {
if (element.classList.contains(className)) {
element.classList.remove(className);
} else {
element.classList.add(className);
title.innerHTML = element.innerHTML;
title.classList.add("fadeIn");
setTimeout(() => title.classList.remove("fadeIn"), 500);
}
}
Sections CSS
/* Section */
section {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
min-height: 100vh;
padding: 0 10vw;
}
.hide {
opacity: 0;
transition: all 2s ease-out;
transform: translateX(-100%);
}
.animate-in {
opacity: 1;
transform: translateX(0);
}
section:nth-child(odd) {
background-color: #333;
color: #eee;
}
section ul {
display: flex;
margin-bottom: 2rem;
font-size: 5rem;
gap: 15vw;
}
section ul li:nth-child(1) {
color: orangered;
transition-delay: 1s;
}
section ul li:nth-child(2) {
color: blue;
transition-delay: 1.1s;
}
section ul li:nth-child(3) {
color: yellow;
transition-delay: 1.2s;
}
Scroll Animation Website using JavaScript
Now its time to use the Intersection Observer.
const observer = new IntersectionObserver((elements) =>
elements.forEach((element) => {
element.isIntersecting
? element.target.classList.add("animate-in")
: element.target.classList.remove("animate-in");
console.log(element);
})
);
document
.querySelectorAll(".hide")
.forEach((animeEl) => observer.observe(animeEl));
Watch the complete project on YouTube
For more detailed information about the responsive navbar html css js project, check out the complete video tutorial on my YouTube channel.
1 thought on “Scroll Animated Website”