Search code examples
javascriptjquerycssflexboxbulma

Setting nav to fixed after scrolling to a certain position


I'm designing a landing page using a Flexbox based CSS Framework - Bulma.

I created a navbar below a fullheight section and I'm using it to scroll through sections, which gets fixed/unfixed depending whether the page is scrolled below the fullheight section. This is the JQuery code I'm using to add/remove the fixed position class:

$(window).scroll(function () {
    if ($(window).scrollTop() > $('#cover').height()) {
        $('#navbar-sticky').addClass('is-fixed');
    }
    if ($(window).scrollTop() < $('#cover').height()) {
        $('#navbar-sticky').removeClass('is-fixed');
    }
});

The issue I'm facing is that when the navigation bar is set to position: relative - default position, when clicking on any link to a section it "overscrolls" using the height of the navigation bar.

Another issue is that when navigating to the first section - where the class is toggled, there's also an overscroll, I believe using if ($(window).scrollTop() >= $('#cover').height()) (is greater than or equal to) fixes that.

Here's a relevant codepen that describes my issue https://codepen.io/miraris/full/wrLdwN I'm also using a smooth-scroll library in that codepen, but that's irrelevant and the issue is the same when it's removed (just no offset).


Solution

  • When an element's position is changed to Fixed, a portion equal to it's height is freed from DOM and elements below it shift up.

    We can have a wrapper to fill the space created by navbar becoming fixed.

    Html

    <div class="navbar-space-fill hidden"></div>
    <div id="navbar-sticky">
    .... your HTML ....
    </div>
    

    Javascript

    On page load-

    $('.navbar-space-fill').css({'height':$('#navbar-sticky').height()});
    

    When position of navbar becomes fixed -

    $('.navbar-space-fill').removeClass('hidden');
    

    else -

    $(".navbar-space-fill").addClass("hidden");