Troubleshooting & How-Tos 📡 🔍 Web Development

Pure CSS Buttons

Several months ago, I went on a minor site optimizing kick. One thing I decided to do was replace the validation labels with something smaller, less obtrusive, and directly on the page. I tried to duplicate the look of the classic antipixel-style buttons by splitting a link into two elements, but had so much trouble getting borders and height to match up correctly that I wrote it off completely.

Simple Version

After a while I came back to it, and started with very simple buttons like this:

Two rectangles, each slightly taller than a line of text, with thin black outlines, one yellow and one green, stating Valid HTML and XFN Friendly

Your browser shows this as:

Valid XHTML XFN Friendly

Here’s the CSS and HTML used for this version:

a.w3c, a.nw3 {font: 9pt Arial, Helvetica, sans-serif; border: 1px #000 solid; padding: 2pt; text-decoration: none;}  
a.w3c:link, a.w3c:visited {color: #000; background: #fc6;} 
a.w3c:hover, a.w3c:active {background: #fec;} 
a.nw3:link, a.nw3:visited {color: #000; background: #adb;}
a.nw3:hover, a.nw3:active {background: #cfe;}
<a class="w3c" href="#">Valid XHTML</a> <a class="nw3" href="#">XFN Friendly</a>

Of course, Netscape 4 had problems with this [Note: this was back in 2004, when there were still people using it], because it dislikes putting borders or padding on inline elements — like links. Not only does it push them onto separate lines, but they’re no longer clickable! What I ended up doing was separating out the border and padding rules and putting them in an @media screen section to hide them. So on Netscape 4 it looked like this:

[Similar, but with underlines and no borders.]

Earlier this month, I found Eric Meyer’s take on the same problem: using CSS to imitate those buttons so that visitors don’t have to download an extra 15 images just for footnotes. He was trying for as exact a match as possible, and the result looks great – in Mozilla, Opera, Safari or Konqueror. But the margins aren’t quite right in IE, and unlike Eric, my site isn’t a showcase of what CSS can do.

Adapting to IE

I ended up using his idea of putting a single tag inside the link — that’s all you really need to divide it into two regions — and using two classes to simplify using the same styles for different types of buttons. Since I’d already abandoned the idea of an exact match, I didn’t worry about getting the fonts and spacing exactly right, and since I was using these in a horizontal row, I didn’t have to worry about specifying widths. It looked pretty good, at least on Mozilla, Opera and Safari:

[Two rectangles, each slightly higher than a line of text, with a black border, and split horizontally. The first is split between light blue on white 'W3C' and black on yellow 'Valid XHTML' an the second is split between white-on-green 'XFN' and black-on-light-gray 'Friendly.']

I still had problems in Internet Explorer, though. It adds the padding together, even though it shouldn’t mess with the line height on an inline element, so it ended up with an extra line of background color around the left section:

[Similar, but with margins around the smaller section of each rectangle.]

Since I wasn’t trying to match exactly, I decided to just remove all the vertical padding, leaving something much narrower than the originals, but much cleaner than what I could get otherwise.

[Similar, but the space in each box above and below the text has been removed.]

Final Version

<a class="btn w3c" href="#"><span>W3C</span> Valid XHTML</a>
<a class="btn fea" href="#"><span>XFN</span> Friendly</a>
<a class="btn ff" href=""><span>Get</span> Firefox</a>
a.btn {font: 8pt Arial, Helvetica, sans-serif;
	padding: 0 .5em 0 0; border: 1px #000 solid;
	text-decoration: none}  
a.btn span {border-right: 1px solid #000;
	margin: 0 0.1em 0 0; padding: 0 0.5em}

a.w3c:link, a.w3c:visited {color: #000; background: #fc6}
a.w3c:hover, a.w3c:active {background: #fec}
a.w3c span {background: #fff; color: #06c}

a.fea:link, a.fea:visited {color: #000; background: #ccc}
a.fea:hover, a.fea:active {background: #bed}
a.fea span {background: #093; color: #fff}

a.ff:link, a.ff:visited {color: #fff; background: #009}
a.ff:hover, a.ff:active {background: #99f}
a.ff span {background: #f93; color: #000}

This works well in modern versions of IE, Mozilla, Netscape, Opera, Safari and Konqueror. IE5 gets the colors right, but doesn’t show the borders. Netscape 4, interestingly, doesn’t recognize multiple classes. It thinks btn w3c is a single class with a space in the middle, so its freak-out over borders and padding is no longer a problem. It just ends up looking like a normal text link. It’s not great, but at least it works, and at this point that’s all I want for NS4.

There’s one more problem, and that’s one of accessibility. The Web Accessibility Initiative (WAI) and Section 508 guidelines both suggest you avoid putting links next to each other with no separation, because a screen reader might not make it clear to a blind web surfer that the links are separate. I haven’t come to a final decision on this one, but what I’ve got on some pages is just separating them with ordinary bullets:

W3C Valid XHTML · XFN Friendly · Get Firefox