I have some 'internal rules' about writing code that could help with this.
1) if you have a cascade off a parent element, you rarely if ever should need to put the same class on more than one element. This means ALL of the child classes except 'current' are unnecessary. No need to get "class-happy"
2) NEVER try to do sliding doors with LI as one half of the image - it's more trouble than it's worth. This might mean you need an empty sandbag span or bold tag - oh well.
3) If you want to override a parent's psuedo-states for 'current', put that 'current' class on that parent element and not it's children - cleans up your specificity.
4) If you are going to use sliding doors, there's rarely a good reason to have more than one image... Handshakes for multiple files takes time regardless of how fast the connection - real world in most cases anywhere from 60ms to 400ms, though a full second apiece is not uncommon. Less images == less handshakes, so lets see if we can use one image to build the ENTIRE menu! While at it, let's try and keep that one image under 2k in size.
5) Never use %/em fonts on a image interaction unless you plan on at LEAST 50% extra image padding. It will break your layout HORRIBLY on large font/120dpi systems without lots of extra planning.
6) Never specify padding/border the same time as width/height.
7) Margins are more headache than they are worth once floats are involved - so don't use them! For show/hide on the menu this means absolute positioning instead of margin chicanery.
8) LI in most cases are a pain in the ass - so when not using them as parent elements for positioning, do yourself a favor, set them to display:inline and pretend they don't exist.
9) Float:none will often not take if you have your specificity wrong, so be sure the child cascade to set none is correct. If the float is on #mainMenu li, make sure you use #mainMenu li li to override back to none. #mainMenu ul li can often end up ignored by legacy IE. "#mm li a" to override use "#mm li li a".
10) NEVER trust the default or named line-heights. The specification does not say what the default line-height actually should be apart from a loose recommendation of 110% to 130%. You've got a image behind that thar text, get a fixed line-height on it.
So, lets put that together. NORMALLY I'd say get rid of the DIV around #mainMenu, but since the only practical float wrapping behavior for a menu of floats is width:100%; float:left; - we'll go ahead and keep the DIV. Strip off ALL the other classes except "current", which we'll move off the anchor and onto the LI wrapping it. We then add empty spans into our top level anchors. You could wrap the text in the spans, but that makes doing transparency a pain in the ass so we'll just use them as sandbags.
Which resulted in this:
I based that almost entirely off your one little screencap, but tossed on some of my own hover states, current state, etc, etc.
As with all my examples, the directory:
... is unlocked so you can grab the gooey bits. Valid XHTML 1.0 Strict, would be valid CSS 2.1 if not for the IE specific 'behavior' property (big deal), tested working IE 5.5, 6, 7 & 8, Firefox 2 and 3.6, Opera 9.63 and 10.52, and the latest flavors of Safari and Chrome.
Let's take a look at the CSS file:
First I always start out with a reset so we know things are at a nice stable baseline across all browsers. There are bigger/fatter/bloated resets - I've never needed more... There are smaller resets, they tend to screw up form elements - this is a nice happy medium.
I set a background-color on body just so I could see what's going on, and for scripting assist I used peterNed's 'hover anywhere' - aka csshover3.htc. It's a nice, easy predictable way to implement them, and the file isn't as grossly oversized as some of the other implementations out there. The only problem is a handful of servers might be total retards and not serve it with the right mime-type - you encounter that, don't ***** about the .htc and dive for some other solution; fix the damned server.
mainMenu - Float:left; width:100%; on the outer div to make it wrap floats, and we'll put that top padding on it here. I also like to set the font-size/line-height as soon as possible - and I do so in px thanks to the image interaction and using the condensed property. Since the full separate lines of "font-size" and "line-height" ends up almost as long as a full condensed font line, I bite the bullet and just use the whole thing.
Since that makes all our measurements a nice fixed px, we can then apply part of our mainMenu.png as the repeat-x.
*** NOTE *** The mainMenu.png I use uses PALETTE transparency, not alpha. Palette transparency in .png works just fine all the way back to IE 4.0... ONLY alpha transparency .png have issues. I combine this with a technique called "close enough anti-aliasing" so it doesn't have jagged corners, but you don't have to sweat matching the background up as much. I also use tweakpng.exe to strip the GAMA line so there are no color matching issues in IE either. This all combines into a smaller file than it could ever be as .gif - really there is no difference between 8 bit .png with palette transparency and a normal 8 bit .gif from a functionality standpoint once you strip out that GAMA data field - except .png is usually a smaller file. At 1.5k I'm willing to bet that's smaller than the seven .gif files you'd need to pull off the same effect as separate images; and we have none of those 'first hover not cached' headaches to deal with either.
mainMenu il - We add the list-style:none and the side padding. Putting the top padding on the wrapping div makes it work all the way back to IE 5.x
mainMenu li - I set these to position:relative so the nested UL's can be positioned off them. Floating them left makes them behave across all browsers when it comes to positioning info, and I pad them on the right side to make room for the span sandbag without resorting to margins on the anchor.
mainMenu li a - we declare this as "li a" so our later specificity can override it. (just "#mainMenu a" is hard to override without !important). I also float these left instead of just setting them to block due to a positioning bug that can rear it's ugly head in IE7 or IE8's compatibility mode. You'll notice the padding is uneven - the shorter right padding is because we have the padding on the LI. It too is position:relative so we can position the nested span off the anchor. You COULD try to position it off the parent LI instead, but again IE can throw a wobbly over that. Stripping the underscore and setting the color is nothing fancy, but we apply the same background image as we did #mainMenu and just slide it's background around. You'll notice I don't declare heights on the UL, LI or A - I let the line-height and padding do all my work for me to get that 18px your demo image had. 3px top padding + 1px bottom padding + 14px line-height. Poof!
mainMenu li a span - here's our sandbag. Absolute position it.. I made 6px of room for it, and I position it right:-6px - but I make it 8px wide. Zooming in and out Firefox can be a real dip sometimes, so a bit of overlap compensates for gecko's being a bit... #DDD. This gets that same background image again, this time slid over -248px to show the right 8px of our button off state.
mainMenu .current a - for the current button I added some color and styling. Apart from that all I had to do is slide the background up to -64px to reveal the 'current' image state.
mainMenu .current a span - much like it's parent, all this needs is the background slid up -64px.
mainMenu li ul - This gets absolute positioning applied. left:-999em is pretty much guaranteed to slide the menu so far off the left side of the screen you'll never have to worry about it, and it won't screw up screen readers like display:none can. I also set display:inline on it here because IE 6 & 7 can often 'stick' leaving the menu open when you de-hover for god knows what reason (redraw error?). Changing the display state on hover seems to fix that.
I strip padding off it since we'll handle that on our anchors, and from there it's just background-color and a border to style it up a bit. You can probably figure out how to apply more styling from there.
mainMenu li:hover ul - left:1px slides it into view nice and pretty, and of course our display state change to make IE behave.
mainMenu li:hover a - These get a different background position (0 -46px) to show our hover state part of the image.
mainMenu li:hover a span - ditto ditto.
mainMenu li li - turn off floating and padding we had for their parents, then set display:inline. IE7 can REALLY flake out about styling LI, and IE6 is no winner either often throwing in extra padding between them. Setting them to display:inline removes all those problems...
mainMenu .current li a - I set the parent "li.current a" to bold just to make it stand out more, here we undo that.
mainMenu li li a - Again remove the floats and set them to display:block so they appear one atop the other. Even out the padding a bit, strip off the background image, and setting white-space to nowrap seems to fix some left-over oddities that crop up when you undo a float state.
mainMenu li li a:hover - Just a bit of background color for hovering.
.... and we're done.
Not too complex... Hopefully you were able to follow along with my breakdown/reasoning/choices and come away with something useful from it.
Hope this helps.
-- edit -- and wow, those colors remind me of demonoid.com