demosthenes.info

A blog by Dudley Storey on , , , , , , and anything else that strikes his fancy.

featured articles

popular favourites

CSS3 Tab Navigation

An array of folder tabs can work as a navigational metaphor for some sites. Creation of the tabs is relatively straightforward: the basic HTML markup would be the navigational list I’ve used many times before:

  1. <ul role="navigation">
  2. <li><a href="#">Home</a></li>
  3. <li><a href="#">About Us</a></li>
  4. <li><a href="#">Products</a></li>
  5. <li><a href="#">Contact</a></li>
  6. <li><a href="#">Your Privacy</a></li>
  7. </ul>

We’ll set the links side by side with a slight curve on the top corners using border-radius, and supply a linear gradient and box-shadow (as each tab will eventually overlap slightly). For the CSS3 parts I’ll provide just Webkit and Mozilla solutions in the code that follows to save space; in a real-world application you would cover every browser with added vendor prefixes.

  1. ul[role=navigation] li {
  2. display: inline; font-family: "Blue Highway", sans-serif;
  3. text-transform: uppercase;
  4. }
  5. ul[role=navigation] li a {
  6. text-decoration: none; border-bottom: none;
  7. color: #fff; padding: 0.8rem 2.6rem 2rem 2.6rem;
  8. border: 1px solid #777; border-radius: 5px 5px 0 0;
  9. background: -moz-linear-gradient(top, #dfc891, #776c51);
  10. background: -webkit-linear-gradient(top, #dfc891, #776c51);
  11. background: #dfc891;
  12. box-shadow: 0 0 15px rgba(0,0,0,0.5);
  13. -moz-transition: 0.2s all linear;
  14. -webkit-transition: 0.2s all linear;
  15. letter-spacing: 0.15rem;
  16. text-shadow: 0 1px 0 #000;
  17. }

I’ve also added a tiny bit of text-shadow to separate the link text from the background, and separated the letters slightly to provide greater legibility. I’ve also provided a default background for the links, should the browser not understand CSS3 gradients.

(Note that I’m using the CSS3 rem unit for measurement, but most any system would do).

We want to hide the excess of the tabs at the bottom, so I’ll supply more padding to the <ul> element and set overflow to hidden. (Note that there is no need to add a container element such as div to achieve this.)

Then we want to overlap the tabs. That’s easy: we’ll just apply a negative margin-left value to all of them:

  1. ul[role=navigation] li { margin-left: -1.2rem; }

The overlapping tabs stack in the order they appear in the code. To push one tab to the foreground (indicating which page we are on) we’ll create an id called forefront and apply it to a link (since we can be on only one page, and thus have one active tab, at a time). forefront will have position: relative (since we want to “nudge” the link without disturbing the others) and a z-index to visually push it to the foreground while we raise it vertically very slightly:

  1. ul[role=navigation] li a#forefront {
  2. position: relative; top: -0.2rem; z-index: 2;
  3. }

And then apply it to the link that represents the page we are on:

  1. <li><a href="#" id="forefront">About Us</a></li>

Finally, we want to animate the hover effect on the tabs: we’ll do so with a simple CSS transition, applied to the default state of the links to create smooth animation both from and returning to this point. As we want each link to move independently, without affecting the others, we’ll set a position: relative on those too, with a top: 0 position that we can use as an opening position:

  1. ul[role=navigation] li a {
  2. position: relative; top: 0;
  3. -moz-transition: 0.2s all linear; 
  4. webkit-transition: 0.2s all linear;
  5. }

Finally, we need to write the activation and new position of the links, activated by mouseover. We’ll also add an a:focus selector for touchscreen devices that are unable to detect :hover

  1. ul[role=navigation] li a:hover,  ul[role=navigation] li a:focus {
  2. top: -0.6rem;
  3. }

The only remaining issue is one of efficiency: in order to change which tab is actively in the foreground to indicate which page we are on, we would need to move the id onto the appropriate tab on each page. While this is certainty achievable, it is time-consuming, especially if we add more pages. It also means that we could not use the navigation as a server-side include.

In past articles I have shown how to get around this issue by using PHP to create “self-aware pages”; as a different solution, I’ll show the same idea implemented in a slightly more elegant fashion with JQuery.

web developer guide

featured comment

by JoelB in Goodbye, JQuery Validation: HTML5 Form Errors With CSS3

what i'm reading

A Storm of Swords: A Song of Ice and Fire: Book Three
A Storm of Swords: A Song of Ice and Fire: Book Three

what i'm watching

Californication: The Third Season
Californication: The Third Season

what i'm playing

Mass Effect 3 Collector's Edition
Mass Effect 3 Collector's Edition

what i'm hearing

Dub FX
Dub FX

blogs

podcasts

no ads ever

This blog is free of advertising, and always will be.

creative commons licensed

The content of this blog is free to use in whatever way you wish under the Creative Commons license.