views:

666

answers:

7

When setting up a rollover effect in HTML, are there any benefits (or pitfalls) to doing it in CSS vs. JavaScript? Are there any performance or code maintainability issues I should be aware of with either approach?

A: 

I'd stay on the CSS side of the house, but I've done very little Javascript.

CSS seems to be easier to standardize across browsers than Javascript, though that may be changing with the advent of Chrome's V8 and Firefox's upcoming new rendering tool.

warren
+1  A: 

Because it's an aspect of presentation, I'd say it's more standards based to do it with CSS. It used to be done in Javascript, simply because we couldn't do it with CSS (old browsers suck, and I don't think :hover was even added until CSS 2).

Jon Smock
+6  A: 

It will still work in CSS if the browser happens to have Javascript disabled.

+1  A: 

Implementing a rollover with CSS uses the :hover pseudo-class to define the style of the target element when it is hovered over. This works great in many browsers but not in IE6 where it only works well with the anchor tag (i.e. a:hover). I used CSS hover to implement a tabbed navigation bar but had to use IE behaviors to get it working in IE6.

b3
+24  A: 

CSS is fine for rollovers. They're implemented basically using the :hover pseudo-selector. Here's a really simple implementation:

a{
    background-image: url(non-hovered-state.png);
}
a:hover{
    background-image: url(hovered-state.png);
}

There are a few things you need to be aware of though:

  • IE6 only supports :hover on <a> tags
  • Images specified in CSS but not used on the page won't be loaded immediately (meaning the rollover state can take a second to appear first time)

The <a>-tags-only restriction is usually no problem, as you tend to want rollovers clickable. The latter however is a bit more of an issue. There is a technique called CSS Sprites that can prevent this problem, you can find an example of the technique in use to make no-preload rollovers.

It's pretty simple, the core principle is that you create an image larger than the element, set the image as a background image, and position it using background-position so only the bit you want is visible. This means that to show the hovered state, you just need to reposition the background - no extra files need to be loaded at all. Here's a quick-and-dirty example (this example assumes you have an element 20px high, and a background image containing both the hovered and non-hovered states - one on top of the other (so the image is 40px high)):

a{
    background-image: url(rollover-sprites.png);
    background-position: 0 0; /* Added for clarity */
    height: 20px;
}
a:hover{
    background-position: 0 -20px; /* move the image up 20px to show the hovered state below */
}

Note that using this 'sprites' technique means that you will be unable to use alpha-transparent PNGs with IE6 (as the only way IE6 has to render alpha-transparent PNGs properly uses a special image filter which don't support background-position)

Dan
You can get the `:hover` pseudoclass to work on any element in IE6 by specifying a doctype.
Justin Poliey
Technically, I think the background position should be `0 -20px` to work right, but since `background-repeat` isn't set to no-repeat, it doesn't matter.
Wes P
@jdp: I'm not sure you're correct there my friend.. IE6 has only every supported :hover (without hacks) on <a> tags. Though, I'm more than willing to be proven incorrect.. Got an example?
Dan
@Wes P: You're entirely correct, on both counts. I'll amend my code, thanks.
Dan
AFAIK, the standards state that :hover should work for all elements, but only works for anchors in IE6.
CJM
A: 

Isn't there a mnemonic for remembering the sequence of declarations in CSS?

Rob Wells
+1  A: 

Yep, the best way to do this is css sprites. An annoying problem occurs in IE6, when browser make a request every time an element is hovered. To fix this, take a look here.

Ionut Staicu