Links. And how to mask them. Or, how to make them visible and good enough for every single person that wants to visit your page. If you put only text and wrap that one in an div or span element of your choice, there has to be a lot of css gymnasctics included afterwards if the result is expected as 100% - perfect. If you decide to use images instead of text, than you probably would try to handle that desire with a few lines of javascript, which is very common practice today. But, when it comes to styling and coloring and layout modification, CSS is - remember, invented for that. Therefore, for rollover buttons, too.
Why avoiding javascript?
Again, the same old reason: performance.
No one says that javascript solutions are sluggish or sloppy or just - slow. No, quite the opposite, but, in this case, javascript has nothing to interfere with, yep.
First, let's compare the overall usage of js and css regarding rollover images in a very simple way:
js typical rollover method
Usually requires no more than 4 images. One image for a link, one image-active link, one for visited link state and one image for hover state. Beside those images we need few or just one line of js code + few html elements.
Javascript method is not working when some jackass actually turns off javascript from his/hers favorite browser. ☺
this button method, the following method
Requires only 1 image. Includes two states. Hover and active. Uses few lines of css for moving that one image up, down, left or right, depends on your choice. No need for preload (unless there are much more buttons) and co-operates perfectly with every single browser.
Here is the rollover sample that shows and hides journal menu links on this site. →

It's width is 18px with 54px height.
If you have some other size for button in mind, some other image, let's say 20px, the complete image would be 20px in width and 60px in height. Negative values for vertical image position in background property for circleImg a hover and a active are doing the whole magic.
css code for it ↓
#circleWrap { position:absolute; left:0px; top:0px; width:auto;height:auto;} .circleImg a { padding:0; display:block; width:18px; height:18px; background:url('button.jpg') 0 0px no-repeat;} .circleImg a:hover {background-position:0 -18px;} .circleImg a:active {background-position:0 -36px;} .hiddenText {position:absolute;z-index:-1; font-size:0%;visibility:hidden;display:none;}
Explanation ↓
ID #circleWrap - image container wrapper id
position_absolute - rule selection depends on site structure
left and top_0px - defines the exact location of the image container
width and height_auto - you don't want to touch this. If you do, you'll die :P
Class .circleImg a - image and link container it self
padding_0_display_block - simply do nOT modify this line
width and height_18px - correct, true size of the image box
background_url('button.jpg') 0 0px no-repeat - image stands at absolute left on top and is displayed only once
Classes .circleImg a:hover and active - defines image position when over and clicked
Class .hiddenText - This hides the text inside circleWrap and reveals it when page is viewed as simple html, without any stylesheet.
<!DOCTYPE html> <html lang="en" xml:lang="en"> <head> <meta charset="utf-8"> <title>Css button demo</title> <link href="style.css" rel="stylesheet" /> </head> <body> <div id="circleWrap"> <div class="circleImg"> <a href="#"> <span class="hiddenText">Link name</span></a> </div> </div> </body> </html>
Looks like a clear picture. But, what if we play a little bit more?
Let's imagine that we need more than one.. ↓
<!DOCTYPE html> <html lang="en" xml:lang="en"> <head> <meta charset="utf-8"> <title>Css button demo</title> <link href="style.css" rel="stylesheet" /> </head> <body> <div id="circleWrap"> <div class="circleImg"> <a href="#"> <span class="hiddenText">Link name</span></a> </div> </div> <div id="cWrapSecond"> <div class="cImgSecond"> <a href="#"> <span class="hiddenText">Link name</span></a> </div> </div> </body> </html>
Css for that would be a little bit different, but not that much at all ↓
#circleWrap { position:absolute; left:50px; top:50px; width:auto;height:auto;} #cWrapSecond { position:absolute; left:100px; top:50px; width:auto;height:auto;} .circleImg a { padding:0; display:block; width:18px; height:18px; background:url('button.jpg') 0 0px no-repeat;} .cImgSecond a { padding:0; display:block; width:18px; height:18px; background:url('button.jpg') 0 0px no-repeat;} .circleImg a:hover, .cImgSecond a:hover {background-position:0 -18px;} .circleImg a:active, .cImgSecond a:active {background-position:0 -36px;} .hiddenText {position:absolute;z-index:-1; font-size:0%;visibility:hidden;display:none;}
As you may have already noticed, a:hover and a:active are defining how our image behaves when mouse is acting over it.
For example, you can modify those values .. ↓
.circleImg a:hover, .cImgSecond a:hover {background-position:-2px -18px;} .circleImg a:active, .cImgSecond a:active {background-position:5px -36px;}
..and the difference would be very obvious. That would bring one "banging" little ball!