title: Fixed page header and in-page anchors vs. Tripit Slate
body: <p>This question is about getting hashed URLs (like <code>mydomain.com/somepage#SomeAnchor</code>) to scroll out from under a fixed page header, when those URLs are jump targets. It's an offshoot of <a href="https://stackoverflow.com/questions/4086107/html-positionfixed-page-header-and-in-page-anchors">this answered question</a> – but I'm wondering whether anyone has gotten its answers to fully work on the Tripit Slate docs-publishing framework?</p>
  
  <p><a href="http://buddycloud.com/api#accounts" rel="nofollow noreferrer">This Slate-based site</a> is not ours, but it shows our predicament: </p>
  
  <ul>
  <li><p>If you click a link from the left nav, the center text column scrolls
  to your selected heading. All is well.</p></li>
  <li><p>But try clicking a link in the body text. E.g., from
  <a href="http://buddycloud.com/api#accounts" rel="nofollow noreferrer">http://buddycloud.com/api#accounts</a>, click the <code>push notification</code>
  link. You scroll to an entirely different subheading. The target you requested
  actually has focus, but it's hidden under the top nav bar. (Scroll up and 
  you'll see it.)</p></li>
  </ul>
  
  <p>Our <em>left-nav</em> links work cleanly, like the buddycloud site's. Thanks to <a href="https://stackoverflow.com/questions/4086107/html-positionfixed-page-header-and-in-page-anchors">Sidnicious' 4086107 answer</a> we've placed an invisible pseudo-element above all our headings, as devised by Nicolas Gallagher. Here's the CSS class:</p>
  
  <pre><code>.jumptarget::before {
    content:"";
    display:block;
    height:85px; /* fixed header height*/
    margin:-85px 0 0; /* negative fixed header height */
  }
  </code></pre>
  
  <p>And here's how we apply it to our headings:</p>
  
  <pre><code>## &lt;span class="jumptarget" id="SomeAnchorName"&gt; SomeHeading &lt;/span&gt;
  </code></pre>
  
  <p>Which is what works fine for the left nav. From css-tricks, we've learned why it nevertheless fails for "in-page" hashed links:</p>
  
  <blockquote>
    <p>When a link includes a hash, like this: <code>&lt;a href="#section-two"&gt;Section Two&lt;/a&gt;</code>
     ...the browser window will scroll...to the minimum
    possible position to make that element wholly visible. ...flush with
    the top edge of the browser window. This can be..., in the case of a
    fixed-position, stay-on-top header, hugely problematic.</p>
  </blockquote>
  
  <p>Indeed, our fixed top nav looks much like buddycloud's (ours is 82 px high). And our in-page hashed links hide under it, just as theirs so.</p>
  
  <p>With two important exceptions: First, in cases where the target "hashed" URL resides within the <em>same</em> markdown file as the outbound link, the target cleanly peeks out from under the fixed header, just as left-nav links do. (On the source side, Slate stores all content as <code>.md</code> files.) This localizes the problem: Link targets hide <em>only</em> where Slate has to traverse to a <em>separate</em> target <code>.md</code> file, and to then concatenate <code>#&lt;SomeAnchorName&gt;</code> to complete the URL.</p>
  
  <p>Second, we <em>have</em> found a hack that gets all "in-page" hashed links to clear our top header. This involves dual-tagging our headings in HTML, using two spans. The first is an empty dummy span, which sits above the actual heading text to trick the scroll behavior. (It's tagged with our above <code>jumptarget</code> class.) On the heading itself, we apply a separate span with a class, which corrects a left indent from the first hack. The dual-tagging looks like this:</p>
  
  <pre><code>&lt;h2&gt;
      &lt;span class="jumptarget" id="bogusN"&gt; &amp;nbsp; &lt;/span&gt;
      &lt;span class="jumpleft"&gt; Bogus Heading 2 &lt;/span&gt;
  &lt;/h2&gt;
  </code></pre>
  
  <p>But although this reveals our "in-page" hashed links, it completely breaks our left nav. Due to some interaction with Slate's <code>tocify</code> left-nav generator, any headings tagged in this way misbehave as follows: (1) Hide their children in the left nav. (2) When clicked, prevent the <code>jumptarget</code> class from scrolling them out from under the top header. (3) When clicked, collapse their parent in the left nav.</p>
  
  <p>So in all, our dilemma is that: Our fix for links from our left nav leaves our in-text links broken. Whereas, our fix for the in-text links breaks our left-nav fix.</p>
  
  <p>If anyone has globally solved this on Tripit Slate, or <code>tocify</code>, or a different framework, we'd be very grateful for pointers. Clean CSS, hacky HTML, or jivey JavaScript – we're agnostic. Thanks!</p>
  
  <p>[Update 7/13/16:] Here's the script that our developer added to <code>layout.erb</code>, to clear link targets from getting hidden by a persistent header. We're testing whether it works for all links. Comments very much invited:</p>
  
  <pre><code>&lt;script&gt;
      var container = $('.page-wrapper .content');
      var body = $('body');
      var headerHeightPixels = 85;
  
      container.on('click', function(event) {
          var target = $(event.target);
  
          if (target.is('a') &amp;&amp; target.attr('href').charAt(0) === '#') {
              setTimeout(function() {
                  $('body').scrollTop($('body').scrollTop() - headerHeightPixels)
              }, 0);
          }
      });
  &lt;/script&gt;
  </code></pre>