State saving navigation with CSS6

February 24th, 2010 by Freddy Kelly posted in Development

A common feature of most web navigation systems is the “active” state, e.g. the page you are currently on is highlighted in some way using an additional CSS class.

This effect is easily achieved when using somekind of back end CMS to power your website. For example WordPress automatically assigns a class of “current” to links which are active. This makes it really straightforward to hook into with a basic CSS selector, eg:

#nav ul li.current {
	border-bottom: 2px solid red;
}

(this is purely an example and would probably look pretty horrific.)

Achieving the same effect with a more basic site (with no CMS) can be a little trickier. You can either re-make the nav code in each page and add the class in manually (don’t do this). This is naff though as it creates duplication all over the place, meaning making changes to your menu would be a nightmare.

A better solution would be to code a single version of your menu (keep it in an include file), then use CSS selectors to point out the “active” item. Below is a quick method for doing this…

Step 1. The basic HTML:

<ul>
  <li id="nav-home"><a href="/">Home</a></li>
  <li id="nav-about"><a href="about.html">About us</a></li>
  <li id="nav-services"><a href="services.html">Services</a></li>
  <li id="nav-links"><a href="links.html">Links</a></li>
  <li id="nav-contact"><a href="contact.html">Contact us</a></li>
</ul>

This is a very bog-standard UL > LI > A structure, the only difference being we have given each list item it’s own unique #ID with the prefix “nav-”.

Step 2. Building our pages:

The next step is to build each of our pages. For each page we will add a #ID to the body tag, matching the #ID we set in our navigation. eg:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
	<title>About us | Fake Company Ltd</title>
	<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
	<link rel="stylesheet" type="text/css" href="style.css" media="all" />
</head>
<body id="about">...

Step 3. The CSS magic…

Now we have our two matching #IDs setup for each of our pages/links, we simply need to hook them together with a bit of CSS:

body#about #nav-about a {
	border-bottom: 2px solid red;
}

This statement simply selects the A tag within the #nav-about LI on any page that is rapped in a body tag with the #about ID... Simples ^.^

There you have it, a simple method for creating that “active” state without butchering your HTML. It’s worth also noting that using a body id can help in many other areas, for example: if a design requires a different layout on a single page, you can hook into the body id to apply styles to this specific page – meaning you don’t have to create any additional classes/ids :-)

  1. Dave says:

    its really helpful…

  2. Dave says:

    listing for navigation is really important from seo point of view

  3. Gareth says:

    Thats a really good article Fred. I have been wondering how to do this for a while and always ended up using javascript…..anyone seen any similar tutorials?

  4. Kendall Bulter says:

    Would you please translate your blog into German as I’m not that comfortable reading it in English? I’m getting tired of using Google Translate all the time, there is a little WP plugin called like global translator which will translate all your posts by default- that would make reading posts on your awesome blog even more pleasant. Cheers mate, Kendall Bulter!

  5. Tom Girling says:

    I prefer to use php to create a current class on a link – I use a php function to create my menu links which looks at the current page & does it all for me….I wouldn’t really want to have to go through all the pages on a site giving the body tag on every page a different ID….much less coding involved!

    I do appreciate where you are coming from though & I’m sure for some people only using html & CSS on a small site, it works perfectly.

  6. Freddy Kelly says:

    @Tom Yes, I agree. As mentioned you would normally do this with your chosen CMS, especially as your navigation would probably be generated dynamically anyway – it makes much more sense.

    This technique is really just for basic HTML sites with static content/pages.

    Thanks for your comment!

Leave a Reply