10/08/03

Comments 13

Image rollovers with CSS

Here's how a plain text link can be converted into a pure image rollover using only CSS. You can see the result on the site's logo.

If you're not already familiar with 'Fahrner Image Replacement', read Doug Bowman's article on Using Background-Image to Replace Text. This presented a guilt-free way of using images for titles, although it relied on a superfluous <span> tag to hide the actual text. Not really a concern unless you were an absolute XHTML purist. The bigger problem was with JAWS screen readers, that treated text styled with 'display:none' as invisible and skips it.

The Gilder-Pixy Method

The following combines 2 techniques - Tom Gilders text-transform and Pixy's no-preload rollovers. The former uses 'text-indent: -10000em;' to hide the text from view, while the latter changes the position of the background image, rather than loading a seperate image. This means that you have to create an image containing both states, like this. These methods avoid the need to use the Box Model hack, display:none or some convoluted route to preload the rollover state. Its small code, and the rollover is faster. Combining the 2 methods also allows you to use pure images, rather than the text link/background combination (such as A List Apart)

Here's the code that went into the HTML:

<div id="logo">
<a href="/index.php" title="click to go back home">// hicksdesign</a>
</div>

No presentational markup, its just a plain ol' text link. Here's the CSS to go with it:

#logo a {
	text-indent: -1000em;
	background: url(images/logo.png) no-repeat left top;
	width: 64px;
	height: 369px;
	display: block;
	overflow: hidden; /* For nested divs in Safari */
	}

/*  IE 5 hack \*/
#logo a {overflow: hidden;}
/* end hack */ 
	
#logo a:hover {
	background-position: -64px 0px;
}	

There are 2 changes to the original code. The addition of the display: block, as the <a> tag will be treated as an inline element rather than a block and nothing will show up. Also, if the rollover is placed inside an absolutely-positioned nested div, Safari throws up a huge horizontal scroll bar (presumably 1000em wide). The overflow:hidden stops this, but needs to be hidden from IE 5 Mac or else the image won't visible.

Pros and Cons

This method allows you to create image based rollovers, without any need for javascript. Not that javascript is evil, but there are several advantages to using this method:

  • Substantially less code.
  • Works in IE 5-6 Win/Mac, Opera 7, Mozilla/Firebird/Camino and Safari.
  • Users without CSS, or those using a different stylesheet will see the just plain text link.
  • Search engines place little importance on <alt> tags, but plain text links are good. I've been told that text styled with display:none doesn't count either, but I can't confirm this.
  • Javascript rollovers need an 'onMouseOver' and 'onMouseOut' event adding to the <a> tag. Accessibility validators pick up on this and request that you supply an alternative with <noscript>. A bit of a faff quite frankly.
The only disadvantages are:
  • If the user has CSS on, but images turned off to improve browsing speed, they'll see nothing. Ooops! Tom has a solution for this which requires an extra span tag.
  • One other problem is a bug in Safari, where if you place the rollover in an absolutely positioned DIV the image doesn't revert back when rolling out. Fortunately, I was able to position the logo DIV with margins instead (and decrease the amount of code needed in the process! Sweet!)

Thanks to Tom Gilder and Pixy for creating these methods!

Further Reading:

Dave Shea has written an article on Fahrner Replacement for Digital Web Magazine.

Technorati TagsTags: ,

Comments | RSS

Comments are now closed, but you can still have a jolly time reading what others have left:

#1

Jeff Croft said 1943 days ago:

Great article!

While the cons are noteworthty, I don't think they should stop anyone from using this method.

Con #1: The percentage of folks who have CSS on and images off is VERY small. It's got to be damn near zero. These people are probably used to getting confused layouts, since many CSS designers rely on images, as well.

Con #2: The Tantek hack isn't much of a problem, IMHO. Worth noting, but not really a "problem," per se.

Con #3: This is obviously a bug in Safari, and one I would imagine David Hyat will get around to fixing soon (he's usually pretty quick about these things). I wouldn't hesitate to use this method because of the Safari nug -- Safari users are still a pretty small percentage, and I think we can count on it being fixed in short order.
#2

Sam Newman said 1935 days ago:

Nice article Jon, thanks. On minor gripe (this actually applies to the site as a whole) is that on Firebird part of the left of the screen gets chopped off - I can send a screenshot if required. I'm fairly sure this issue will be present on all gecko based browsers. Anyway, guess I'll have to read your site using IE for now :-)
#3

Jeremy Fuksa said 1920 days ago:

I'm getting this to work... sort of. What if I have three image rollovers I want to site nicely next to eachother?

I created a separate ID for each rollover I wanted, but when I implement it, all the images stack vertically instead of horizontally. What other parameters can I set to make this stop happening?
#4

Jon Hicks said 1920 days ago:

Jeremy,

This is because your needing to use 'display:block' - its forcing a carriage return after each element. You could try using 'float:left' on the first 2 divs. Another option would be to use absolute positioning to make each one sit where it should. Let me know if that doesn't help...
#5

caiuschen said 1906 days ago:

Great article. As for the left part of your site being cut off; I do not have that problem. I'm using a Firebird nightly, though: 20030903.
#6

Jon Hicks said 1906 days ago:

Caiuschen,

That comment you read is out of date now - I recently solved the cut-off content issue (see the article on vertical centering).
#7

Alex Walker said 1858 days ago:

Nice article Jon.
A few weeks back we used pixy's method to style a list as 'rollover-ized tabs' for our site. We hadn't picked up the Safari hover:off bug till just now. What a pain.
#8

sandy rubinfeld said 1800 days ago:

This is a wonderful and simple method. It works fine for me in Netscape 7.1, Firebird, Safari. However, major problems in IE 5.2.2 -- it doesn't show up at all. My nav is horizontal. When I change display: block to inline, then the text shows up, and the hover partially shows. Then it breaks in all browsers. Anyone else having problems in IE with this? Much thanks!
#9

sandy rubinfeld said 1800 days ago:

An added note to the above: When I put in all the links, Safari acts strangely, as well. The links do show up and the hover works, but either they do not take the horizontal space of the background images from the URL, or they are not positioned horizontally where they should be. Firebird and Netscape are perfect, though.
#10

Jon Hicks said 1799 days ago:

Sandy, have you tried floating each one left, rather than display:inline?

Also, I've been meaning to update this. IE 5 Mac doesn't like the overflow:hidden, but Safari needs it. See this blog entry:

http://www.hicksdesign.co.uk/journal/archives/000237.php
#11

sandy rubinfeld said 1799 days ago:

Thanks a lot, Jon!
Your blog entry with the IE hack did work, and I've kept it at 'display:block'. Now, IE works like it should.
I did find, however, that it was quite tricky to get it working right. I took out the overflow:hidden code from the rest of the gilder-pixy method, and put it after the stylings for the hover and active links, like so (don't faint, but I did use a table for my links ;-)
#digitalmenu a:hover, #printmenu a:hover, #webmenu a:hover, #motionmenu a:hover, #handmenu a:hover, #writingmenu a:hover
{background-position: 0 -40px; }

#digitalmenu a:active, #printmenu a:active, #webmenu a:active, #motionmenu a:active, #handmenu a:active, #writingmenu a:active
{background-position: 0 -40px; }

/* IE 5 hack \*/
tr#mainmenu td a { overflow: hidden; }
/* end hack */
#12

Jon Hicks said 1798 days ago:

Sandy, thats right, the hack goes after the code. Sorry, perhaps I hadn't made that clear enough.
#13

kate shorey said 1748 days ago:

hi how long have you all been plahing inteimately with CSS? My Mom the webdesigner took a class a year ago while I was maintaining existing code (usually HTML 3.2 with JavaScript).

I am just now getting to the purist stuff and am about to take HWG's CSS class. Bought a few info arch, CSS, and web style books and have a fire lit under me. I can't wait to try all this stuff as I recreate my 10 "scrapbook" web sites from scratch!

http://solakate.com
http://urlygrl.com

Elsewhere

The Rissington Podcast - weekly shenanigans with Jon Oxton

Hicksmade - unique handmade goods by Leigh Hicks width=

love

Brit Pack: A proud member I love Omniweb Coda Segment Publishing I buy my type from Veer The Forgiveness Project