Issue
I am trying to build a Navbar where the padding shrinks as the user starts to scroll. The shrinking is done by simply adding a class to the header element on scroll and then changing the padding in CSS.
The issue I am having is that when I scroll to around 50px where the 'shrink' class is added to the the toggleClass gets stuck in a loop making the navbar flip between the two css properties really quickly. This can be fixed by applying a 'position: fixed' to the header element instead of 'sticky' however I need to use 'position:sticky' in this case.
$(window).on("scroll touchmove", function() {
$('header').toggleClass('shrink', $(document).scrollTop() > 50);
});
body {
padding: 0;
margin: 0;
}
header {
background: red;
position: sticky;
top: 0;
padding: 50px 0;
}
header.shrink {
padding: 10px 0;
}
.nav-container {
max-width: 1400px;
margin: 0 auto;
background: green;
display: flex;
align-items: center;
justify-content: space-between;
}
.logo {
padding: 0;
margin: 0;
display: block;
}
nav ul {
list-style: none;
background: orange;
display: flex;
}
main {
max-width: 1400px;
margin: 0 auto;
}
main .container {
background: rgb(34, 193, 195);
background: linear-gradient(180deg, rgba(34, 193, 195, 1) 0%, rgba(253, 187, 45, 1) 100%);
min-height: 6000px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<header>
<div class="nav-container">
<div class="logo">
Logo
</div>
<nav>
<ul>
<li>Home</li>
<li>About</li>
<li>Contact</li>
</ul>
</nav>
</div>
</header>
<main>
<div class="container">
<h2>Content</h2>
</div>
</main>
Click here for a codepen example
Solution
The problem is that the size of your element changes and then the browser re-calculates the scrollposition giving you that nice glitch.
This is a known bug: chromium, bugzilla
Update: The only "solution" I've found is to have an outer element that NEVER changes size (in your case the header). That one is made sticky and it's height should be defined by height + bottom margin (so that it takes up the right amount of initial space in the document and dont trigger the recalculation.
$(window).on("scroll touchmove", function() {
$('header').toggleClass('shrink', $(document).scrollTop() > 50);
});
body {
padding: 0;
margin: 0;
}
header {
overflow-anchor: none;
position: sticky;
top: 0;
height: 70px;
margin-bottom:80px;
}
header.shrink .sticky-wrapper {
padding: 10px 0;
}
.sticky-wrapper {
background: red;
padding: 50px 0;
transition: padding 0.2s ease-in-out;
}
.nav-container {
max-width: 1400px;
margin: 0 auto;
background: green;
display: flex;
align-items: center;
justify-content: space-between;
}
.logo {
padding: 0;
margin: 0;
display: block;
}
nav ul {
list-style: none;
background: orange;
display: flex;
}
main {
max-width: 1400px;
margin: 0 auto;
}
main .container {
background: rgb(34, 193, 195);
background: linear-gradient(180deg, rgba(34, 193, 195, 1) 0%, rgba(253, 187, 45, 1) 100%);
min-height: 6000px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<header>
<div class="sticky-wrapper">
<div class="nav-container">
<div class="logo">
Logo
</div>
<nav>
<ul>
<li>Home</li>
<li>About</li>
<li>Contact</li>
</ul>
</nav>
</div>
</div>
</header>
<main>
<div class="container">
<h2>Content</h2>
</div>
</main>
Answered By - Despina Kastani
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.