CSSnewbie

About CSSnewbie

Our mission is to help the beginning to intermediate web designer master the subtleties of CSS by offering CSS tutorials, tips, and techniques.

Posts Filed Under ‘Navigation’

Intelligent Navigation Bars with JavaScript and CSS

Arnold as the Terminator

I’ve developed a trick over the years that I’ve used on a number of websites now for making my sites’ navigation bars “intelligent” or “self-aware.” By that, I mean that the navigation bar automatically knows which tab/button/whatever should be considered the currently active link, without having to manually specify a class or ID on either the body tag or on the links themselves. And since I’ve found it so useful, I thought I should share it with you, even though it does involve a smidgen of JavaScript.

I start with an unordered list that looks something like this:

<ul id="nav">
	<li><a href="/about/">About Us</a></li>
	<li><a href="/contact/">Contact Us</a></li>
	<li><a href="/archives/">Our Archives</a></li>
	<li><a href="/free/">Free Stuff</a></li>
</ul>

Then I turn the unordered list into a navigation bar, using the technique I described in my last article. I won’t delve into those details here, for the sake of brevity and my fierce, fierce (fierce!) hatred of repetition, but you might want to read the prior post first if you missed it. The navigation bar gives me tabs that expand nicely for different text sizes and respond by growing and changing color when people hover over them.

But what if you want to somehow indicate to your users which page or section of the site they’re currently visiting? For that, I use the following JavaScript magic:

function setActive() {
  aObj = document.getElementById('nav').getElementsByTagName('a');
  for(i=0;i<aObj.length;i++) {
    if(document.location.href.indexOf(aObj[i].href)>=0) {
      aObj[i].className='active';
    }
  }
}

This tiny little function does four things:

  1. Finds all of the anchor tags (via getElementsByTagName) inside of the element with the “nav” id (getElementById) – our unordered list, in this case.
  2. Cycles through every anchor tag that we’ve found (our “for” loop).
  3. Compares the “href” of the anchor tag with the page we’re currently on (document.location, which is the URL that shows up in the bar at the top of your browser) to see if the href is contained therein.
  4. If the href is a match for the page we’re on, it sets a class of “active” on the anchor tag (className=’active’).

Then we have to make sure to run the setActive script when we load the page, so that our tab gets set as soon as the page is loaded. I accomplish that with this line of JavaScript somewhere below my setActive function within the same file:

window.onload = setActive;

After that comes the CSS. Because we’ve used our JavaScript to set a class of “active” on our tab, all we need to do is style the active class. I usually do something fairly simple like the code below, which make the tab drop down from the top, applies a background color, and gives it a dark border on all sides but the top:

ul#nav li a.active {
	padding-top: 15px;
	background-color: #075a97;
	border: 1px solid #333;
	border-top: none;
}

And voila! Your navigation bar suddenly knows and indicates exactly where you are, without having to remember to specify any extra IDs on the body tag or navigation links. You can see it in action here.

As a caveat, this technique assumes that you’re not linking to a lot of commonly-nested directories in your navigation. For instance, if you have one tab going to “/blog/” and another to “/blog/archive/”, then both tabs will inherit the “active” class when you’re in the archive directory (because /blog/ is part of /blog/archive/). One way to get around this limitation would be to be more specific on the first tab – for instance, linking to “/blog/index.php” instead.

Tab-Based Navigation in Six (or Seven) Easy Steps

example of tab-based navigation

Navigation bars are the signposts of the web world: we take them for granted because of their ubiquity, but we’d all have a much harder time getting around without them. On most websites, nav bars hold a position of honor near the very top of the page, meaning they’re one of the first things your users see upon entering your site. As such, there’s a lot of pressure on navigation bars to look clean, act sophisticated, and ply the client’s wife with small talk and Manhattans while you close the deal.

Because of all that pressure, a lot of designers turn to the Tools of Yesteryear to ensure their navigation looks exactly the way they expect it to. Table cells, flash buttons, images, and (shudder) image maps make far too common an appearance at the top of otherwise respectable websites.

But you don’t need all that! Here’s a simple tutorial on how to create a perfectly respectable tabbed navigation bar with clean, happy XHTML and a few lines of CSS. I’m using tabs because I’m fond of them, but you could adapt these techniques to create whatever sort of navigation you’d like.

We’ll start with an unordered list, like so:

<ul id="nav">
	<li><a href="/about/">About Us</a></li>
	<li><a href="/contact/">Contact Us</a></li>
	<li><a href="/archives/">Our Archives</a></li>
	<li><a href="/free/">Free Stuff</a></li>
</ul>

Why an unordered list? Well, because when you get right down to it, what is a nav bar but a list of links, given in no semantically vital order? Nothing, I tell you. Nothing. Once we have our list, we have a page that looks something like this. I’ve applied a couple other styles to my body tag (moved the text away from the edges, set a font family, and given my page a top border), but as you can see, our navigation list is Plain Jane.

The next thing we’ll need to do is move our navigation to where we want it. I want my tabs to look like they’re coming out of that border I’ve applied to the body, so let’s move the list to the top right corner:

ul#nav {
	position: absolute;
	top: 10px;
	right: 0; }

The “position: absolute;” rule pulls our list out of the normal flow of the document so that we can put it wherever we want. I then use a couple of other rules to move it 10 pixels from the top (i.e., the width of my border) and place it right along the right side of the page. If you wanted your navigation on the left, a rule of “left: 0;” would do the trick.

But our list still looks like a list (in everything but IE), and we can’t have that. The first step along the road to total list domination is to remove the margins, padding, and bullets that make our list so list-like. We’ll append our previous rule, so it now reads thusly:

ul#nav {
	position: absolute;
	top: 10px;
	right: 0;
	list-style: none;
	margin: 0;
	padding: 0; }

This is fairly straightforward: the “list-style” rule removes the bullets from our list, and then we set our margins and padding to zero to make the list fit snug against our top border, as you can see here.

Next up, we’ll put our list items in a single horizontal row. This is accomplished with a single rule:

ul#nav li {
	float: left; }

As you can see, our list items are now arranged horizontally. Now let’s use some CSS magic to make them look a little more like tabs:

ul#nav li a {
	display: inline;
	float: left;
	padding: 8px 5px 3px 5px;
	margin-right: 5px;
	background-color: #034a7f; }

We’re modifying the anchor tag here instead of the <li> tag for one primary reason: we want the entire tab to act as a link, not just the text portion. By applying our padding and background color to the anchor tag instead of the list item, we make our entire tab clickable. You can see the effect here.

Oh, and that bit at the top about displaying inline and floating left? Well, that’s what we in the biz like to call a “hack.” The two rules are working together to accomplish a single task: to make Internet Explorer 6 play nicely. The “float: left” property reminds IE6 that we want our clickable area to take up all the space we’ve given it, not just the text part – without this statement, only the text (and not the whole tab) is clickable in IE. But floating the links also introduces some weird spacing problems in IE: the browser suddenly decides to start doubling the size of our margins (more on that can be found here). But the “display: inline” rule reminds Internet Explorer that we really want all these elements in a snug little row, so no extra margin gets inserted.

Of course, after all that work our tabs are still a little tough to read, so let’s apply a couple more styles to our links:

ul#nav li a {
	display: inline;
	float: left;
	padding: 8px 5px 3px 5px;
	margin-right: 5px;
	background-color: #034a7f;
	color: #fff;
	font-weight: bold;
	text-decoration: none; }

This change is basic, but effective. I set the text color to white, the font weight to bold, and used “text-decoration: none;” to remove the underline from our tabs. The change is a big improvement.

Now, we could be done here, but I like to add a touch of interactivity to my tabs. Another benefit of making the tabs out of our anchor tags is that anchor tags respond to the :hover state in all browsers… including Internet Explorer (even though it ignores it everywhere else). So let’s add some style to our hover states:

ul#nav li a:hover {
	padding-top: 12px;
	background-color: #075a97; }

And just like that, our navigation bar responds to interaction. Hover your cursor over the tabs and watch how they drop down and change color in response to your every whim. That little touch of interactivity helps ensure your users know exactly what they’re clicking on, and adds a touch of sophistication to the top of your page. And better still, the tabs (and text within) grow and shrink automatically when your users change the page’s text size – I’d like to see an image map do that! With these simple styles in your bag of tricks, your client’s wife doesn’t stand a chance.

If you found this post useful, watch for a follow-up article later in the week, where I’ll show you how to make your navigation elements “self-aware” with just a touch of JavaScript and a couple extra CSS rules. If that sounds interesting, subscribe to the feed. If that sounds scary, you’ve watched too many Terminator movies.

Update: You can read the second article in this two-part series here.

Style your links with CSS

A Spider Web - Photo by MR+G

Anchor tags (a.k.a. links or hyperlinks) (these things: <a>) are one of the more ubiquitous elements of the web world. In fact, it’s the anchor tags that put the ‘Web’ in the World Wide Web – they’re the points of interconnectivity, like strands in a spider web, that hold this whole crazy Net of ours together.

And we all know what links look like, too: they’re dark blue, underlined, and stand out on a page like the varicose veins on the backs of great-Aunt Esther’s legs. And just as we don’t understand why Esther would choose to wear those shorts in public, we don’t understand why something as common as an anchor tag should have to look so darn unattractive.

With CSS, links don’t have to be ugly.

But here’s the kicker: with CSS, links don’t have to be ugly. They can look pretty much however you want. Here are a few of the things you can do to make your links stand out without sticking out:

Change the Color. Some stick-in-the-mud Web proponents would have you believe that blue is the only color a hyperlink should ever wear, in much the same way that white shoes after Labor Day are a social faux-pas. Their argument is that people are used to seeing blue, underlined links; to mess with this convention is to anger the gods and confuse your readers. I say bollocks! Any text that stands out from the rest will attract attention. And green can stand out just as well as blue:


a {
	color: #6c6;
}

This gives us a lovely link the exact shade of a seasick leprechaun. How’s that for fancy?

Underline, Schmunderline. Personally, I’m not a big fan of underlined text. Too much of it can be a distraction – everything on the page seems to be clamoring for attention. So why don’t we remove the underline from that hyperlink:

a {
	text-decoration: none;
}

And now, our links don’t overwhelm the nearby text.

Or, you could even make the underline only appear when someone puts their mouse over the link (my personal favorite):

a {
	text-decoration: none;
}
a:hover {
	text-decoration: underline;
}

The rules above state that “normal” anchor tags should not have any sort of decoration: no underlines, in other words. However, when someone “hovers” over an anchor, we should put the underline back.

Image is Everything. If you wanted to get really fancy, you could even make a small image (an icon, if you will) appear next to your links. All you have to do is create your image at the appropriate size, put it on your server where your CSS can get to it, and do something like this:

a {
	padding-left: 16px;
	background-image: url(icon.gif) no-repeat;
}

This rule is a little more complicated, so I’ll explain in greater detail. First, we applied some padding to the anchor tag… we need some room for the image to show up. Then, we applied the image to the background of the element (which, as we learned last time, is applied to the padding around an element). Under normal circumstances, the background would repeat itself in every direction, showing up underneath our link text. We don’t want that, so we added the ‘no-repeat’ condition to stop it from showing up more than once. And the result: links with images.

Putting it All Together. When our powers combine, we become… Captain Hyperlink! Or, at the very least, we can have aesthetically pleasing links that somehow manage to attract attention without overwhelming the page. And without reminding us of great-Aunt Esther’s visit last summer.

If we take what we know about CSS classes and apply that to this example, we could even make certain types of links look different from others:

a.pdf {
	color: #c00;
	font-weight: bold;
	text-decoration: none;
	padding-left: 10px;
	background-image: url(pdf_icon.gif) no-repeat;
}
a.pdf:hover {
	text-decoration: underline;
}

Now how’s that for some fancy linkage? I encourage you to take these examples I’ve provided and expand upon them. What can you make your links do?