Sticky nav bar is flickering when reaching bottom of page

Brian picture Brian · Feb 12, 2013 · Viewed 18.2k times · Source

I recently go my nav bar to act as a sticky nav bar that adheres to the top of my page after I scroll down to a certain point, however, when I reach the bottom of my page the entire nav bar flickers, and even disappears sometimes. Think of it as an old TV that would flicker and you would end up hitting on the side to stop the flickering. How would I hit my nav bar to stop it from flickering. Here is my site so you can witness all the glory of the flicker.

Here is my HTML for the nav:

<div id="nav-wrapper">
<div id="nav" class="navbar navbar-inverse affix-top" data-spy="affix">
  <div class="navbar-inner" data-spy="affix-top">
    <div class="container">

      <!-- .btn-navbar is used as the toggle for collapsed navbar content -->
      <a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
      </a>

      <!-- Everything you want hidden at 940px or less, place within here -->
      <div class="nav-collapse collapse">
        <ul class="nav">
            <li><a href="#home">Home</a></li>
            <li><a href="#service-top">Services</a></li>
            <li><a href="#contact-arrow">Contact</a></li>
        </ul><!--/.nav-->
      </div><!--/.nav-collapse collapse pull-right-->
    </div><!--/.container-->
  </div><!--/.navbar-inner-->
</div><!--/#nav /.navbar navbar-inverse-->
</div><!--/#nav-wrapper-->

And here is my JS:

<script>
    $(document).ready(function() {
        $('#nav-wrapper').height($("#nav").height());
        $('#nav').affix({
            offset: 675
        });
    });
</script>

An important note should be that this only began occurring after I changed the offset in my JS from offset: $('#nav').position() to offset: 675. You might say, well just change it back, but with the old offset, my sticky nav would jump prematurely to the top.

Thanks for any help of input you can provide me!

Answer

Leo picture Leo · May 14, 2013

Your site looks fine to me now, but I was brought here looking for a solution to the same problem, so I thought I would add my experience here.

The issue I had was that the affix code applies a class (e.g. affix or affix-bottom) to the affixed element based on its vertical position on the page. I'll call these 'zones'.

If the CSS for the new class is such that it moves the affixed element vertically, it may end up instantly in a different zone, so the class is removed, so it moves back, so the class is applied etc... The position therefore alternates with every onscroll event, and flickers.

The key for me was to ensure that the data-offset-top / data-offset-bottom values and CSS classes and were set so that the element no longer moves vertically when the affix toggles. I.E. Something like:

<div class="someClass" data-spy="affix" data-offset-top="20" data-offset-bottom="300">
  ...
</div>

(The data-offset-bottom is to reattach the element so it doesn't crash into e.g. a tall footer, and won't always be necessary.) And then:

.someClass.affix {
  /* position: fixed; already applied in .affix */
  top: 10px;
  /* might also need e.g. width: 300px; as position: fixed; removes the element from its parent. */
}
.someClass.affix-bottom {
  position: absolute; /* Start scrolling again. */
  top: auto; /* Override the top position above. */
  bottom: 20px; /* It should stop near the bottom of its parent. */
}

Sometimes the jump when the CSS classes are changed pushes the element further into the zone it is entering, which leads to a single 'flick' at the boundary, but not repeated flickering.

N.B. I think the very slight jump when your menu becomes fixed could possibly be smoothed out in this way, by making a very slight adjustment to the vertical position of the element when affixed, and/or by setting data-offset-top to some appropriate value.

Cheers,

Leo