Wookieguy
Wookieguy

Reputation: 231

A sticky Top Bar makes the page jump up when scrolling past it with Zurb Foundation

I am using the Zurb Foundation 4 framework for my site. I want to have a navbar that is positioned beneath a header that sticks to the top of the page when you scroll past. This works fine, except that the page content jumps up ~45 pixels when the Top Bar sticks to the top of the page. The effect can be seen on this page, though this is a different navigation element: http://foundation.zurb.com/docs/components/magellan.html

Is there some way to fix this, or do I have to change my site design to accomodate this bug?

The documentation is here: http://foundation.zurb.com/docs/components/top-bar.html

<div class="contain-to-grid sticky">
 <nav class="top-bar">
      <ul class="title-area">
        <!-- Title Area -->
        <li class="name">
          <h1><a href="/">Top Bar</a></h1>
        </li>
        <!-- Remove the class "menu-icon" to get rid of menu icon. Take out "Menu" to just have icon alone -->
        <li class="toggle-topbar menu-icon"><a href="#"><span>Menu</span></a></li>
      </ul>

      <section class="top-bar-section">
        <ul class="left">
          <li class="divider"></li>
          <li class="has-dropdown"><a href="/grid.php">Item 1</a>

            <ul class="dropdown">
              <li><label>Level One</label></li>
              <li><a href="#">Sub-item 1</a></li>
              <li><a href="#">Sub-item 2</a></li>
              <li class="divider"></li>
              <li><a href="#">Sub-item 3</a></li>
              <li class="has-dropdown"><a href="#">Sub-item 4</a>

                <ul class="dropdown">
                  <li><label>Level Two</label></li>
                  <li class="has-dropdown"><a href="#">Sub-item 1</a>

                    <ul class="dropdown">
                      <li><label>Level Three</label></li>
                      <li class="has-dropdown"><a href="#">Sub-item 1</a>

                        <ul class="dropdown">
                          <li><label>Level Four</label></li>
                          <li><a href="#">Sub-item 1</a></li>
                        </ul>
                      </li>
                      <li><a href="#">Sub-item 2</a></li>
                      <li><a href="#">Sub-item 3</a></li>
                      <li class="divider"></li>
                      <li><a href="#">Sub-item 4</a></li>
                    </ul>
                  </li>
                  <li><a href="#">Sub-item 2</a></li>
                  <li><a href="#">Sub-item 3</a></li>
                  <li><a href="#">Sub-item 4</a>
                </ul>
              </li>
              <li><a href="#">Sub-item 5</a></li>
            </ul>
          </li>
          <li class="divider"></li>
        </ul>
        <!-- Right Nav Section -->
        <ul class="right">
          <li class="divider hide-for-small"></li>
          <li><a href="#">Item 2</a></li>
        </ul>
      </section>
    </nav>

Upvotes: 5

Views: 10801

Answers (4)

Pierce Butler
Pierce Butler

Reputation: 215

This issue was fixed: https://github.com/zurb/foundation/issues/1993

Answer:

If you don't want it to jump to the top specify in data-options:

<nav class="top-bar" data-options="scrolltop: false">

or on initialization:

$(document).foundation('topbar', {scrolltop: false});

Upvotes: 6

Vinay Raghu
Vinay Raghu

Reputation: 1279

Remove the "sticky" class if you don't need it. Worked for me.

Upvotes: 2

RioBrewster
RioBrewster

Reputation: 105

On this page: https://github.com/jordanmerrick/foundation/commit/47391710c7b6d30ad54e50f3b2526cb8f6184be1

I found the code in foundation.topbar.js that adds padding to the body tag depending on whether top-bar is sticky or not:

if ($('.sticky').length > 0) {
   var distance = $('.sticky').length ? $('.sticky').offset().top: 0,
       $window = $(window);
      var offst = $('nav.top-bar').outerHeight()+20;
     (".sticky").after("<div class='top-bar-sticky-padding'></div>");
     $window.scroll(function() {
       if ( $window.scrollTop() >= ( distance ) ) {
          $(".sticky").addClass("fixed");

- $('body').css('padding-top',offst); }

      else if ( $window.scrollTop() < distance ) {
         $(".sticky").removeClass("fixed");

- $('body').css('padding-top','0'); } }); }

I'm not a javascript wizard - but it seems as if instead of setting offst to the height of the .top-bar, you set it to the value of .top-bar-sticky-padding directly, you can control the offset with a media query instead of forcing an offset the size of the top-bar.

Am I wrong? I'm nervous about "hacking core" but this seems to have solved the problem for me.

Upvotes: 1

Matt van Andel
Matt van Andel

Reputation: 657

This appears to be a hard-coded "feature" in Foundation 4's Javascript. Instead of merely preventing the default behavior of the link, it automatically forces the link to redirect to #, which causes the browser to jump to the top of the page. This appears to be intentional (more on that in a second).

The only alternative for now is to just not use the Top Bar component and create your own navigation using other, more reliable Foundation components. For instance, you can build your own navigation easily enough using both the .sticky class and simply defining a fresh <nav> element with all necessary <ul> menu items within.

The Top Bar has a very specific use by design... clicking "Menu" will use Javascript to reveal the navigation as a single column of options under the Top Bar. To ensure that mobile users can scroll a big set of options, this jumps the window to the top of the page and removes the fixed behavior until you close the menu. This works well enough when your Top Bar starts at the top of the page, but has serious implications when it doesn't (for instance, scrolling to the top of the page might move the menu out of view).

Now, this is purely opinion... but I'm really not a fan of Foundation's Top Bar implementation. Usability tests have shown that putting your mobile menus in the footer and linking to them with an anchor are more efficacious and user-friendly. You can use .hide-for-small to hide your desktop menu items and .show-for-small to reveal your own custom, anchored "Menu" link... that menu link would anchor to a mobile-specific menu in your footer (which again, you would reveal with .show-for-small).

Long story short: Top Bar is sloppy from a usability standpoint and broken (by design) for your use-case. I'd recommend building your own sticky menu :-)

Upvotes: 11

Related Questions