Greg's Blog

helping me remember what I figure out

CSS Image Rollovers

| Comments

Usually when I build a page that uses image rollovers I use a small and simple Macromedia generated script, that include in my page as an external JavaScript file called “_roll_over.js”. The contents of that file is as follows:

<!–
function MM_findObj(n, d) { //v3.0
var p,i,x; if(!d) d=document; if((p=n.indexOf(“?”))>0&&parent.frames.length) {
d=parent.frames[n.substring(p+1)].document; n=n.substring(0,p);}
if(!(x=d[n])&&d.all) x=d.all[n]; for (i=0;!x&&i<d.forms.length;i++) x=d.forms[i][n];
for(i=0;!x&&d.layers&&i<d.layers.length;i++) x=MM_findObj(n,d.layers[i].document); return x;
}
function MM_swapImage() { //v3.0
var i,j=0,x,a=MM_swapImage.arguments; document.MM_sr=new Array; for(i=0;i<(a.length-2);i+=3)
//alert(MM_findObj(a[i]));
if ((x=MM_findObj(a[i]))!=null){document.MM_sr[j++]=x; if(!x.oSrc) x.oSrc=x.src; x.src=a[i+2];}
}
function MM_swapImgRestore() { //v3.0
var i,x,a=document.MM_sr; for(i=0;a&&i<a.length&&(x=a[i])&&x.oSrc;i++) x.src=x.oSrc;
}

function MM_preloadImages() { //v3.0
var d=document; if(d.images){ if(!d.MM_p) d.MM_p=new Array();
var i,j=d.MM_p.length,a=MM_preloadImages.arguments; for(i=0; i<a.length; i++)
if (a[i].indexOf(“#”)!=0){ d.MM_p[j]=new Image; d.MM_p[j++].src=a[i];}}
}

//–>

Next I’d proceed to include the file in the page, pre-load the images required and set the appropriate onMouseOver event for the element that requires a rollover action. As an example here is the sample source of the Sunbeam site:

<html>
<head>
<title>Site name >> Home</title>

<link rel=”stylesheet” type=”text/css” href=”/css/default.css”>
<script language=”JavaScript1.2” type=”text/javascript” src=”/js/_roll_over.js”></script>
</head>

<body topmargin=”0” leftmargin=”0” marginheight=”0” marginwidth=”0” class=”ban_data” onLoad=”return MM_preloadImages(‘/images/sb_home_nav_prod_o.gif’, ‘/images/sb_home_nav_serv_o.gif’, ‘/images/sb_home_nav_about_o.gif’, ‘/images/sb_home_nav_media_o.gif’);”>

<a href=”/products/index.cfm?home_id=3” onMouseOut=”MM_swapImgRestore();” onMouseOver=”MM_swapImage(‘SB_nav_1’,”,’/images/sb_home_nav_prod_o.gif’,’SB_txt’,”,’/images/sb_home_txt_prod.gif’,1);”><img name=”SB_nav_1” src=”/images/sb_home_nav_prod.gif” width=”186” height=”27” alt=”Product centre” border=”0” /></a>
</body>
</html>

And this set up worked rather well, as it, as far as I am aware, works on all browsers. However times are a changing and just recently I noticed that sites were adopting a style sheet based roll over mechanism. Totally makes sense, and hence I wanted to know what made it happen. So off I went and pulled apart Zeldman’s homepage. And below is a code sample page making use of the CSS rollover technique

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
<html xmlns=”http://www.w3.org/1999/xhtml” xml:lang=”en” lang=”en”>
<head>
<title>Css rollover</title>
<meta http-equiv=”Content-Type” content=”text/html; charset=iso-8859-1” />
<meta name=”DESCRIPTION” content=”” />
<meta name=”KEYWORDS” content=”” />

<!– style sheet–>
<style>
<!–
/* Totally ripped from http://www.zeldman.com/
even the comments :)
*/
.rb {
/* Opera uses this background for the rollover effect. */
background: url(i/categories_btn_o.gif) no-repeat 1px;
}
#ic {
display: block;
padding: 0;
border: 1px solid #fff;
background: url(i/categories_btn.gif) no-repeat 1px; /* start hiding from macie\*/
background-position: 0px; /* stop hiding */
width: 100px;
height: 14px;
voice-family: “"}"”; /* Need we explain? */
voice-family: inherit;
width: 100px;
height: 14px; /* Actual values to overlap borders */
}
html>body #ic {
width: 100px;
height: 14px; /* Be nice to Opera */
}
#ic {
background-image: url(i/categories_btn.gif);
}
a#ic:hover {
background-image: url(i/categories_btn_o.gif);
border: 1px solid #333;
}
.alt {
display: none;
}
–>
</style>
</head>

<body>
<div id=”rb”><a id=”ic” href=”” title=”Categories”><span
class=”alt”>Categories</span></a></div>
</body>
</html>

As stated in the teaser I am not too sure what is going here, but here is what I do know:

  • the class rb defined in the style sheet for the div tag uses the background image set here for the roll over (good comments eh??)
  • Now the id ic is set twice. Hmm?? The first instance helps define borders, border colours and size as well as setting the default background for this id to the my image.
  • And then they make use of the box model hack for IE 5 and above, so that the border displays properly.
  • No idea what html>body#ic does, possibly some kind of inheritance?
  • However I know that a#ic:hover, is where the roll over action takes place and is very similar to normal roll over behaviour. You just specify the image to display when the mouse hovers, and change the background colour
  • The alt class is there for browsers that cannot render Style Sheets properly. This would result in nothing being displayed at all, but since older browsers don’t understand style sheets, at least the span element will appear, thus giving the user the ability to still surf the site.

I guess there is still a lot to learn about style sheets, but it’s cool and web standards compliant. Just in case you were wondering why bothering trying to figure it out in the first place.