0

I'm using Foundation, and would like a sticky top bar with sub links to internal parts of the page. The problem is, if I do it naïvely, i.e.:

<div class="sticky">
  <nav class="top-bar" data-topbar role="navigation">
    <section class="top-bar-section">
      <ul class="left">
        <li><a href="#/intro">Intro</a></li>
        <li><a href="#/basic">Basic</a></li>
      </ul>
    </section>
  </nav>
</div>

... not much stuff ...

<a name="/intro"></a>
<h2>Intro</h2>

... much stuff ...

<a name="/basic"></a>
<h2>Basic</h2>

... much stuff ...

... then the top of the page scrolls to the top of the header, which is then obscured by the sticky top bar. See the jsfiddle and click on the top links to see what I mean.

How can I keep a sticky top bar, yet have clicks on the top bar scroll the page such that the header is right below the top bar, instead of obscured?

Claudiu
  • 224,032
  • 165
  • 485
  • 680

2 Answers2

1

Solution #1

Add an <h2> style rule to the CSS, something like:

h2 {
margin-top: 30px;
}

Solution #2

If you want to minimise the extra white-space added to the document, you might try something like the following, instead:

a[name]:target {
padding-top: 30px;
}

This will only add white-space to the <a> element which is currently targeted.

Rounin
  • 27,134
  • 9
  • 83
  • 108
  • Thanks. This works with `padding-top`, but leaves a lot of unnecessary space. There must be a better way ... – Claudiu Nov 18 '15 at 21:28
  • I have added an alternative solution to the post above, which will result in less whitespace being added to the page. – Rounin Nov 18 '15 at 22:50
0

I ended up writing a function to do this.

  1. It changes the window location, so acts as if the user clicked an <a href='#internal-ref></a> link.
  2. It scrolls to the link anyway using scrollIntoView() (thanks to this answer for making me aware of its existence).
  3. It then scrolls back by $("nav.top-bar").height() pixels using window.scrollTo().

The code:

function scrollToAnchor(name) {
  // change location
  window.location = '#' + name;

  // scroll to element anyway
  var element = $("a[name='" + name + "']")[0];
  if (!element) {
    console.error("No such anchor with name", name);
    return;
  }
  element.scrollIntoView();

  // scroll back to leave room for sticky nav
  var stickyNavHeight = $("nav.top-bar").height();
  console.log(stickyNavHeight);
  window.scrollTo(window.scrollX, window.scrollY - stickyNavHeight);
}

Live demo.

Community
  • 1
  • 1
Claudiu
  • 224,032
  • 165
  • 485
  • 680