Adding watermarks to images with mini_magick error 256

April 8, 2009 – 10:56 am

I was attempting to watermark an uploaded image using attachment_fu for uploads and the mini_magick gem for processing. I received an odd little error that Google doesn’t seem to have many answers for. That error is Error 256. This is what I was doing:

after_attachment_saved do |image|
  if image.thumbnail.nil?
    img = MiniMagick::Image.from_file(image.full_filename(:large))
    img.combine_options do |c|
      c.gravity 'SouthWest'
      c.draw "image Over 0,0 0,0 "images/logo_watermark.png""
    end

    img.write(image.full_filename(:large))
  end
end

Looks sound, right? Should work, right? Well, oddly enough it didn’t and I received the error. I know others have used that exact method in the past and it’s worked fine for them, but for those of us that receive the ambiguous error I’ve got the answer.

Command line.

Mini_magick is a simple Ruby wrapper for ImageMagick anyway, so let’s just bypass it altogether and do it ourselves. The code above uses ImageMagick’s mogrify, but since we’ve got better control we should go ahead and use ImageMagick’s composite which gives us a better looking watermark on images. The original code turns into this:

after_attachment_saved do |image|
  if image.thumbnail.nil?
    img = image.full_filename(:large)
    system("composite -gravity SouthWest -watermark 10.0 -dissolve 75% 'images/logo_watermark.png' "#{img}" "#{img}"")
  end
end

There you have it.

UPDATE: The HTML “code” tag is parsing the escaped quotes. Make sure you escape the quotes around “#{img}” so they turn into \”#{img}\”

Embed your free online portfolio from SHOWN’D

January 5, 2009 – 3:07 pm

I just finished adding a feature on SHOWN’D that allows you to embed your showcase directly to an external site. It can be your blog, personal page, business page, or anything that you can place a simple script into. The script is automatically generated for you whenever you update your portfolio, and you can even play around with the style settings. You don’t need to change scripts after generating a new one, it simply keeps updating itself on your site as you update your portfolio on SHOWN’D. Below is my embedded showcase:

Pretty neat, huh? It’s in the early stages so there may be a couple of bugs here and there. What I would like is for many people to use it so I can fine tune it to different setups. The plan is to allow paid users to have more options in modifying the style and also the option to remove the SHOWN’D logo. I’m thinking letting them directly access the CSS would be a good way to give them the versatility they may want.

Ruby snippet: Return a different string if empty or if replacing

December 24, 2008 – 12:53 am

In my latest Rails project I needed a quick way to return a string if that string happened to be blank, and also a way to return a different string if the existing string is set. Here’s the solution I came up with which I placed in extras.rb in my lib directory (require ‘extras’ in environment):

def otherwise(alternate, existing = nil)
    self == existing ? alternate : self
end

I’m using it like so in my project:

<!-- If it's blank -->
<%= image_tag(image.general_filename('large'), :class => "full", :alt => (h image.description.otherwise(image.project.title))) %>

<!-- If it has a string you would like to replace -->
<%= image_tag(image.general_filename('large'), :class => "full", :alt => (h image.description.otherwise(image.project.title, "No description"))) %>

Image-based menu with CSS color property

December 10, 2008 – 1:11 pm

I’ve been covering the image-based CSS menu now quite a bit, this being my third article of the sort. Menus are very important, and there’s so much that can be done with them that I figure I’d write an article on different variations to what is essentially the same menu. This article will cover something which I consider to be extremely useful to designers who wish to make dynamically-colored menus using images rather than text.

For example, let’s say you have your standard menu with 4 links: Home, Locations, About, Contact. Maybe you want to color each link differently, one red, one blue, one green, one orange. The hover state for all of them will be… let’s say white. You can go ahead and make 4 images (home red, locations blue, about green, contact orange) and then 4 additional hover state images bringing your total to 8. Fair enough, it’s not really a tough task to undertake, though I can help you cut that time in half.

You show your client the menu and he loves it. You continue working on the rest of the site and a few days later the client frantically calls you and says, “we need to change the the menu IMMEDIATELY! Our competitor’s menu has the same colors, plus our logo designer decided to use different colors and we want them to match!”

This kind of thing happens all the time, and if you’re using images instead of browser-rendered text it can start taking up more and more time to recreate those images again.

Another example is a menu for a site that lets users choose a theme, or perhaps a seasonal change to the site’s colors. Rather than making images for each of the themes, use this method.

All right, enough anecdotes, let’s get right to it. Most of this markup and CSS is from the first article in the series which means you can just refer to that if you need in-depth explanations of what’s going on.

The markup:

<ul id="menu">
	<li id="selected" class="home"><a href="#">Home</a></li>
	<li class="locations"><a href="#">Locations</a></li>
	<li class="about"><a href="#">About Us</a></li>
	<li class="contact"><a href="#">Contact Us</a></li>
</ul>

Again, very short and sweet. The CSS is, for the most part, the same as the original with a slight variation which I’ll get to:

html {margin: 0; padding: 0;}
body {
	margin: 0;
	font-family: Arial;
	background-color: white;
	font-size: .75em;
	color: #333;
}
a:link {color: white; text-decoration: none; font-weight: bold;}
a:hover {color: #87acee;}

ul#menu {
	list-style: none;
	margin: 0;
	padding: 10px;
	height: 25px;
	background: #303136;
}
ul#menu li {
	float: left;
	display: inline;
	height: 25px;
	margin: 0 10px;

}
ul#menu li a {
	display: block;
	height: 25px;
	text-indent: -999em;
}

.home a {background:white url(images/menu_home.png) 0 0 no-repeat; width: 67px;}
.locations a {background: red url(images/menu_locations.png) 0 0 no-repeat; width: 119px;}
.about a {background: orange url(images/menu_about.png) 0 0 no-repeat; width: 115px;}
.contact a {background: green url(images/menu_contact.png) 0 0 no-repeat; width: 136px;}

.home a:hover, ul#menu li.locations a:hover,
.about a:hover, ul#menu li.contact a:hover {background-color: white;}

As you can see it’s pretty much the same. The differences lie within the background color of the list item element in question. What we’re doing here is creating an image of the text with an alpha transparency.

This is what it would look like in Photoshop:

You don’t need a hover state image since that will be controlled strictly through the CSS. What you need is the transparent image. If you don’t know how to make it, I’ll quickly show you how in Photoshop.

Making the images

Step 1: Create a new layer (above the Background Layer) and give it the background color you’d like. I used #303136 for mine.
Step 2: Switch to the background layer and either make it transparent or hide its layer visibility. The point is you cannot have a locked layer at the base.
Step 3: Use the Type Tool and type out your menu word. Use a color that contrasts your background. I used #ffffff (white) for mine.
Step 4: Rasterize the layer (right click the layer in the layers panel, click rasterize type) and open up the layer’s blending options by right clicking the layer in the panel and then clicking “Blending Options…”
Step 5: In the advanced blending section of blending options, move the Fill Opacity slider to 0 and set the knockout to “shallow.”

That’s that. Crop it up to taste and save your file for web as PNG-24 (that’s important.) You can create the other menu item files in the same method.

Now when you want to change menu colors, you can do so in the CSS simply by changing the background-color, leaving the image intact, as such:

.your_item a {background: #56FD34 url(images/your_image.png) 0 0 no-repeat;}
.your_item a:hover {background-color: #9D14AB;}

What about IE6?

As you might have noticed, IE6 doesn’t play nice with this on account of using alpha-transparent PNGs to achieve the anti-aliased text effect. In order to fix this while maintaining valid CSS you’ll need to use ActiveX but do so in an IE6-specific stylesheet using conditionals. Here is the CSS you’ll put in your IE6 stylesheet:

ul#menu li a {position: relative;} /*Fix IE6 link bug on PNGs*/
.home a {
	background-image: none;
	filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, src=images/menu_home.png, sizingMethod=image);
	cursor: pointer;
}
.locations a {
	background-image: none;
	filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, src=images/menu_locations.png, sizingMethod=image);
	cursor: pointer;
}
.about a {
	background-image: none;
	filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, src=images/menu_about.png, sizingMethod=image);
	cursor: pointer;
}
.contact a {
	background-image: none;
	filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, src=images/menu_contact.png, sizingMethod=image);
	cursor: pointer;
}

We’re knocking out the background image on IE6 and replacing it with a Microsoft proprietary ActiveX filter. If you placed this in your IE stylesheet, you’ll need to tell the XHTML file to load it for IE6 only. Place the following inside your document’s <head> tags and replaced ie_styles.css with your stylesheet:

<!--[if lt IE 7]><link href="ie_styles.css" media="screen" rel="stylesheet" type="text/css" /><![endif]-->

View the complete menu

This kind of technique is something you can get used to putting together on all your image-based menus to make life much easier on you. I was very thorough in this tutorial, so while it may seem like a lot to do, it’s actually the kind of thing you can get done in mere minutes.

Adding a drop down to our image-based CSS menu

December 8, 2008 – 7:40 pm

Drop down menus are all the rage!

CSS drop down menus have been done before, so rather than reinvent the wheel, let’s use a tried-and-true CSS drop down menu method by Patrick Griffiths and Dan Webb aptly named the “Suckerfish Dropdown.” You can read more about it at A List Apart, a site with oodles and even-more-oodley-oodles of web design articles.

What we’re going to be doing is integrating my previous image-based CSS menu with the Suckerfish drop down. It’s pretty easy. As always, first, the markup:

<ul id="menu">
		<li id="selected" class="home"><a href="#">Home</a></li>
		<li class="locations"><a href="#">Locations</a>
			<ul>
				<li><a href="#">Americas</a></li>
				<li><a href="#">Asia</a></li>
				<li><a href="#">Europe</a></li>
				<li><a href="#">Africa</a></li>
				<li><a href="#">Oceania</a></li>
			</ul>
		</li>
		<li class="about"><a href="#">About Us</a>
			<ul>
				<li><a href="#">Company Profile</a></li>
				<li><a href="#">Investors</a></li>
			</ul>
		</li>
		<li class="contact"><a href="#">Contact Us</a>
			<ul>
				<li><a href="#">Online</a></li>
				<li><a href="#">Phone</a></li>
			</ul>
		</li>
	</ul>

As you can see, the markup is identical to the image-based menu markup with the addition of a nested unordered list. That nested unordered list will be our drop down. It’s neater, more semantically relevant, and shorter than any Javascript solution you can think of, that’s for sure! Next up, the CSS:

html {margin: 0; padding: 0;}
body {
	margin: 0;
	font-family: Arial;
	background-color: white;
	font-size: .75em;
	color: #333;
}
a:link {color: white; text-decoration: none; font-weight: bold;}
a:hover {color: #87acee;}

ul#menu {
	list-style: none;
	margin: 0;
	padding: 10px;
	height: 25px;
	background: #303136;
}
ul#menu li {
	float: left;
	display: inline;
	height: 25px;
	margin: 0 10px;

}
ul#menu li a {
	display: block;
	height: 25px;
	text-indent: -999em;
}

.home a {background: url(images/menu_home.png) 0 0 no-repeat; width: 67px;}
.locations a {background: url(images/menu_locations.png) 0 0 no-repeat; width: 119px;}
.about a {background: url(images/menu_about.png) 0 0 no-repeat; width: 115px;}
.contact a {background: url(images/menu_contact.png) 0 0 no-repeat; width: 136px;}
.home a:hover, ul#menu li.locations a:hover,
.about a:hover, ul#menu li.contact a:hover {background-position: bottom left;}

ul#menu li#selected a {background-position: bottom left;}

/*Drop downs*/

ul#menu li ul li a {
	background-image: none;
	text-indent: 0;
	padding: 0 0 0 25px;
	height: auto;
	width: auto;
}
ul#menu li ul li {
	float: none;
	height: auto;
	display: block;
	margin: 0 0 10px 0;
}
ul#menu li ul li a:hover {
	background: url(images/pointer.png) 0 center no-repeat;
}

ul#menu li ul {
	display: none;
	position: absolute;
	top: 1em;
	width: 179px;
	padding: 15px 10px 0 10px;
	background: url(images/dropdown.png) left bottom no-repeat;
	left: 0;
	margin: 0;
}

ul#menu li>ul {
	top: auto;
	left: auto;
}

ul#menu li:hover ul, ul#menu li.over ul {
	display: block;
	left: auto;
}
*:first-child+html ul#menu li:hover ul,
*:first-child+html ul#menu li.over ul {
	position: static;
}

Let’s start breaking that down a little. Everything above the /*Drop downs*/ comment is from this previous article, so read that one if you’d like an explanation of what’s going on there.

The first snippet we’ll take a look at is the following:

ul#menu li ul li a {
	background-image: none;
	text-indent: 0;
	padding: 0 0 0 25px;
	height: auto;
	width: auto;
}
ul#menu li ul li {
	float: none;
	height: auto;
	display: block;
	margin: 0 0 10px 0;
}
ul#menu li ul li a:hover {
	background: url(images/pointer.png) 0 center no-repeat;
}

What we’re doing here is resetting the properties set previously for the top-order unordered list. We’re wiping the background-image on the anchor which was used for the menu item image, resetting the text’s indent that took care of hiding plain text from the viewer, and resetting the height and width properties. Next, for the list item itself we’re removing the float property we previously used to simulate an inline list, resetting the height property, and adding some margins to the bottom just to space things out a bit.

Also, we’re adding in a little arrow pointing to the link you’re hovering. I guess I did that just because we can.

Next up is the drop down box itself:

ul#menu li ul {
	display: none;
	position: absolute;
	top: 1em;
	width: 179px;
	padding: 15px 10px 0 10px;
	background: url(images/dropdown.png) left bottom no-repeat;
	left: 0;
	margin: 0;
}

ul#menu li>ul {
	top: auto;
	left: auto;
}

This is where Suckerfish really comes in. What’s happening here is the drop down box is being hidden via display: none; and reset to an absolute position right below its list parent. The rounded corner is a simple background:

Just place it on that nested unordered list attached to the BOTTOM of the element and it’ll resize itself accordingly, provided the drop down itself isn’t taller than the image (in which case you can make the image larger yourself), keeping the rounded corners at the bottom of the drop down.

To bring up the drop down menu when a user hovers over the menu item, that’s where the rest comes in:

ul#menu li:hover ul, ul#menu li.over ul {
	display: block;
	left: auto;
}
*:first-child+html ul#menu li:hover ul,
*:first-child+html ul#menu li.over ul {
	position: static;
}

The reason for the “ul#menu li.over ul” is simple: IE6 doesn’t play nice with pseudo-classes. :hover will only work on anchors and nothing more. To remedy that, use the following snippet of Javascript for IE6:

startList = function() {
	if (document.all&&document.getElementById) {
		navRoot = document.getElementById("menu");
		for (i=0; i<navRoot.childNodes.length; i++) {
			node = navRoot.childNodes[i];
			if (node.nodeName=="LI") {
				node.onmouseover=function() {
					this.className+=" over";
				}
				node.onmouseout=function() {
					this.className=this.className.replace(" over", "");
				}
			}
		}
	}
}
window.onload=startList;

This will add the “over” class to LI nodes within the “menu” ul, and remove them on mouse outs. While other compliant browsers will just simply use the li:hover method, IE6 will instead attach the “over” class which has the CSS property of the li:hover method, in effect giving it the same outcome.

View the drop down menu

That’s all it takes.
UPDATE: Thanks John for pointing out the IE error. I’ve fixed it in the post, but the changes made were adding “left: auto;” to “ul#menu li:hover ul, ul#menu li.over ul {}” to set the position on hover, and also “margin: 0;” to “ul#menu li ul {}” to reset the margins on IE.

How to create a fixed overlay footer with CSS

November 23, 2008 – 8:36 pm

I’ve seen various techniques on how to create footers sticking to the bottom of the screen which will expand downward if there’s enough content, but will remain stuck on the bottom of the screen if there isn’t. That’s useful for many sites, however if you want it to overlay above the rest of your content and remain fixed at the bottom of your screen even if there’s enough content to push it downward you’ll need another solution.

The CSS

html {margin: 0; padding: 0;}
body {
	margin: 0;
	padding: 0;
	font-family: Arial;
	background: white;
	font-size: .75em;
	color: #333;
}

#container {
	height: 1500px;
	overflow: hidden;
	margin: 0 auto;
	padding: 0 10px;
}

#footer {
	width: 100%;
	background: #ccc;
	position: fixed;
	z-index: 1;
	bottom: 0;
	padding: 10px;
}

It’s easier than you might think, really. This works in Firefox, Safari, Opera, and IE7.

The Problem

As you might have guessed, this doesn’t work well with IE6. I’ve found that the easiest method to make it work, without having to go into quirk mode, is to use CSS expressions.

And a collective groan fills the air.

Yes, I know, I feel the same way about them, but in this case it works. We can put it in a CSS conditional statement so only IE6 reads and executes it. We can do it like this:

* html #footer {
	position: absolute;
	top:expression(eval(document.compatMode &&
		document.compatMode=='CSS1Compat') ?
		documentElement.scrollTop
		+(documentElement.clientHeight-this.clientHeight)
		: document.body.scrollTop
		+(document.body.clientHeight-this.clientHeight));
}

You can view the example to see the footer in action.

This works and solves the problem. We’re not done yet, though. If you want your page to validate, which you probably should, you’ll need to take that out of your stylesheet and place it in an IE6-specific stylesheet to avoid 2 errors. In order to do so, create a separate stylesheet and call it ie6_styles.css, or whatever you want. Then, after linking your base sheet, add this to your markup:

<!--[if lt IE 7]>
<link href="/stylesheets/ie6_styles.css" media="screen" rel="Stylesheet" type="text/css" />
<![endif]-->

That statement is saying “If the IE version is below 7, process the markup enclosed within these tags”, which means it it loads the ie6_styles.css stylesheet. Validation parsers such as the W3C CSS Validator don’t read through conditional statements so everything will validate nicely.

IE unordered list extra space bug

November 23, 2008 – 4:51 am

I was working on converting a client’s design into XHTML/CSS when I encountered something I SHOULD have faced long ago, but never did on account of my recent change in CSS practice. Since early this week, I’ve been starting new projects with a reset stylesheet to make my life a little easier and manage my time more efficiently. Anyway, onto the problem.
 

The problem

After completing the site, I checked in IE6 only to realize all my unordered [block] list menus had some odd extra space to the left. In other words, they had phantom indentations. The padding, margin, and indents were reset to 0, so I couldn’t figure out what the problem was. The list-style was also set to none. Googling produced a lot of people having the same issue, but no actual solutions in about 15 minutes of browsing. Stripped down and showing only relevant bits, this is the CSS I had in place:

* {margin: 0; padding: 0;}
ul, ol, li {list-style: none;}

The markup was straightforward:

<ul id="whoCares">
	<li><a href="#">A link</a></li>
	<li><a href="#">A link</a></li>
	<li><a href="#">A link</a></li>
</ul>

The solution

Utterly, painfully simple.

ul, ol, li {list-style-position: outside; list-style: none;}

 

That damn list-style-position. It almost makes you want to punch yourself.

SHOWN’D - Showcase your stuff.

November 21, 2008 – 12:12 am

So the latest project I’ve been working on is finally ready for prime time. SHOWN’D is a resource for creative professionals. It allows them to set up an online portfolio and connect with employers.

SHOWN'D

I like how it turned out in the design department, and early users seem to be reporting pretty pleasant experiences with the usability of it. I put a lot of focus on the interface, so I’m glad to hear that. I’m still hot fixing and adding things here and there, but the app is deployed and ready for use. The front page is something I’ve been going back-and-forth on this past week. The way I want to have it (which is how it looks while logged in, sans the intro header) I will probably add when we get some employers posting jobs since right now it’s a bit empty and doesn’t give it the right look.

Anyway, just wanted to post this update. This probably also explains my lack of posts lately. I’d like to keep adding some more CSS tips, so hopefully I can get back to that soon.

Quick tip to fight email form spam

August 16, 2008 – 3:54 am

I discovered this a couple of days ago, but the simplicity and “oh wow, I should’ve thought of this years ago”-ness of it makes me believe I’m not the first to think of this.

A few months ago I began receiving spam from the form over at my XHTML slicing site at http://designerschopshop.com . The form itself is actually a slightly modified version of Dustin Diaz’s AJAX contact form, but for this tip you can use any form at your disposal. Lately though, I’ve been receiving 6-8 spam messages per diem. That’s just unacceptable. Wait, I take that back, ALL spam is unacceptable. Especially that super annoying kind that seems to be along the lines of:

Oedipus conflagration is among pacifists with trepidation annihilating mesomorphs http://cheappillsforyourdick.ru/pills/cialis “Hear ye!” behooves cornerstones of Tbilisi yearning for exhilaration http://hotbabes.anddickpills.com/buy/12387/pills dignified constitution

Ugh. Those emails make me want to have a sex-change operation so I can hit on a raging homophobic bodybuilder that’ll beat my ass after I tell him my truthful gender, just so the pain will be great enough to hopefully make me forget about the bastards that send that type of spam. It’s that intense.

Anyway, back to the topic at hand.

I didn’t want to go the Captcha route and wanted to keep it simple. What I did is create two input boxes for email. I gave one the id and name attribute of “email”, and the other “emailFalse”. I placed “emailFalse” before email, but I did this:

<label style="display: none;" for="emailFalse">E-mail address: (required)</label>
<input id="emailFalse" class="text" style="display: none;" name="emailFalse" size="25" type="text" />

<label for="email">E-mail address: (required)</label>
<input id="email" class="text" name="email" size="25" type="text" />

Then, in my validation Javascript (and in the PHP, just in case), I added something along the lines of this:

...
else if ( emailFalse.value != "" ) {
		alert("Not gonna work this time, bud.");
	}
...

In other words, you create an extra text box with an id/name attribute that contains “email” (I’m under the assumption that spammers in this case use a regular expression to know which field is which), hide it from normal users via a quick “display: none;”, and add a validation check that looks to see whether or not that field has been filled out. If the field isn’t left blank, it’s spam, so don’t send it. I’ve gone from 6-8 spam emails every single day to 0 in the last 4 days. Obviously, the only thing that keeps this solution working is spammers not knowing about it (yet) and coding around it (so far.) Even so, right now it’s working brilliantly, and that makes me happy.

Neat, eh?

Creating an image-based menu with CSS

July 10, 2008 – 12:36 pm

The year is 2008 and I come upon a new site on a daily basis using the Javascript method of creating an image-based menu with rollover effects. I’m not talking flashy rollover effects like the types given to you by various JS libraries such as MooTools and script.aculo.us, I’m talking a simple image replacement effect. Invoking JS for this sort of thing is bulky and unnecessary when it can be done oh-so-easily with some straightforward CSS.

One highly used method, which I’ll cover another time, allows you to place browser-rendered text in that menu. That’s useful for many reasons, but sometimes you don’t WANT browser-rendered text because you’d like to use a non-web standard font but wish to maintain the text in place for screen readers and SEO. In this case we want to create a menu using the “Cooper Std” font. So let’s get started.

First, the markup:

<ul id="menu">
	<li class="home"><a href="#">Home</a></li>
	<li class="locations"><a href="#">Locations</a></li>
	<li class="about"><a href="#">About Us</a></li>
	<li class="contact"><a href="#">Contact Us</a></li>
</ul>

That’s all. It’s very short and semantically relevant.

For this sort of method it’s best to create your images as sprites (or one big sprite, up to you.) What I mean by that is to take the image for the normal state and the image for the hover state and place them on one image, like so:

Menu image sprite

Then rather than calling a different image for the hover action, you just call the same image with an altered background position. You’ll see what I mean in the code. This helps stop the flicker you would get when the browser tries loading the new image when hovering, and it also lowers the amount of requests made to the web server. It would be even better to place all of the images into one big sprite map, but for the sake of this tutorial we’ll just create one sprite per menu item.

This, without styling, will produce the following results, so anyone in a text browser will still be able to see your links. So let’s start adding some styles.

body {
	margin: 0;
	padding: 10px;
	font-family: Arial;
	background-color: #303136;
	font-size: .75em;
	color: #333;
}
ul#menu {
	list-style: none;
	margin: 0;
	padding: 0;
	height: 25px;
	width: 520px;
}
ul#menu li {
	float: left;
	display: inline;
	height: 25px;
	margin: 0 10px;
}

This will give your menu a bit more structure. What you’re doing here is creating the menu as an unordered list with static height/width dimensions. With text-based menus you generally want to stay away from hard-coded height properties to account for users who wish to increase or decrease their font sizes and not allow that to break your design, but in this case that’s not necessary since these are images.

We’re floating the list items to the left to create a “seemingly inline” list out of what are block elements. The “display: inline” property is there as a fix for IE6 adding a random margin.

Next thing we want to do is add the images to each class along with their corresponding width properties:

ul#menu li.home a {
	background: url(images/menu_home.png) 0 0 no-repeat;
	width: 67px;
}
ul#menu li.locations a {
	background: url(images/menu_locations.png) 0 0 no-repeat;
	width: 119px;
}
ul#menu li.about a {
	background: url(images/menu_about.png) 0 0 no-repeat;
	width: 115px;
}
ul#menu li.contact a {
	background: url(images/menu_contact.png) 0 0 no-repeat;
	width: 136px;
}

Note the background position, “0 0″, which is the same as “left top.” This will show the image in its normal state. However, we’ve got a little problem here. The browser-rendered text is showing up, and the menu image only spans as high and wide as the text itself. We can fix that pretty easily with the following snippet:

ul#menu li a {
	display: block;
	height: 25px;
	text-indent: -999em;
}

Setting the inline anchor element to a block element allows us to specify its height and width explicitly. The text-indent will move the text completely out of view. Google frowns upon using “black hat” tactics such as hidden text for SEO purposes, but when you’re doing this to a few words in a menu in which the images you’re replacing the words with say the same thing, I’ve never heard of them having a problem with that. It’s when you start hiding paragraphs of key words out of view that Google decides you’re no good.

The only thing left to do is the hover state. This will do the trick:

ul#menu li.home a:hover, ul#menu li.locations a:hover,
ul#menu li.about a:hover, ul#menu li.contact a:hover {
	background-position: bottom left;
}

See that? All you’re doing is moving the background’s position to the bottom left rather than the top left. It’s the same image, but it gives the illusion of loading a new one. No flicker.

View the menu

Final touches

If you’re using Firefox, when clicking a menu item you’ll see an ugly dotted line border around the element going all the way to the left edge of the screen. This is something the browser adds itself. There’s a way to get rid of it though, just add a hidden overflow property:

ul#menu li {
	float: left;
	display: inline;
	height: 25px;
	margin: 0 10px;
	overflow: hidden;
}

Also, if you want to specify a selected state for a menu item, just add an ID attribute called “selected” and add this CSS:

ul#menu li#selected a {background-position: bottom left;}

View the final menu with selected item