Custom image form submit buttons - What is the correct approach?
Clients, those crazy people, sometimes they get these funny little ideas like: hey wouldn’t it be neat if the form buttons looked like {insert cliche web2.0 button style here}:. My initial answer to this is that the UI the browser creates for you is the most usable and least likely to create problems across different browsers and platforms
This being said, it is still often necessary to alter form UI elements to create branding/look and feel consistency throughout a given site or web application.
Input Type = Image
The most obvious and common method for changing the look of a submit button is by using an input of type "image". This is a good solution and is valid xhtml (even with strict doctypes).
<form>
<input src="/assets/img/image_submit/something_btn.gif" name="foo"
value="bar" type="image">
</form>
We are done here right? Wrong. Enter our good friend IE6. IE6 has the odd behavior of not passing along the name/value pair declared on the input. In most web browsers, when we submit the form above we would be passing along a name of "foo" and a value of "bar" in the post array. Depending on which server side technology being used, that name and value pair may be of importance to you! The work around, if that is the case, is to put a hidden input element into your form like so:
<form action="">
<input type="image" name="foo" value="bar" src="/demo/something_btn.gif" />
<input type="hidden" name="foo" value="bar" />
</form>
I don't know about you, but this just doesn't sit well with me. Call me picky, but extraneous form elements just should not be necessary for your application to work properly. Before we get to the better solution also take note that IE5 and IE5.5 both do not even submit a form at all using input type image. Javascript can be used as a workaround in that case, but who wants to tie the usability of their entire application to whether a given person has javascript enabled or not - that is just bad design.
Enter the Button Tag
Straight from the W3C page on the button tag:
"Defines a push button. Inside a button element you can put content, like text or images. This is the difference between this element and buttons created with the input element."
Image form submitting - this is the button tag's purpose in life. All we do is put a regular old image tag within the button of type submit and... viola!
Note that an alt tag on the image is absolutely essential. If the user were to have images disabled and there was not an alt text on the image, they would be left with a less than usable form.
<form action="">
<button type="submit" name="foo" value="bar">
<img src="/assets/img/image_submit/something_btn.gif" alt="Something!" />
</button>
</form>
Wait a minute you say... that doesn't look good AT ALL.
CSS to the Rescue
By default the browser tries to make a button look like, well, a button. Let's strip out all that default button style nonsense and let our custom pixels shine.
<form>
<button class="custombutton" type="submit" name="foo" value="bar">
<img src="/demo/something_btn.gif" alt="Something!">
</button>
</form>
<!-- this would go into an external css file normally -->
<style type="text/css" media="screen">
.custombutton {
padding: 0;
margin: 0;
border: none;
background: none;
cursor: pointer;
}
/* alternate cursor style for ie */
* html .custombutton { cursor:hand; }
</style>
There... that is better.
Clearing padding, margin, border, and background takes care of all the default browser button stylings. Setting the cursor to pointer is necessary to ensure you get the hover effect. I also like to treat IE6 and under like the special child it is by giving it its little hand styled pointer.
This method is usable on all browsers except for the truly ancient ones that we don't care about (gen 4 and lower) and solves the custom submit button problem. In IE6 the button tag actually passes along its "name" property, but our special friend still get its wrong by passing along the actual contents (inner HTML) of the button tag rather than the "value" property (but hey, at least you get something). And finally, to top it all off, it validates in XHTML 1.0 strict.