I’m working on a navbar that shrinks using intersection observer that adds a class accordingly but when the transition starts, it starts from 0 padding.
Here right when the .nav-scrolled is added, the CSS properties are also added to the nav bar. But right when it adds, the padding starts transitioning from 0. What can I do?
const nav = document.querySelector("nav");
const sectionOne = document.querySelector(".intersection");
const sectionOneObserver = new IntersectionObserver(function(entries, sectionOneObserver) {
entries.forEach(entry => {
if (!entry.isIntersecting) {
nav.classList.add("nav-scrolled")
} else {
nav.classList.remove("nav-scrolled")
}
});
});
sectionOneObserver.observe(sectionOne)
.nav-container {
display: flex;
justify-content: center;
}
nav {
position: fixed;
width: 100vw;
padding-block: 20px;
display: flex;
justify-content: space-between;
align-items: center;
transition: 1s ease;
}
nav>* {
margin-inline: 5%;
}
nav>div {
width: 300px;
display: flex;
justify-content: space-between;
align-items: center;
overflow: hidden;
padding-block: 10px;
}
.nav-scrolled {
width: 80%;
padding-block: 15px;
font-size: 20%;
border-radius: 20px;
transform: translateY(15px);
}
.nav-scrolled>* {
margin-inline: 15px;
}
.intersection{height:10vh}
.body{color:red; height:120vh}
<div class="nav-container">
<nav>
<a href="#">
<h1>Heading</h1>
<h2>Heading-2</h2>
</a>
<div>
<a href="#">link1</a>
<a href="#">link2</a>
<a href="#">link3</a>
</div>
</nav>
</div>
<div class="intersection"></div>
<div class="body"><div>
2
Answers
It’s not that the padding starts from 0. This happens because you have
margin-inline
on the children of the nav element. This margin disappears when you scroll and the children don’t have a transition-tag, so that’s why it appears to be jumping. I just removed this css-line. Seems to work just fine 🙂It seems to be a problem with the
.nav-scrolled>*
selector. It’s the property change on this that is causing the jump. It’s easier to see this when the transition is extended to be5s
long.The problem is happening because you do not have a
transition
applied onnav>*
even though you are changing properties when scrolled, thus an immediate jump with no transition visible. The fix is to move your transition to apply to both the parent.nav
selector and thenav>*
selector, like this: