Roll Over, Rollovers

I recently stumbled on a way to do image rollovers in pure CSS. Or so I thought; unfortunately, it doesn't actually work, even in the latest browsers. That got me thinking, though, and I did come up with something eventually. I'm not happy with the working method, but it works.

It is possible to do highlighting of images by giving them a checkerboard transparency, and setting a background color (or even an image) which then shines through the foreground. That one works fine, and it doesn't do any more violence to the document than traditional rollover code. I'm putting it in last, just for kicks, even though it isn't strictly a rollover.

Doesn't Work, But Should(?)

Here's what I first devised, only to hit a brick wall of failure. (Ouch.) I figured that you could put a button image in a table cell and set the background of the cell to the "active" image. Then you put the "normal" image in the foreground inside a hyperlink, and then on hovering the link turn the button invisible. As I understand it, an invisible element still exists-- but can you interact with it? My brain says "yes," the specification says nothing, and current browsers say "no." Try it for yourself:

Here's the CSS:

td.cell {height: 30px; width: 70px; background: url(active.gif);}
a.cell:hover img.cell {visibility: hidden;}

I still don't get why this doesn't work. Browser failings? Flawed CSS? A misunderstanding of how CSS treats invisible elements? Help me out.

Works, But is Icky

When I say "icky," I mean from a structural/content point of view. It basically means fiddling with the background of an anchor element which has no visible content-- I use a non-breaking space. This kills all content from the anchor itself, since you can't put ALT text on a background image. And you can't exactly inline these guys, but since when did anyone do rollovers in the middle of the document? Anyway, this works...


Here's the CSS which makes it possible:

a.blank {background: url(normal.gif); height: 30px; width: 70px; display: block;}
a.blank:hover {background: url(active.gif);}

Of course, because the link itself has no actual content indicating where the link points, the accessibility penalties are severe. And it's almost certainly going to break horribly in any browser with a version number less than 5.0. I wouldn't recommend this anyone without serious caveats. Still, it's kind of neat, isn't it?

Works, But With Limits

The last one isn't a pure rollover, but with some creativity one can acheive similar effects. This requires creating an image with a fairly flat background and then giving it a "checkerboard transparency," which is a trick I first learned from Todd Fahrner. By setting a grid of transparent pixels, you can let whatever's behind the image come partwya through, giving a nice screening effect. In Todd's example, this was used to lay text over a background image. But what if we mess with the background of the image itself? Consider:

That's the same image five times, each time with a different background color. In fact, the first one has a background color which is equal to the non-transparent background colors. This smooths out the background color of the button. Of course, we can use any color or even a background image, so long as we don't mind it getting washed out:

And the CSS:

a.imgbg1 img, a.imgbg2 img {background: silver;}
a.imgbg1:hover img {background: yellow;}
a.imgbg2:hover img {background: yellow url(target.gif);}

This one even lets you set visited styles, if you're so inclined to mark your graphic icons according to where a user has been, and do it about a million times more easily than you could with Javascript.

Works, But With Different Limits

Of course, there's always the approach of styling hyperlink text itself, and letting the chips fall where they may. This involves giving up some control over appearance, but there you have it. You can still do pretty neat stuff. The following two links are just plain text links with moderately complex styling. It actually isn't too out there in CSS terms, but browser support has only recently caught up to this sort of thing:

Eric's Books CSS:TDG

The CSS used in this case:

a.button1, a.button2 {padding: 5px; border: 2px solid black; background: #66CCFF; color: #003366;
   font: bold 12px sans-serif;}
a.button1:hover {background: yellow; color: red; border-color: navy;}
a.button2:hover {background: yellow url(target.gif) center no-repeat; 
  color: red; border-color: navy;}

Again, the author can define sophisticated "visited" styles to indicate that the button points to something already seen. The background image used here isn't very good, but illustrates the point. I'll come up with something more interesting as soon as I turn this into a real article.