• entries
94
127
• views
83355

# CSS controlled images & buttons

250 views

Edited 2006-07-22: Found ways to preload images for rollover and alternate text/images through CSS.

*rants about browser-hell for a few pages*

Anywho... Now I can change the images and buttons of the page purely through CSS, without touching the (X)HTML. I tried several methods, that I'll present.

# Inherited code

It all started with this odd piece of code I "inherited". It's for a button! Imagine that! I've omitted the linking code (onclick="document.location.href='aboutus.aspx'; return false;" language="javascript") and name tags.

// HTML.. kinda :P "image" title="About Us" class="btnAboutUs" oncontextmenu="return false;" onmouseover="this.className='btnAboutUs-Over';" onmouseout="this.className='btnAboutUs';" onmousedown="this.className='btnAboutUs-OnClick';" src="images/transp_pixel.gif" border="0" />// CSS.btnAboutUs{background: url(images/aboutus_idle.gif) center center;width: 69px;cursor: pointer;height: 28px;border: none;}.btnAboutUs-Over{background: url(images/aboutus_over.gif) center center;width: 69px;cursor: pointer;height: 28px;border: none;}.btnAboutUs-OnClick{background: url(images/aboutus_click.gif) center center;width: 69px;cursor: pointer;height: 28px;border: none;}

## The markup

The onmouseover, onmouseout, and onmousedown events gives the input object new class names so the images can be defined by the CSS. Nifty! The src and border attributes are only there so we won't get a image-not-found-icon, since in this case behaves as .

## The stylesheet

The button is now represented by three classes, each defining what button to show on each event. But what if we want the same image on normal and onclick? Or just change the image and not the other selectors? Seems like alot of copy-paste... What if we could inherit the values from the basic image? hmmm...

# Enhanced code

CSS inheritance let's us override only the selectors we want, as just the image path. We use the id attribute instead, and use the class attribute for the different states; idle, over, click.

// HTML "image" title="About us" id="btnAboutUs" class="idle" onmouseover="this.className='over';" onmouseout="this.className='idle';" onmousedown="this.className='click';" src="images/transp_pixel.gif" border="0" />// CSS #btnAboutUs{background: url(images/aboutus_idle.gif) center center;width: 69px;cursor: pointer;height: 28px;border: none;}#btnAboutUs.over{background: url(images/aboutus_over.gif) center center;}#btnAboutUs.click{// changed picture completely (including size), not so smart but just showing that it's possible.background: url(images/aboutus_click.gif) center center;width: 145px;height: 57px;}

## Thoughts

This simplifies the (X)HTML quite a bit, and now we only change two values instead of five when reusing the code. But the real improvement is in the CSS. Now if you only want one image, you can just ignore the over and click classes! And the cursor and border selectors are inherited so all btnAboutUs has that! But can't we get hover events "naturally"?..

# Quirky code

If we wrap the input-tag in a regular link, a-tag, we can get hover events for free* !

// HTML// note the a-tags!"image" title="AboutUs" id="btnAboutUs" src="images/transp_pixel.gif" border="0" />// CSS#btnAboutUs{background: url(images/menu_aboutus_idle.gif) center center;width: 69px;cursor: pointer;height: 28px;border: none;}a:hover #btnAboutUs{background: url(images/menu_aboutus_over.gif) center center;}/* there's no a:click so we can't detect it, but check this: */a:visited #btnAboutUs{background: url(images/menu_aboutus_visited.gif) center center;}

## Thoughts

Sadly we can't detect click events without using classes again. But the HTML is hell-a-clean! And we can detect visited links!

* = Of course, this doesn't work in IE5.5 or even 6. When it's too good to be true, it usually is.

There are two differences so it doesn't act as a clickable image. First remove the hinting (hand cursor) with CSS, i.e. cursor: default; instead of pointer. Then add the property disabled="disabled" to the HTML input-tag so it won't work as a link.

# Summary

I'm currently using the second method, since it works for most browsers and has an extra event - just in case. Sadly, but correctly, you can't inject text with CSS so you can't alternate between text and image buttons through CSS very easily, but there seems to be some ways.

In some cases/browsers the image flickers on hover, so you can extend this code to cover for that with this or this.

Let me hear your thoughts on images and buttons in CSS!

There are no comments to display.