Becky Becky - 6 months ago 35
jQuery Question

Expanding margin with header

I have a header that when you scroll down it stays in a static flow and goes away. Then when you scroll up the header appears where ever the user is on the page. This all works great, but when I am scrolling all the way up to the top, my margins are expanded due to the header and then once it reaches the very top the margin rise back up to match the header.

I have a banner image with an over-lay. Scroll down a ways and then scroll back up. You will see the changed margin with the image over-lay. Along with that the header is 'fidgety'.

What can I do so the margin always stays the same and doesn't nudge back up?

var didScroll;
var lastScrollTop = 0;
var delta = 5;
var navbarHeight = $('header').outerHeight();

$(window).scroll(function(event){
didScroll = true;
});

setInterval(function() {
if (didScroll) {
hasScrolled();
didScroll = false;
}
}, 250);

function hasScrolled() {
var st = $(this).scrollTop();

// Make sure they scroll more than delta
if(Math.abs(lastScrollTop - st) <= delta)
return;

// If they scrolled down and are past the navbar, add class .nav-up.
// This is necessary so you never see what is "behind" the navbar.
if (st > lastScrollTop && st > navbarHeight){
// Scroll Down
$('header').removeClass('nav-down').addClass('nav-up');
} else {
if (st < navbarHeight) {
if (st === 0 || st < 1) {
$('header').css('position', 'static');
}
} else {
$('header').css('position', 'fixed');
}
// Scroll Up
if(st + $(window).height() < $(document).height()) {
$('header').removeClass('nav-up').addClass('nav-down');
}
}

lastScrollTop = st;
}


<header class="nav-down">
</header>


header {
background: #F2F2F2;
height: 120px;
top: 0;
transition: top 0.5s ease-in-out;
width: 100%;
z-index: 100;
border-bottom: 1px solid #9C9C9C;
}
.nav-up {
top: -123px;
}

Answer

This is caused because when you change the position of header to fixed it causes the DOM to be nudged up the same height of header because you're header no longer effect's DOM layout.

The fix:

Would be to append margin-top with the same height of header when you apply position: fixed to your #service-img here it is in code ( Untested since you're using live site ):

function hasScrolled() {
    var st = $(this).scrollTop();

    // Make sure they scroll more than delta
    if (Math.abs(lastScrollTop - st) <= delta)
        return;

    // If they scrolled down and are past the navbar, add class .nav-up.
    // This is necessary so you never see what is "behind" the navbar.
    if (st > lastScrollTop && st > navbarHeight) {
        // Scroll Down
        $('header').removeClass('nav-down').addClass('nav-up');
    } else {
        if (st < navbarHeight) {
            if (st === 0 || st < 1) {
                $('header').css('position', 'static');
                $('#service-img').css('margin-top', '0px');
            }
        } else {
            $('header').css('position', 'fixed');
            $('#service-img').css('margin-top', '120px');
        }
        // Scroll Up
        if (st + $(window).height() < $(document).height()) {
            $('header').removeClass('nav-up').addClass('nav-down');
        }
    }

    lastScrollTop = st;
}

EDIT:

Just tested on your site with my code using Chrome DevTools and it works fine. Hope that helped!