tactile

– thoughts on CSS, UIs and UX.

position:fixed; headers and hash URLs / fragment identifiers

Posted: September 19th, 2012 Author:

I came across an interesting problem today while working with a fixed header and a hash-URL or fragment identifier URL. When loading a URL with a fragment identifier, the fixed header can obscure the content you’re linking too; not great.

Some of the suggested fixes on the web are a little short-sighted – I might have a more elegant solution, but it’s still not bullet-proof.

What’s a fragment identifier?

Think of a fragment identifier as a nifty tool to create a shortcut to a specific section or fragment of the HTML document. Fragment identifiers can be appended to URLs by first using a hash (#) symbol as a prefix.
Traditionally, to mark-up the fragment in a document, you’d use empty anchors as a fragment identifier, such as:

<a name="navigation"></a>

…but you can use any ID-ref in a web document as a fragment identifier. The W3C use this to great effect in their tomes of specs, such as in this example: www.w3.org/TR/html5/the-a-element.html#the-a-element.

The problem

When using a fixed position header, any fragment URLs or using links that reference fragments, the header can obscure the content you’re linking to – this is well explained on @necolas’ blog post.

The possible fixes

Some of the suggested fixes available on the web don’t apply to any ID reference, or are a bit tardy. One of the better solutions proposed by CSS-tricks (and @necolas) suggested using the ::before pseudo-element to create an offset height equal to the height of the fixed header (e.g. 285px) as such:

h2:before { 
  display: block; 
  content: " "; 
  margin-top: -285px; 
  height: 285px; 
  visibility: hidden; 
}

One major drawback here is you’d have to add a selector for each possible fragment identifier use. In this case, the fix would only apply to fragment identifiers in <h2>s.

The second drawback is that this applies to all <h2>s regardless as to whether they’re being used as fragment identifiers or not.

Enter: :target

The :before and :after Pseudo-elements don’t work in IE8 or less. If IE8 or less is not your concern, then you could use the CSS3 selector: :target to overcome both drawbacks as such:

*:target::before { 
  display: block; 
  content: " "; 
  margin-top: -285px; 
  height: 285px; 
  visibility: hidden; 
}

Note: This is not a fix for the shortcomings outlined in @necolas’ article, it just makes your use of selectors more efficient.

Thoughts

IMO, position:fixed; is more trouble than its worth, especially when mixed into a mobile context, browser support is still sparse. We wouldn’t be in this fragment-identifier-target mess if it wasn’t for position:fixed.

It feels like the whole position:fixed implementation is poor in general. If you want to see browser weirdness, start messing with position:fixed. It’s a jungle out there folks.

3 Comments on “position:fixed; headers and hash URLs / fragment identifiers”

  1. 1 Alex Maughan said at 10:39 am on September 20th, 2012:

    Another option is to progressively enhance all your fragment links with JavaScript. Once again, not ideal with regard to entry level phones etc, but may solve the problem more comprehensively across all devices/browsers.

    The added benefit of using JavaScript (with some help re development speed with a library like jQuery), is that you can animate the window scroll, which helps show the user that they are still on the same page but have just been moved to a different part. Can prevent users form getting disorientated and, for example, using the browser back button, as well as giving them a clearer understanding of how to get back to where they were before.

    Created a a quick demo of what I mean here:

    http://maughan.me/lab/fragments/

  2. 2 Alex Maughan said at 10:46 am on September 20th, 2012:

    Also, meant to mention that, being progressively enhanced, with JS disabled the fragment links will still work (minus the fixed offset solution).

    But if JS is disabled, then you can revert back to your CSS solution(s) above to create the offset.

  3. 3 HTML fragment identifiers | stylus said at 4:57 pm on March 25th, 2014:

    […] Read more  on this at this blog: http://tactile.co.za/blog/2012/positionfixed-headers-and-hash-urls-fragment-identifiers/ […]