Web developers loathe the task of building forms almost as much as users loathe having to fill them in. These are both unfortunate facts of the Web, but some smart JavaScript and intelligent CSS can go a long way to remedying the situation. In this article, I’ll introduce a number of simple tricks for improving the usability of forms, and hopefully inspire you to improve on them and create your own.
I’m going to start off with some simple tricks, before introducing the interesting stuff later on. If the material seems too simple for you, feel free to skip ahead.
It’s the Little Things that Count
You will certainly have encountered our first trick before; it’s used by Google, the world’s most popular search engine. Whenever you load up www.google.com, your cursor jumps straight to the search box, ready for you to enter your query. It happens so fast you may not even have thought about it, but, in fact, it works equally well in any situation in which the primary purpose of a page is to fill in a form. It can be done in a number of different ways, each of which assumes that the form element you want to focus on has an id attribute set to “myfield”:
<body onload="document.getElementById('myfield').focus()">
This is, more or less, the method used by Google. It’s short and to the point. It does, however, require the addition of an onload to your body element, which some people find unsightly.
<script type="text/javascript">
window.onload = document.getElementById('myfield').focus;
</script>
This can be added to any point in your HTML file, or hidden away in an external script. If you’re going to be using a lot of JavaScript on a page, it can make sense to move it all in to an external script file in order to keep the JavaScript code separate from your HTML. This method has the disadvantage that you can only assign one thing to the window.onload
event at a time.
<script type="text/javascript">
addEvent(window, 'load', function() {
document.getElementById('myfield').focus()
});
function addEvent(obj, evType, fn){
if (obj.addEventListener){
obj.addEventListener(evType, fn, true);
return true;
} else if (obj.attachEvent){
var r = obj.attachEvent("on"+evType, fn);
return r;
} else {
return false;
}
}
</script>
This uses Scott Andrew’s addEvent
function, which I discussed in my previous article. This is probably the best approach to take if you’re keeping your code in a separate file, as it will allow other functions to be attached to the onload event as well.
<script type="text/javascript">
document.getElementById('myfield').focus();
</script>
The above will only work if it is placed in the HTML source code some point after the input field. This can be useful if you are working with a server side templating system that makes it difficult to add code directly to the top of a document — for example, if you are including the top part of the page using a server side include.
The above four options are available for most of the tricks I’ll demonstrate in this article. For future tricks, I’ll demonstrate the method using inline attributes such as onload and onclick only, but you should be aware that there are several ways to skin this particular cat.
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.
Enhancing Text Entry Fields
The most common form field is <input type="text">
. We’ve already seen how auto-focusing on this when the page loads can make a nice enhancement. A useful trick for fields containing a default value that needs to be changed is the following:
<input type="text" name="myfield" id="myfield" size="30"
value="This should be changed"
onfocus="this.select()">
When the field receives the focus, the text inside it will be instantly selected; it will be over-written the moment the user starts to enter their own text. This is also useful if the user is likely to copy and paste the text from the widget, as it saves them from having to first select it.
Here’s a nice trick for forms that are being used to create something that has an obvious title — for example, an email, or an article on a Website:
<input type="text" name="title" id="title" size="30"
onkeyup="document.title = 'New item: ' + this.value">
This creates an effect similar to many popular email programs, where the text in the title bar of the document changes as the subject of the email is typed. This could be particularly useful in an environment where multiple windows are likely to be open at once — a Webmail client, for example.
On a related note, sometimes the value of one form field can by initially guessed by looking at the value of another. A classic example is a content management system where each entry has a human readable title and a unique URL. The URL can default to matching the title, but with punctuation removed and spaces converted to underscores. Here’s the code to do that:
<input type="text" name="title" id="title" size="30"
onkeydown="document.getElementById('url').value =
this.value.replace(/[^a-z0-9 ]/ig,
'').replace(/ /g, '_')">
<input type="text" name="url" id="url" size="30">
The critical thing here is that the user can still over-ride the guessed value for the URL if they want to by entering text directly in the field. If you just want to create a URL from a title without any intervention from the user, it’s best to do so in the server side code that processes the form.
Validation
Client side form validation is one of the most popular uses of JavaScript. Before we go on, I’d like to point out that if you’re building a server side application you should always check that data is valid in your server side code, whether or not you have used client side validation. Not doing this can leave your application wide open to all manner of unpleasant security problems — remember, malicious attackers know how to disable JavaScript in their browser. This point cannot be stressed enough. We now return to our regular scheduled programming…
Validation is a big topic, and one that has been covered extensively in tutorials all over the Web. Rather than rehash old ideas, I’m going to focus on a more usable way of validating user input. For instant feedback to the user, how about displaying an icon next to each form field that indicates whether or not that field has been correctly completed? Such an icon can be hooked straight in to the label elements we added earlier, and changed by using JavaScript to alter the label element’s class attribute.
Here’s a simple example for a required form field, broken down in to the CSS, the JavaScript and the HTML:
<label for="subject" class="required">Subject:</label>
<input type="text" id="subject" name="subject" size="40"
onblur="checkRequired('subject');">
This is simple enough. The label element starts off with a class of “required” to visually indicate that the field is a required field. The JavaScript function checkRequired('subject')
is called onblur, which refers to the point at which the focus moves away from the field.
<style type="text/css">
label {
padding-left: 22px; /* To leave room for the icon */
}
label.required {
background-image: url(required.gif);
background-repeat: no-repeat;
background-position: 3px 0px;
}
label.problem {
background-image: url(caution.gif);
background-repeat: no-repeat;
background-position: 3px 0px;
}
label.completed {
background-image: url(complete.gif);
background-repeat: no-repeat;
background-position: 3px 0px;
}
</style>
The CSS gives each label a left padding of 22 pixels. The icons we’ll use will each be 15×15, which gives us a little room to spare. Special classes of required, problem and completed are defined, each with their own background icon positioned to appear in the padding to the left of the form text.
<script type="text/javascript">
function getLabelForId(id) {
var label, labels = document.getElementsByTagName('label');
for (var i = 0; (label = labels[i]); i++) {
if (label.htmlFor == id) {
return label;
}
}
return false;
}
function checkRequired(id) {
var formfield = document.getElementById(id);
var label = getLabelForId(id);
if (formfield.value.length == 0) {
label.className = 'problem';
} else {
label.className = 'completed';
}
}
</script>
Here, we define two JavaScript functions: one to find the label associated with a specific ID, and another, which checks that a specified form field has something in it, and sets the associated label’s class accordingly. This is the simplest possible case for validation; additional functions can be written to cope with problems such as checking that email addresses are in a useful format. This technique could be taken even further by disabling the submit button until all the form fields have been correctly completed; however, if this is done, it is vital that the initial disabling of the submit button take place in the JavaScript, to ensure that non-JavaScript enabled browsers can still use the form.
The last trick I will introduce revolves around data that has a very specific format. Rather than reject a user’s input if it doesn’t match the format rules perfectly, it is sometimes possible to reformat the user’s data once they have entered it. A classic example is a form field for accepting US phone numbers. US phone numbers, when the area code is included, are exactly 10 digits long. The traditional way of displaying them is (785) 555-5555. Using JavaScript, we can take the user’s input, strip out all non-digit characters and, provided we are left with 10 digits, reformat them to look like the above example:
<script type="text/javascript">
function checkPhone() {
var phone = document.getElementById('phone');
var label = getLabelForId('phone');
var digits = phone.value.replace(/[^0-9]/ig, '');
if (!digits) {
return;
}
if (digits.length == 10) {
phone.value = '(' + digits.substring(0, 3) + ') ' +
digits.substring(3, 6) + '-' +
digits.substring(6, 10);
} else {
phone.value = digits;
}
}
</script>
<label for="phone">Phone Number:</label>
<input type="text" id="phone" name="phone" size="20"
onblur="handlePhone();">
This technique can be taken even further to allow multiple ways of entering structured data, such as a date, with any recognised values being converted to a standard format. My better date input script does exactly that, and I recommend you check out the source code to see exactly how it works.
To better illustrate the ideas in this article, I’ve put together this simple form that demonstrates some of the techniques introduced. I hope I’ve inspired you to think about new ways of improving your form’s usability using JavaScript and CSS.
Frequently Asked Questions (FAQs) about Usable Forms
What are the key elements to consider when designing a usable form?
When designing a usable form, it’s crucial to consider several key elements. Firstly, simplicity is key. The form should be as straightforward as possible, with clear, concise instructions. Secondly, the form should be intuitive. This means that the user should be able to understand what is required of them without needing to read extensive instructions. Thirdly, the form should be user-friendly. This means that it should be easy to navigate, with clear, easy-to-read fonts and colors. Lastly, the form should be responsive. This means that it should work well on all devices, including mobile phones and tablets.
How can I make my form more user-friendly?
There are several ways to make your form more user-friendly. Firstly, you can use clear, concise language. Avoid using jargon or technical terms that your users may not understand. Secondly, you can use visual cues to guide your users. This could include things like arrows or highlighted fields. Thirdly, you can provide helpful error messages. If a user makes a mistake, your form should provide a clear, helpful message that explains what went wrong and how to fix it.
What is form validation and why is it important?
Form validation is a process that checks the data entered into a form to ensure it meets certain criteria. This could include checking that an email address is in the correct format, or that a password meets certain security requirements. Form validation is important because it helps to ensure that the data collected is accurate and reliable. It also helps to protect your form from spam and other malicious activity.
How can I make my form more accessible?
Making your form accessible means ensuring that it can be used by as many people as possible, including those with disabilities. This could include things like using large, easy-to-read fonts, providing alternative text for images, and ensuring that your form can be navigated using a keyboard. You should also ensure that your form is compatible with screen readers and other assistive technologies.
What is the role of color in form design?
Color plays a crucial role in form design. It can be used to guide the user’s eye, highlight important information, and convey meaning. For example, red is often used to indicate an error, while green is used to indicate success. However, it’s important to remember that not everyone perceives color in the same way, so you should also use other cues, such as icons or text, to convey information.
How can I ensure that my form is mobile-friendly?
Ensuring that your form is mobile-friendly is crucial in today’s increasingly mobile world. This means that your form should be responsive, meaning that it adjusts to fit the screen size of the device it’s being viewed on. You should also ensure that your form is easy to navigate on a small screen, with large, easy-to-tap buttons and fields.
What is the importance of form testing?
Form testing is a crucial part of the design process. It involves testing your form with real users to identify any issues or areas for improvement. This could include things like usability issues, confusing instructions, or technical glitches. By testing your form and making necessary adjustments, you can ensure that it is as user-friendly and effective as possible.
How can I reduce form abandonment?
Form abandonment occurs when a user starts filling out a form but doesn’t complete it. There are several strategies you can use to reduce form abandonment. Firstly, you can make your form as simple and straightforward as possible. Secondly, you can provide clear, helpful error messages. Thirdly, you can use progress indicators to show users how much of the form they have completed and how much is left.
What is the role of feedback in form design?
Feedback is a crucial part of form design. It involves providing users with clear, immediate feedback on their actions. This could include things like highlighting fields that have been filled out correctly, providing error messages for fields that have been filled out incorrectly, and providing a confirmation message once the form has been submitted. Feedback helps to guide users through the form and makes the process more user-friendly.
How can I design a form that is both user-friendly and secure?
Designing a form that is both user-friendly and secure can be a challenge, but it’s crucial for collecting accurate, reliable data. To achieve this, you can use form validation to check the data entered into your form. You can also use secure protocols, such as HTTPS, to protect the data as it’s being transmitted. Additionally, you should ensure that your form is accessible and easy to use, with clear, concise instructions and helpful feedback.