Не получается корректно анимировать navbar при скролле (position: fixed)
Идея в том, чтобы при прокрутке страницы НИЖЕ высоты окна браузера, nav-меню плавно выезжало сверху и фиксировалось. И наоборот, при прокрутке ВЫШЕ высоты окна браузера, nav-меню плавно уезжало вверх.
Выезжает вниз-то оно нормально, а вот вверх улетает без анимации и вообще не понимаю как все реализовать корректно.
Взял простенькую реализацию navbar с bootstrap для примера. вот весь код:
css
<style>
body{
min-height: 2000px;
}
.fix{
z-index: 1000;
width: 100%;
position: fixed;
animation: anim 1s forwards;
}
@keyframes anim{
0%{
transform: translateY(-100%);
}
100%{
transform: translateY(0);
}
}
</style>
html:
<nav class="navbar navbar-dark bg-dark">
<div class="container-fluid">
<form class="d-flex">
<input class="form-control me-2" type="search" placeholder="Search" aria-label="Search">
<button class="btn btn-outline-success" type="submit">Search</button>
</form>
</div>
</nav>
js (jquery)
<script>
var wHeight = $(window).innerHeight();
$(window).on('scroll', function() {
var offset = $(this).scrollTop();
if (offset > wHeight) {
$('nav').addClass('fix');
} else {
$('nav').removeClass('fix');
}
});
</script>
Пробовал в блоке else помимо удаления fix, добавлять класс например endAnim, который делал бы противоположную анимацию. Но бесполезно, так как fix удаляется, nav мгновенно улетает вверх.
Весь день вот сижу играюсь с этой анимацией и все не получается никак реализовать. Погуглил, тоже ничего подходящего не нашел.
Как же все-таки реализовать эту, казалось бы, простую задачу???
Буду очень благодарен за помощь!
Ответы (1 шт):
Вам здесь не нужно правило @keyframes, оно лишнее.
Причина, почему у вас так получается, очевидная. Когда вы удаляете класс fix, то значение у свойства position меняется с fixed на relative. Поэтому у вас элемент и "улетает", то есть возвращается на своё исходное место.
var wHeight = $(window).innerHeight();
$(window).on('scroll', function() {
var offset = $(this).scrollTop();
if (offset > wHeight) {
$('nav').addClass('fix');
} else {
$('nav').removeClass('fix');
}
});
body {
min-height: 2000px;
}
nav {
position: fixed;
z-index: 1000;
width: 100%;
transform: translateY(-200%);
transition: all 1s;
}
.fix {
transform: translateY(0%);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<nav class="navbar navbar-dark bg-dark">
<div class="container-fluid">
<form class="d-flex">
<input class="form-control me-2" type="search" placeholder="Search" aria-label="Search">
<button class="btn btn-outline-success" type="submit">Search</button>
</form>
</div>
</nav>
upd/
var wHeight = $(window).innerHeight();
$(window).on('scroll', function() {
var offset = $(this).scrollTop();
if (offset > wHeight) {
$('nav').addClass('fix');
$('nav').removeClass('no_fix');
} else {
$('nav').removeClass('fix');
$('nav').addClass('no_fix');
}
});
body {
min-height: 2000px;
}
nav {
position: relative;
z-index: 1000;
width: 100%;
transform: translateY(0);
}
.fix {
position: fixed;
animation: fix 1s forwards;
}
@keyframes fix {
0% {
transform: translateY(-200%);
}
100% {
transform: translateY(0);
}
}
.no_fix {
position: relative;
animation: no_fix 1s forwards;
}
@keyframes no_fix {
0% {
position: fixed;
transform: translateY(0);
}
90% {
position: fixed;
transform: translateY(-200%);
}
100% {
position: relative;
transform: translateY(0);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<nav class="navbar navbar-dark bg-dark">
<div class="container-fluid">
<form class="d-flex">
<input class="form-control me-2" type="search" placeholder="Search" aria-label="Search">
<button class="btn btn-outline-success" type="submit">Search</button>
</form>
</div>
</nav>