<!-- ======= Header ======= -->
<header>
<nav>
<h1>Animated scroll menu</h1>
<ul>
<li><a data-page="home" href="#">Home</a></li>
<li><a data-page="about" href="#">About</a></li>
<li><a data-page="contact" href="#">Contact</a></li>
<div class="bubble"></div>
</ul>
</nav>
</header>
<!-- ======= Main ======= -->
<main>
<section data-index="0" class="home">
<h2>Home</h2>
</section>
<section data-index="1" class="about">
<h2>About</h2>
</section>
<section data-index="2" class="contact">
<h2>Contact</h2>
</section>
</main>
/*--------------------------------------------------------------
# General
--------------------------------------------------------------*/
:root {
--bg-header: white;
--header-color: black;
--main-color: white;
--shadow-color: rgba(0, 0, 0, 0.3);
--home-gradient-color1: #56ab2f;
--home-gradient-color2: #a8e063;
--about-gradient-color1: #06beb6;
--about-gradient-color2: #48b1bf;
--contact-gradient-color1: #fc4a1a;
--contact-gradient-color2: #f7b733;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: sans-serif;
}
/*--------------------------------------------------------------
# Header
--------------------------------------------------------------*/
header {
box-shadow: 0px 3px 10px var(--shadow-color);
position: sticky;
top: 0px;
background-color: var(--bg-header);
}
nav {
min-height: 10vh;
margin: auto;
width: 90%;
display: flex;
align-items: center;
justify-content: space-between;
}
nav h1,
nav ul {
font-size: 1.5rem;
flex: 1;
}
nav ul {
list-style-type: none;
display: flex;
justify-content: space-between;
}
nav a {
color: var(--header-color);
text-decoration: none;
}
@media (max-width: 800px) {
nav h1,
nav ul {
font-size: 0.6rem;
}
}
/*--------------------------------------------------------------
# Main
--------------------------------------------------------------*/
section {
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
section h2 {
font-size: 5rem;
color: var(--main-color);
}
.home {
background: linear-gradient(
to right top,
var(--home-gradient-color1),
var(--home-gradient-color2)
);
}
.about {
background: linear-gradient(
to right top,
var(--about-gradient-color1),
var(--about-gradient-color2)
);
}
.contact {
background: linear-gradient(
to right top,
var(--contact-gradient-color1),
var(--contact-gradient-color2)
);
}
.bubble {
position: absolute;
z-index: -2;
background: linear-gradient(
to right top,
var(--home-gradient-color1),
var(--home-gradient-color2)
);
transform: scale(2);
transition: all 0.5s ease;
}
const sections = document.querySelectorAll('section');
const bubble = document.querySelector('.bubble');
const gradients = [
'linear-gradient(to right top, var(--home-gradient-color1), var(--home-gradient-color2))',
'linear-gradient(to right top, var(--about-gradient-color1), var(--about-gradient-color2))',
'linear-gradient(to right top, var(--contact-gradient-color1), var(--contact-gradient-color2))',
];
const navCheck = (entries) => {
entries.forEach((entry) => {
const { className } = entry.target;
const activeAnchor = document.querySelector(`[data-page=${className}]`);
const gradientIndex = entry.target.getAttribute('data-index');
const coords = activeAnchor.getBoundingClientRect();
const directions = {
height: coords.height,
width: coords.width,
top: coords.top,
left: coords.left,
};
if (entry.isIntersecting) {
bubble.style.setProperty('left', `${directions.left}px`);
bubble.style.setProperty('top', `${directions.top}px`);
bubble.style.setProperty('width', `${directions.width}px`);
bubble.style.setProperty('height', `${directions.height}px`);
bubble.style.background = gradients[gradientIndex];
}
});
};
const options = {
threshold: 0.7,
};
const observer = new IntersectionObserver(navCheck, options);
sections.forEach((section) => {
observer.observe(section);
});
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.