...rediscover the joy of coding

Resizing Single-Image-Rollovers Using jQuery

In this article I describe how to create shaped buttons in HTML/CSS that size to their content, have roll-over state, and require only a single image, using jQuery.

I'm sure most web developers know about image rollovers (using separate images for normal and "hover" states of anchors). Hopefully also the use of "CSS Sprites" is becoming better known - combining the normal and rollover images into a single physical image file to speed up load times and reduce flicker. I won't cover those techniques here.

However, if you want the anchor or button to size to its contents, it's more difficult to make use of these techniques. Here's one way.

Sizing Rollovers

(The final result - view demo).

Start With Markup

Before diving into fancy techniques, get the markup down as you would like it, if you didn't have to style anything.
<a href="..." class="rollover">Button Text</a>
Ideally we want the markup to be clean and not compromised by styling requirements.

Handle Degradation Gracefully

My technique is going to make use of JavaScript, so let's handle the case where the user has it disabled for some reason. Here's some very basic CSS to give the button a simple style:
  background-color: #00f;
  border: solid 1px #000;
  color: #fff;
  font-weight: bold;
  padding: 4px;
  text-decoration: none;

a.rollover:hover { background-color: #008; }
Add Styling Naively

Next, I'm going to add some rollover styling - but in a way that isn't complete. Firstly I created a simple rollover image, but made it very wide - it needs to be at least as wide as the widest button is ever going to be:

Button Rollover

I'm going to define my rollover styling against a class selector of "extra" - you'll see where that comes from in a moment.
  background: url(buttons.png) repeat-x left 0;
  border: none;
  height: 27px;
  padding: 23px 40px 10px 40px;
  position: relative;

a.rollover.extra:hover { background-position: left -57px; }
Note that we've had to undo some of the styles applied previously, such as border.

We're kind of getting there, but our buttons won't look correct on the right-hand-side.

Use JavaScript To Add Styling Markup

To fix the right-hand end-caps, we need to modify our markup. However, I really don't want to have to do that on my pages - afterall, I might change my mind about the site styling.

Here I recommend using JavaScript to tweak at runtime the markup to what we need. I'm going to use jQuery for this:
$(function() {
    .append('<div class="cap"></div>');
Basically, when the pad is ready, I find all elements with class "rollover", add another class ("extra"), and append into the rollover button an empty span element which has a class of "cap".

That class "extra" triggers the image rollovers. The "cap" span can be styled as follows:
a.rollover.extra .cap
  background: url(buttons.png) no-repeat right 0;
  height: 100%;
  position: absolute;
  right: 0;
  top: 0;
  width: 40px;

a.rollover.extra:hover .cap { background-position: right -57px; }
And voila!
If you'd like to see this technique in action, please view the demo.