Search code examples
jqueryfixedanchor-scroll

Fixed nav and anchor


I have a navbar at top. When page loads, it is 'relative'. If I scroll. it changes to 'fixed'. There is an issue with anchors on page. When page loads and I am at top of page, clicking link to an anchor scrolls me to section and a part of it is hidden. When I click the same link in that position, it scrolls to the top of section correct.

What can I do to fix that problem?

The HTML

<nav id="fixedmenu">
 <ul>
  <li><a href="#brends">Brends</a></li>
 </ul>
</li>
...
<section id="brends"></section>

The javascript

   $(document).ready(function() {
    $('a[href^="#"]').click(function() {
     var target = $(this.hash);
     if (target.length == 0) target = $('a[name="' + this.hash.substr(1) + '"]');
     if (target.length == 0) target = $('html');
     $('html, body').animate({ scrollTop: target.offset().top }, 800);
     return false;
    });
   });

and

   $(document).ready(function() {
    var div = $('#fixedmenu');
    var start = $(div).offset().top;
    var wnd = $(document).width();
    $.event.add(window, "scroll", function() {
     var p = $(window).scrollTop();
     $(div).css('position',( (p) > start && wnd > 319 ) ? 'fixed' : 'static');
     $(div).css('top',((p)>start) ? '0px' : '');
     $(div).width($('.container').width());
     $(div).css('box-shadow', '0px 3px 5px 0px rgba(50, 50, 50, 0.4');
    });
   });

UPD: Solved in this way

   $(document).ready(function() {
    $('a[href^="#"]').click(function() {
     var target = $(this.hash);
     if (target.length == 0) target = $('a[name="' + this.hash.substr(1) + '"]');
     if (target.length == 0) target = $('html');
     var menuheight = $('#fixedmenu').height();
     var ofs = ( $('#fixedmenu').css('position') == 'fixed' ) ? menuheight : menuheight * 2;
     $('html, body').animate({ scrollTop: target.offset().top - ofs }, 800);
     return false;
    });
   });

Solution

  • This issue is to do with the fixed-nav. When an element if fixed, it is removed from the DOM and sits over top of it. Therefore all content moves up by the height of the nav bar.

    What you need to do is to apply a padding to your body in css, which ids the height of your nav bar and your page will scroll correctly to the anchors.

    eg: if the nav bar is 50px high:

    body{padding-top:50px}
    

    or to each section:

     section{padding-top:50px}
    

    depending on what your page looks like - you may want to set the padding only when the nav is fixed and remove it when it is relative. Or you may just keep the padding on and have breathing room at the top of your section.

    Another way to achieve this is to remove an offset to the offset.top in your code:

    $('html, body').animate({ scrollTop: target.offset().top - 50}, 800);