Mar24 Accessible and Pretty Image-based Navigation

Image based navigation has an (understandably) bad name in the web industry but there are steps you can take to make it work. This post will result in this:

You can achieve some beautiful effects with image based navigation – just look at Matt Mullenweg’s website. There are pitfalls, however, often there’s a second or two of flickering where the rollover background loads which creates a disjointed experience. Also, whether, Like Matt, you want to create a hand-drawn aesthetic or you just want to use a non-standard font for your navigation (like Blue Door Baby or Bush Theatre) you still have to be sure that you’re making your navigation accessible. Just because a person can read your image, doesn’t mean that Google can, or a screen reader, or that it will be visible on a mobile device or if someone has CSS disabled. So how do we make sure that it’s pretty, doesn’t flicker and is accessible? Allow me to explain:

We shall start with generic navigation markup. It’s an unordered list, or <ul> because that’s the generally accepted markup for XHTML navigation nowdays.

<div id="Navigation">
  <ul>
    <li><a href="home">Home</a></li>
    <li><a href="about">About</a></li>
    <li><a href="site">Site</a></li>
    <li><a href="contact">Contact</a></li>
  </ul>
</div>

Obviously that wont be sufficient to convert to images so we’ll have to add a few more tags and some classes. For example:

<div id="Navigation">
  <ul>
    <li class="home"><a href="home"><span>Home</span></a></li>
    <li class="about"><a href="about"><span>About</span></a></li>
    <li class="site"><a href="site"><span>Site</span></a></li>
    <li class="contact"><a href="contact"><span>Contact</span></a></li>
  </ul>
</div>

I’ve added the class to the <li> tag so that we can assign the image individually to each list item. I’ve also added a <span> to each of the list items, but we’ll get to that later.

Here’s an image of the (seriously lacklustre) menu that I’m trying to create:

This is where we tackle the flickering problem. To do this we use CSS Sprites. The image we use will be just one image and it will contain both the plain and the hover states. So I created the hover states of my menu items by changing the colour and adding some hearts with brushes from Ego Box. And so my final image is as so:

So we can start styling our list. This is the first step:

#Navigation ul {
  list-style-type:none;
}
#Navigation ul li {
  float:left;
}
#Navigation ul li a {
  display:block;
  background:url(images/menubg.jpg) no-repeat 0 0;
  width:125px;
  height:60px;
}

I’ll go through what I did briefly. You probably wont need to read this if you know your CSS basics

  1. I set the list-style-type to none to remove the bullet points
  2. I made the list items float to the left so that they don’t stack on top of each other any more.
  3. I set the a tag to display block (so that it recognises the width and height)
  4. I made the background image out menu background image
  5. And I set the width and height.

Now I have something that looks like this:

So next we need to make each list item say the right thing. We do this by moving the background image a certain number of pixels to the left. Unless all of your menu images are the same size, this is a very manual process, I generally use the rulers in Photoshop to tell me how many pixels I need to move it by. I know that the “Home” image is 125px wide so I know what the CSS for the “About” image will be:

#Navigation ul li.about a {
  background-position:-125px 0;
}

All I’m doing is moving the background image 125 pixels to the left. Now when I do this for all of the images it looks something like this:

#Navigation ul li.about a {
  background-position:-125px 0;
  width:133px;
}
#Navigation ul li.site a {
  background-position:-258px 0;
  width:97px;
}
#Navigation ul li.contact a {
  background-position:-355px 0;
  width:145px;
}

I have also added the widths. I now have something that looks like this:

To get rid of the unsightly text all we have to do is set it to display:none like so:

#Navigation ul li a span {
  display:none;
}

“Why even add it then?” I hear you ask. Same reason we add alt to <img> tags: Accessibility. Yes, it is important.

Yay, now we have a pretty image based menu so the last thing to do is create the hover state. We do this by moving the background image up by the height of the menu, in  this case it’s 60px

#Navigation ul li a:hover {
  background-position:0px -60px;
}

That’s it! Now you have yourself an gaudy, unflickery, accessible image-based menu :)

The complete CSS:

#Navigation ul {
  list-style-type:none;
}
#Navigation ul li {
  float:left;
}
#Navigation ul li a {
  display:block;
  background:url(images/menubg.jpg) no-repeat 0 0;
  width:125px;
  height:60px;
}
#Navigation ul li a:hover {
  background-position:0px -60px;
}
#Navigation ul li.about a {
  background-position:-125px 0;
  width:133px;
}
#Navigation ul li.about a:hover {
  background-position:-125px -60px;
}
#Navigation ul li.site a {
  background-position:-258px 0;
  width:97px;
}
#Navigation ul li.site a:hover {
  background-position:-258px -60px;
}
#Navigation ul li.contact a {
  background-position:-355px 0;
  width:145px;
}
#Navigation ul li.contact a:hover {
  background-position:-355px -60px;
  width:145px;
}
#Navigation ul li a span {
  display:none;
}

Mar03 Tutorial: Centered layouts

This is a revamp of a tutorial I wrote years ago for my old blog (I think maybe 2006/7?)

This is the most effective way that I’ve found to center layouts. There are other ways, but this is the most simple. I’m going to assume that you have a basic knowledge of CSS, including selecting classes and IDs.

Firstly you need to create a container div and give it an id:
<div id="container">   </div>

This container will sit just inside the <body> tag and will contain all of your layout markup. For example:

<body>
  <div id="container">
    <p>this is your content!</p>
  </div>
</body>

Next, in your stylesheet you need to align your text to center. We’ll do this on the body tag.

body {
  text-align:center;
}

Next, select the ID that you created above. In this case it was id="container". Give that container a width (it can be any number):

#container {
  width:800px;
}

Not too different from what you’d normally do, the trick is adding the margin values:
#container {
  width:800px;
  margin:0px auto;
}

This is telling the browser to make the top and bottom margins on the div 0 and for the left and right margins, make them auto. The auto allows the browser to calculate the margins on the side for you so it doesn’t matter what size the window is. You can also change the 0px value to anything you want.

The final thing you might want to do is stop all of the text inside the div from being centered. This is easily fixed by added a text-align to the div style itself, like so:

#container {
  width:800px;
  margin:0px auto;
  text-align:left;
}

Hope it all makes sense! Please leave a comment if you have any questions :)