Form Buttons

BY TOM HERMANSSON SNICKARS
I started experimenting with (X)HTML form button styling and found more quirks than expected. In this article I tell you about my findings and conclusions. Testing have been done with IE6, Firefox 1.5, and Opera 8. The short summary goes like this: 'Style them thoroughly, or not at all. Hide them if you're a design and/or cross-browser perfectionist'.
Putting buttons in your page is pretty straightforward at a first glance. Just put an input element of type button in your code, like this:
<input type="button" value="Button label" />
The button below shows what that would look like.
Alternatively we can use the button element:
<button type="button" >Button label</button>
The default styling is different depending on what operating system and browser you are using. Since the button is rendered like other buttons under the OS/browser, anyone can recognize it as a button, wherever it is. There are also some nice features without any CSS styling: Let's start adding some of our own style settings to a button. The button below has settings for color (a shade of blue), font-family (Georgia – a serif font), font-size (18px), letter-spacing (3px), and padding (5px):
<input type="button"
    value="Custom"
    style="color: #07c;
        padding: 5px;
        font-family: Georgia, ..., serif;
        font-size: 18px;
        letter-spacing: 2px;" />
A button element with the same style settings look like this:
So far the 3D-effect is still there, so you can do some styling to fit the rest of your pages. There are some problems though. If you set the height property the height will be different with the button element and the input element in Opera 8. By controlling the height with the padding property, we can still make the buttons look similar in the three browsers. In IE horizontal padding does not replace the default padding. Instead it is added to it which make the button even wider. In Firefox and Opera the padding looks like one would expect (but only when the button element is used). If these quirks are unacceptable for your design (and you need to use the form button elements), you probably need to do some CSS hacks or scripting to give browsers different property values. By using fixed width buttons we can get around the horizontal padding problem in IE.
<input type="button"
    value="Wide button with fixed width"
    style="color: #07c;
        padding: 2px 5px;
        font-family: Georgia, ..., serif;
        font-size: 18px;
        height: 30px;
        display: block;
        width: 300px;" />
A button element with the same style settings look like this:
Opera doesn't render a button at all when the button tag is used. I recommend the input tag as long as you just need buttons with plain text labels. Adding width works around the IE padding problem though. But this solution is not ok if you want the width to depend on the length of the label. A new IE problem just appeared as well. With wide buttons (regardless of why they are wide) IE stretches the button's borders which make them look awful. In Firefox and Opera they look as one would expect. The buttons are wider, but the border is just as wide as before.
If you cannot accept the browsers different default styling of buttons (and/or the quirks in IE), you need to add more CSS. Let's remove some style settings and add a background-color (light gray):
<input type="button"
    value="Button with background-color"
    style="color: #07c;
        background-color: #ddd;
        padding: 2px 5px;" />
And the same styling with the button tag (on a white background):
<button type="button"
    value=""
    style="color: #07c;
        background-color: #ddd;
        padding: 2px 5px;"
>Button with background-color</button>
The nice 3D-effects, the round corners, and the mouseover effects disappear when we set the background-color. This happens in all of the three browsers I've tested. There is still a simple 3D-effect that looks the same in IE, FF and O8. It's accomplished by changing the border colors to make them look slanted, and lit up by a light source in the upper left corner. When the button is pushed the colors are swapped to give us the impression that the button is pushed in a few millimeters to a level 'below'/behind the document surface. It also looks like the button moves to the bottom right (on dark backgrounds), which is what the label does in IE. In fact, IE and Opera has the neater look with these settings, but the padding problem persists in IE. In Firefox the label looks stuck while the button is moving in, down, and to the right (on dark backgrounds).
Let's try with border settings, but no background-color:
<input type="button"
    value="Button with border"
    style="color: #07c;
        border: 2px solid #07c;
        padding: 2px 5px;" />
With border settings, there are no fancy 3D-effects, and no outset border (unless you add one). In Firefox you can't even see a mousedown effect. Only the focus indicator (the dotted border around the label) shows that you're pushing the button. In Opera a thin dark/black border is added when you push the button. In IE the border is made thicker. The same effects are used to indicate focus. For some reason (OS-settings?), the background-color is now set to a beige or off-white tone in all three browsers.
Let's try with a fixed width button with borders and a background-image:
<input type="button"
    value="Button with full styling"
    style="color: #fff;
        padding: 2px 5px;
        border: 2px solid;
        border-color: #7bf #07c #07c #7bf;
        background-image: url(images/bg1.jpg);
        font-family: Georgia, ..., serif;
        font-size: 18px;
        display: block;
        height: 30px;
        width: 250px;" />
They now look pretty similar, but IE puts a white border inside the CSS border. It's hidden when the button is focused. Opera still shows focus with a thin dark border (no dotted frame). The good news is that the colors and the sizes are the same. Let's see if we can get rid of the white border in IE by removing the background-image:
<input type="button"
    value="Button with full styling"
    style="color: #fff;
        padding: 2px 5px;
        border: 2px solid;
        border-color: #7bf #07c #07c #7bf;
        background-color: #09f;
        font-family: Georgia, ..., serif;
        font-size: 18px;
        display: block;
        height: 30px;
        width: 250px;" />
Ok, this may be the best cross-browser we can do right now, without scripting and CSS hacks. There is one other thing we can do though. With the dynamic pseudo classes in CSS we can get a mouseover effect, but only in Firefox and Opera. IE doesn't support the pseudo classes in CSS2 for other elements than hypertext links – the a tag with the href attribute set. By putting the input tag in an a tag we can get the desired effects:
<a href="javascript: void(0)" >
<input type="button"
    value="Button with full styling"
    class="dynamic_button" /></a>
I move the styling to the head of the document:
#dynamic_button {
    color: #bdf;
    padding: 2px 5px;
    border: 2px solid;
    border-color: #7bf #07c #07c #7bf;
    background-color: #09f;
    font-family: Georgia, ..., serif;
    font-size: 18px;
    display: block;
    height: 30px;
    width: 250px;
    }
Then I add style declarations for input tags nested in a tags. With the CSS pseudo classes I can get some dynamic behavior:
a:active *.dynamic_button {
    color: #fff;
    border-color: #07c #7bf #7bf #07c;
    }
a:focus *.dynamic_button {
    color: #fff;
    border-color: #07c #7bf #7bf #07c;
    }
a:hover *.dynamic_button {
    color: #fff;
    }
a:link, a:visited, a:active, a:hover {
    text-decoration: none;
    }
Now we have a proper form button that looks nearly the same in the three browsers, and they even have a mouseover effect again. With the button tag you can have more styling freedom for the button label. The look can be achieved with just a hypertext link (more about this below), but then we miss out on the special features of the form buttons (the button tag and the input tag of the types button, reset, and submit). It's possible to submit a form with a hypertext link (or ant element for that matter), but only if javascript is turned on in the client browser. These users need the proper form buttons described in this document.

To get pixel perfect styling, that looks exactly the same in major browsers, you should probably opt for the alternative approach – links styled as buttons using CSS (with some optional behavior added with javascript). Most of the form button's looks (and some behavior) may be implemented using a few CSS properties and dynamic pseudo properties (:active :hover :focus). Some additional behavior can be added with a few lines of javascript. With a decent button script you can also separate content, styling, and behavior completely, and have a graceful degradation (to simple hypertext links or form buttons respectively) in older browsers or browsers with scripting turned off. One way to get the best of two worlds is to have a script tag create a link styled as a button, and a noscript tag with a (styled) button (or input) tag for users that can't handle javascript. This is the way Blogger.com does it on their login page. More about links styled as buttons later...