Article
Simple Tricks for More Usable Forms
Labels
The quickest way to enhance your form usability is to add labels, if you're not using them already. The <label> element has been part of HTML since 1998, but many developers remain unaware of its existence. It allows you to logically relate the text describing a form field to the form field itself. When the user clicks on the label, the browser will move the focus to the related form field, or toggle its state in the case of radio boxes and check buttons. Before you add a label, the form field must have an ID attribute set. In fact, the tips in this article almost all require an ID attribute be set on the form field, as this provides a useful means of targeting that field from JavaScript.
Here's the simplest example of a label in action:
<label for="username">Username:</label>
<input type="text" name="username" id="username" size="10">
Clicking on the word "Username" will focus the cursor in the text box. This may not seem like a particularly useful effect, but it gives us a useful hook for styling and potentially adding extra JavaScript behaviour. It also dramatically improves the accessibility of the form for users of assistive software.
Where labels really come in to their own is with checkboxes and radio boxes. Both these widgets are plagued by a tiny active area, sometimes called a "hotspot", which you need to hit dead on with your mouse to cause them to toggle. Adding a label increases the hotspot to cover the text associated with the widget as well:
<input type="checkbox" name="accepted" id="accepted">
<label for="accepted">I agree to the terms and conditions</label>
Of course, labels aren't much good if people don't know they're there. One simple but effective trick for increasing the visibility of labels is to use CSS to change the cursor over them:
<style type="text/css">
label {
cursor: pointer;
cursor: hand;
}
</style>
Why the two cursor declarations? The CSS standard dictates "pointer" as the value for a "pointer that indicates a link". Unfortunately, IE 5 and IE 5.5 for Windows don't understand this value, using "hand" to mean the same thing. By placing pointer first misbehaving Microsoft browsers ignore it and use the hand value, while better behaved browsers take pointer and ignore hand.
Visual Hints
In a large form, it can be easy to lose track of the form field you're currently filling in. A great trick for helping out is the following:
<style type="text/css">
input {
border: 2px solid #ccc;
}
input:focus {
border: 2px solid #000;
}
</style>
This causes all input fields to have a 2 pixel wide gray border, while the input field on which the user is currently focused gets a black border to make it stand out from the others. There's one caveat: IE on Windows doesn't support the :focus pseudo-class! Thankfully, it's possible to replicate the effect using JavaScript:
<input type="text" name="myfield" id="myfield"
onfocus="this.style.border='2px solid #000'"
onblur="this.style.border='2px solid #ccc'">
This brings the effect to IE, at the expense of a lot of extra typing. If you've got a lot of form fields on the page, it makes sense to do this instead, again making use of the addEvent function introduced above:
<script type="text/javascript">
addEvent(window, 'load', function() {
var input, textarea;
var inputs = document.getElementsByTagName('input');
for (var i = 0; (input = inputs[i]); i++) {
addEvent(input, 'focus', oninputfocus);
addEvent(input, 'blur', oninputblur);
}
var textareas = document.getElementsByTagName('textarea');
for (var i = 0; (textarea = textareas[i]); i++) {
addEvent(textarea, 'focus', oninputfocus);
addEvent(textarea, 'blur', oninputblur);
}
});
function oninputfocus(e) {
/* Cookie-cutter code to find the source of the event */
if (typeof e == 'undefined') {
var e = window.event;
}
var source;
if (typeof e.target != 'undefined') {
source = e.target;
} else if (typeof e.srcElement != 'undefined') {
source = e.srcElement;
} else {
return;
}
/* End cookie-cutter code */
source.style.border='2px solid #000';
}
function oninputblur(e) {
/* Cookie-cutter code to find the source of the event */
if (typeof e == 'undefined') {
var e = window.event;
}
var source;
if (typeof e.target != 'undefined') {
source = e.target;
} else if (typeof e.srcElement != 'undefined') {
source = e.srcElement;
} else {
return;
}
/* End cookie-cutter code */
source.style.border='2px solid #ccc';
}
</script>
The cookie-cutter code in the above deals with some cross-browser compatibility annoyances, and is discussed in my previous article.