Skip to: Navigation | Content | Sidebar | Footer

Weblog Entry

Anchor Buttons

September 17, 2008

I can’t be the only one bored to tears of simple border and background colour styling for button formatting.

I recently worked on an application that used a common graphical button style across all pages, but didn’t offer common HTML elements to work with. Some of the buttons were clearly better implemented as a elements, whereas the rest were proper input buttons.

This is, of course, maddening. There’s literally no way to format an a and an input element identically across all browsers, aside from hard-wiring the text of that button into an image and using it to replace the element. That’s not exactly a viable fix on an application with dozens or hundreds of buttons.

I needed a middle ground. Images were necessary to pull off things like bevels and rounded corners and gradients and all those effects that make a button look like a button. But I needed HTML text to allow for easy button creation, and preferably in a way that would allow me to use both anchors and buttons interchangeably.

So I pulled up the Particletree button article from a few years back and went to work. After converting the input elements to buttons, I was able to work through most major cross-browser issues and come up with a set of styles that worked well on both those and anchor elements. You can see the results here, or download the source and images.

Quick update: some of the comments lead me to believe I wasn’t clear enough about what’s happening in these examples. You’ll see three sets of two buttons rendered identically side-by-side. On the left, the button is being constructed with the button element. On the right, the button is instead constructed with the a element. Same visual styling, but different markup.

This is just an incremental update over ground the original Particletree article has covered well, so I won’t bother writing up a detailed explanation. You’ve got the theory, and I think a quick look at the source ought to make the method fairly apparent.

A couple of caveats though: obviously there were concessions made in terms of extra markup for the sake of background images. And IE6/IE7 naturally don’t want to play fair; there’s a conditional comment that pulls in a touch-up CSS file for alignment, and it was necessary to fix the button widths to a hard pixel value. All other browsers expand and contract the buttons gracefully along with the text size, but IE marches to its own beat once again. And Chrome was launched in between when I originally built the demo page and today as I write this, but a quick look tells me it does the right thing.

Share and enjoy.

Stefan says:
September 17, 13h

Interesting article. I consider a appropriate use of buttons and anchors. Another approach which heavily lacks on browser issues is the use of select-elements optical as a set of buttons. One line can float them all. ;-)
I will write an article about this in the next weeks and will show it.

September 17, 14h

I have avoided the button tag because of the way IE posts the form submit. I have not found a way to cleanly work with more than 1 button tag in a form without using JavaScript to make it work. I am looking forward to seeing how you implement this.

Neal G says:
September 17, 14h

Dave, I’ve always considered the input type=”button” to be evil as well and have since switched to the button element simply because it seems more robust and because it is easier to target with css for older browsers (cough, ie6).

Perhaps when CSS8 comes out in 2020 we’ll have better control with styling form elements.

Eivind Ingebrigtsen says:
September 17, 14h

I’ve used a lot of different approaches to that problem, and I’ve landed on a similar approach, though not as infested by div’s.

My solution for this is :
<a href=”#” class=”button”><span>Text here</span></a>

This gives me the option to use the sliding doors effect with two images, or a plain version with border and background-color with an icon in the span using nested classes on the anchor.

Dan says:
September 17, 16h

Really nice tip! I think this is one of those simple little things that everyone misses, but is really useful to know about.

September 17, 17h

Very nice examples.

I, too, am interested to see how you can cleanly implement the button tag in conjunction with its IE quirks.

To those saying just use an ‘a’ link for the button - this isn’t suitable enough (without JavaScript assistance) to handle true POST requests.

You planning on using some JavaScript to assist you in the process?

Dave S. says:
September 17, 18h

Since from some of the comments I don’t think I made it clear enough what’s happening in these demos, I went back and added a bit more explanation.

Short summary: the demo has 3 sets of two buttons side-by-side; the left uses an HMTL button element, the right uses an a element instead. Same rendering, different markup. No Javascript required.

September 17, 19h

Like Mike Cravey above, I too have always avoided the element because of it’s strange behavior in IE.

Despite the standard warnings, I’ve always just styled submit elements with pretty good results. The only visual problems I’ve noticed are usually within Opera or Camino.

September 17, 19h

Of course, I failed to double-check the preview before posting. It should have read:

“…avoided the <button> element…”
“…styled <input type=”submit”/> elements…”

September 17, 21h

Nice examples but I thought (and correct me if this is not the case) that the buttons were supposed to expand and contract with text SIZE as well as length…

The ones we use over at GCap (and Yahoo use the same technique) do this and can be seen at - check out the search button at the top of the page and associated CSS with FireBug - there are IE styles, until I write up a post about them you’ll just have to be creative in how you find those out :>

September 17, 22h

Dave, the problem that some are referring to is the way IE 6/7 submits the button’s value.

More detailed info here:

The fix is to use either JS, or an IE7 only workaround to send the proper value through.

September 17, 23h

You can take a look at my solution which is using a, span and em tags.

September 17, 23h

Nicely done. And thanks for the nice xkcd reference in the sample buttons, made me lough out loud cause it was so unexpected.

Wolf says:
September 18, 00h

I used the Particletree solution a while ago but ditched it in favor of styled type=submit inputs; mostly because there was a black border around the button element in IE that I couldn’t get rid of.

Fraser Kemp says:
September 18, 00h

Eivind - I don’t think the sliding doors effect can be used in this instant due to IE6 (Boo) not allowing :hover element on anything other than the anchor point. I have been completing some updates on a site with curved corner tabbed navigation in multiple languages (the navigation must scale with expanding text lengths). For modern browsers I can easily achieve the rollover state on both ‘doors’ but where IE6 is concerned the only solution is to use JavaScript.

A nice article!

Eivind Ingebrigtsen says:
September 18, 03h

Fraser - I beg to differ: As long as you use the :hover on the anchor and nest the selector on the span like:

a.button {/* style here */}
a.button span {/* style here */}
a.button:hover {/* style here */}
a.button:hover span {/* style here */}

Then you got full power.
Example here:

(never mind the misaligned graphics…)

But you would have to use javascript to submit the forms - which really isn’t a good solution.

September 18, 06h

In my opinion, you still have to use JavaScript to get the button to work properly, or send the right value. In IE, the value of the button is actually the innerText of the button, not the value defined in the tag. It isn’t always consistent across browsers.

We used to think it was plausible to use the button tag, then it caused too many problems that we decided to use a/img instead, since both would require JavaScript to fix their functionality.

September 18, 09h

We use ‘sexy’ css buttons from

They work pretty well, especially in IE.

Dave S. says:
September 18, 10h

Ah, right, the IE submit problem. Goes to show how much time I do back-end processing, I’d completely forgotten about that.

So, no, I don’t have a fix for that; I was mainly interested in the front end here.

September 18, 15h

@wolf: Did you figure out how to get rid of the black border?
@Dave: You’ve got a neat example of how to style buttons and anchors but it seems to me that you spent a quiet some time working on that. I’ve been working on a similar solution myself without being success yet. Getting the images to line up is the hard part. I don’t know if you noticed it but your buttons flickr back and forth between images in IE/6 and IE/7 It’s weird!

Wolf says:
September 19, 00h

@Juliano Moreira: no, I never figured that one out, I don’t think it’s possible.

September 19, 07h

I don’t like it much.

I prefer CSS Globe’s way,

or Google Analytics way.
(Inspect google analytics button, with Firebug and check it out).

September 22, 04h

Nate, I think the trick with the BUTTON element is to use it only to submit a form, but not to submit any information itself. For that, use INPUT elements (type=”hidden”).

This was the subject of recent discussion on Drew’s site:

September 22, 08h

I also have had to fight the problem of a black border around button elements in IE. Very annoying. I think cross browser functionality has been my biggest challenge in every project this year.

Gerben says:
September 23, 08h

Somehow the outline on the anchor, when it is focused, is no longer visible in Firefox (3). This is kind of an accessibility issue.
The buttons are working fine.

September 25, 15h

@Ignacio Ricci: I believe those are all *buttons*, not buttons and *anchors* styled similarly!

October 29, 20h

I still can’t get over the havoc that the text-transform property wreaks in IE6 on button styling..

I was pulling my hair out on a button with a background image and perhaps it was a magical combo of previous junk-perties assigned trying to get it to work, but upon distillation of the CSS, IE6 rendered the text-transform: uppercase to act as an image replacement’s negative text indent… Whoa.

thinsoldier says:
January 28, 20h

I’m surprised. It’s always seemed to me that the majority of people strongly behind web standards were also the people strongly against styling native form widgets (and scrollbars).

I think in the long run us form-stylers will come out on top. The more people use more than 1 OS and rely on web-apps more than desktop apps, the less they’ll care about an app being consistent with the OS instead of consistent across browsers and platforms