Accessibly Hiding Skip Links

The “skip navigation” link has become nearly ubiquitous in standards-based web design, due largely to Zeldman’s teachings (see pg. 200… you have the book, right?). In a nutshell, it’s simply a link to an ID’d element or named anchor on the current page that allows a visitor to jump right to the meat, bypassing whatever else may come before it in the document. Including a skip link at the top of each page is just one quick and easy way to greatly increase your site’s accessibility. It’s invaluable to users of screen-reading software, who otherwise might be forced to listen to a long series of navigation links on every single page before they get to what they’re really after.

The gospel according to Zeldman encourages authors to include this handy link at the top of the document, then hide it from modern browsers with a simple CSS rule:

<a href="#content" class="hide">Skip navigation</a>
.hide { display: none; }

This is nice, since sighted users of modern browsers usually don’t have any trouble finding the content of a web page. The link will only be readable in a user-agent that doesn’t support CSS (or one that overrides author style sheets in favor of its own). That was the theory, anyway. In reality, some popular screen-readers understand the display: none; property:value pair and obediently ignore those elements, completely defeating the purpose of the skiplink. This calls for an alternative hiding method.

The most obvious declaration to use instead of display: none; would be visibility: hidden;. However, graphical browsers maintain the hidden element as part of the normal page flow, reserving appropriate whitespace and flowing content around it, even though the element itself isn’t displayed. Design-wise, this is undesirable. So the key is to hide the skip link and remove it from the flow, so as far as your graphic design is concerned it doesn’t exist, yet it’s still officially a readable part of the document.

When the CSS position property with a value of absolute, relative, or fixed is applied to an element, that element is removed from the natural page flow — subsequent content flows over/under/behind it undisturbed. We can then use other positioning properties with negative values to move the element outside the browser portal:

.hide { visibility: hidden; position: absolute; left: -9999px; }

Unless your display is wider than ten thousand pixels (and if so, I want one!), this should slide the link well outside the window. It would seem by this point that visibility: hidden; isn’t really needed, but leaving it in will exclude the skiplink from the page’s natural tab order. Of course, if you want the skiplink to be selectable via tabbing, by all means leave it visible (though still offscreen and out-of-flow). If this hidden link is contained within a relatively-positioned parent, it will be absolutely positioned in relation to that container. If it’s inheriting any other styles, such as margins, line-height, etc., these can still interfere with your design unless overridden in the .hide rule. Consider yourself thoroughly caveated.

1 comment

  1. After publishing this I finally got around to implementing it on my own site… With a small variation.

    My sidebar menus come after the content in the document structure (which is good both for accessibility and search engines – get your content closer to the top and crawlerbots will drink it up). So rather than simply letting a user skip to the content, I added a link to let them skip directly to the navigation. Then at the top of my #sidebar div I include a link to jump back to the content.

Comments are closed.