I’m Dudley Storey, the author of Pro CSS3 Animation. This is my blog, where I talk about web design and development with , and . To receive more information, including news, updates, and tips, you should follow me on Twitter or add me on Google+.

web developer guide

my books

Book cover of Pro CSS3 AnimationPro CSS3 Animation, Apress, 2013

my projects

CSSslidy: an auto-generated #RWD image slider. 1.5K of JS, no JQuery. Drop in images, add a line of CSS. Done.

tipster.ioAutomatically provides local tipping customs and percentages for services anywhere.

CSS Tab Navigation

css / navigation

Estimated reading time: 3 minutes

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

<ul id="nav">
<li><a href="#">Home</a>
<li><a href="#">About Us</a>
<li><a href="#">Products</a>
<li><a href="#">Contact</a>
<li><a href="#">Your Privacy</a>

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).

ul#nav li { display: inline; text-transform: uppercase; }
ul#nav li a { text-decoration: none; border-bottom: none; color: #fff;
padding: 0.8rem 2.6rem 2rem 2.6rem; border: 1px solid #777; border-radius: 5px 5px 0 0;
background: linear-gradient(to bottom, #dfc891, #776c51);
box-shadow: 0 0 15px rgba(0,0,0,0.5); transition: 0.2s top linear;
letter-spacing: 0.15rem; text-shadow: 0 1px 0 #000;

I’ve 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:

ul#nav 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:

ul#nav li a#forefront { position: relative; top: -0.2rem; z-index: 2; }

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

<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:

ul#nav li a { position: relative; top: 0; transition: 0.2s all linear; }

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

ul#nav li a:hover,  ul[role=navigation] li a:focus { top: -0.6rem; }

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.

comments powered by Disqus

This site helps millions of visitors while remaining ad-free. For less than the price of a cup of coffee, you can help pay for bandwidth and server costs while encouraging further articles.