There is a jQuery-code that animates a smooth transition from menu items to anchors. For the first menu items that are immediately visible, everything works fine. But from those menu items to which you need to scroll, the transition is performed incorrectly (to see the problem, the code shoud be run in a small snippet, not expanded to full screen):
$('.main-nav a').on('click',function(e){
e.preventDefault();
let elementClick = $(this).attr('href');
let destination = $(elementClick).offset().top - $(elementClick).parent().offset().top - $(elementClick).parent().scrollTop();
$('main').animate({ scrollTop: destination }, 1000);
});
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
height: 100vh;
font-size: 16px;
}
header, footer {
height: 20vh;
border: 1px solid maroon;
display: flex;
justify-content: center;
align-items: center;
}
main {
height: 60vh;
overflow: auto;
padding: 20px;
}
.main-nav {
display: flex;
flex-direction: column;
margin-bottom: 30px;
}
.main-nav a {
padding: 5px 0;
}
.content {
padding: 20px;
color: white;
height: 100vh;
}
#one, #four, #seven {
background-color: red;
}
#two, #five, #eight {
background-color: green;
}
#three, #six, #nine {
background-color: blue;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<header>header</header>
<main>
<div class="main-nav">
<a href="#one">1. One</a>
<a href="#two">2. Two</a>
<a href="#three">3. Three</a>
<a href="#four">4. Four</a>
<a href="#five">5. Five</a>
<a href="#six">6. Six</a>
<a href="#seven">7. Seven</a>
<a href="#eight">8. Eight</a>
<a href="#nine">9. Nine</a>
</div>
<div class="content" id="one">One</div>
<div class="content" id="two">Two</div>
<div class="content" id="three">Three</div>
<div class="content" id="four">Four</div>
<div class="content" id="five">Five</div>
<div class="content" id="six">Six</div>
<div class="content" id="seven">Seven</div>
<div class="content" id="eight">Eight</div>
<div class="content" id="nine">Nine</div>
</main>
<footer>footer</footer>
Obviously the problem is with the variable `destination`. But I do not know how to calculate it correctly for all menu items.
If you position
mainrelative, then$(elementClick).position().top + $(elementClick).parent().scrollTop();is enough to calculate the correct position to scroll to.
Difference between the methods, https://api.jquery.com/offset/#offset:
By adding
position: relative,mainbecomes the offset parent.