I’m trying to make side navigation dots such as the following image:
I’ve managed to do it using HTML, CSS, and JS
html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="/assets/style.css">
</head>
<body>
<div class="section" id="home" data-label="Home">Home</div>
<div class="section" id="about" data-label="About Us">About Us</div>
<div class="section" id="contact" data-label="Get In Touch">Get In Touch</div>
<nav class="nav">
<div class="nav-item">
<a href="#home" class="nav-link"></a>
<span class="nav-label">Home</span>
</div>
<div class="nav-item">
<a href="#about" class="nav-link"></a>
<span class="nav-label">About us</span>
</div>
<div class="nav-item">
<a href="#contact" class="nav-link"></a>
<span class="nav-label">Get In Touch</span>
</div>
</nav>
<script>
function activateNavigation() {
const sections = document.querySelectorAll(".section");
const navLinks = document.querySelectorAll(".nav-link");
const observer = new IntersectionObserver(
(entries) => {
navLinks.forEach((navLink) => {
navLink.classList.remove("nav-link-selected");
});
const visibleSection = entries.find((entry) => entry.isIntersecting);
if (visibleSection) {
const visibleSectionId = visibleSection.target.getAttribute("id");
const correspondingNavLink = document.querySelector(`.nav-link[href="#${visibleSectionId}"]`);
if (correspondingNavLink) {
correspondingNavLink.classList.add("nav-link-selected");
}
}
},
{ threshold: 0.5 }
);
sections.forEach((section) => observer.observe(section));
}
// Run the function when the DOM is fully loaded
document.addEventListener("DOMContentLoaded", activateNavigation);
</script>
</body>
</html>
and this is the css:
html {
scroll-behavior: smooth;
}
body {
font-family: "Quicksand", sans-serif;
margin: 0;
color:#000;
overflow: hidden;
}
/* uncomment to hide the scrollbar but keep the scroll action*/
/*
body::-webkit-scrollbar{
display: none;
} */
.section {
height: 100vh;
}
#home {
background: #aff8db;
}
#about {
background: #ffabab;
}
#contact {
background: #fff5ba;
}
#section4 {
background: #2496b3;
}
#section5 {
background: #002B36;
}
#section6 {
background: #41eda8;
}
#section7 {
background: #df3838;
}
#section8 {
background: #c3f0fb;
}
.nav {
--nav-gap: 10px;
padding: var(--nav-gap);
position: fixed;
right: 0;
top: 50%;
transform: translateY(-50%);
display: inline-block;
}
.nav-link:hover ~ .nav-label {
opacity: 1;
}
.nav-label{
color: #000;
font-weight: bold;
opacity: 0;
transition: opacity 0.1s;
}
.nav-item {
align-items: center;
display: flex;
margin-bottom: var(--nav-gap);
flex-direction: row-reverse;
}
.nav-link {
height: 25px;
width: 25px;
background-color:rgba(0, 0, 0, 0.3);
border-radius: 50%;
display: inline-block;
padding: 10px;
margin: 5px;
transition: transform 0.1s;
}
.nav-link-selected{
background: #000000;
transform: scale(1.2);
}
I have managed to convert the above code to Dash except for the js part of it which observes which section takes more than 50% of the page and then automatically makes the dot bigger such as the following image: