posted on:September 10, 2008
Using form labels as text field values
When designing you sometimes have limited space to put and display all of the form elements. Recently that happened to me and when I was trying to squeeze in a simple newsletter form to a 120px wide area (plus a limited height). I realized that some of the elements will have to go. The obvious solution was to get rid of the labels and put only the form text fields. How will the users know what are the text fields for? I will use value attributes and write the explanation in there, something like "Input your email here". Problem solved? Not quite. Why? Because I am a web standards freak
Take a look at the demo
| Download zip file

The problem
Let’s rethink what I just did. I placed a sentence "Input your email here" as a text field value by adding it to the VALUE attribute. Why is that wrong? The VALUE attribute of the INPUT tag should be used as a default value of the text field, not as a text field’s description. The sentence I used is clearly a description and it should be used as a label (of course using LABEL tag). The correct way to use VALUE attribute for text fields is to input something meaningful, something that user might actually write himself (or herself). i.e. if you are logged in as member here on Css Globe and you wish to comment, you will notice that your email is set as a default value of an email text field in the comment form.
How will I find semantically correct way to place the labels (descriptions) into text field? JavaScript of course. It will help me to move stuff around without jeopardizing accessibility. Remember, the aim here is to have meaningful and accessible html code plus to have a usable form that fits the provided design.
Let’s begin with markup. It should look something like this:
<form id="contactForm" action="/" method="post">
<fieldset><legend>Contact Form</legend>
<p>
<label for="contact_name">Input your name here</label>
<input type="text" name="contact_name" id="contact_name" value="" size="30" />
</p>
<p>
<label for="contact_email">And email address please</label>
<input type="text" name="contact_email" id="contact_email" value="" size="30" />
</p>
<p>
<label for="contact_message">Send us a couple of words</label>
<textarea id="contact_message" name="contact_message"></textarea>
</p>
<p class="submit">
<button type="submit" title="Send your message">Send!</button>
</p>
</fieldset>
</form>
LABEL tags must have FOR attributes defined otherwise they don’t make much sense plus this script won’t work
The final design looks like this:

Time to move it to the script. When dealing with this issue I came up with the script that automatically searches for LABEL tags, finds related INPUT (includes only text fields) based on a definition of FOR attributes and inputs the LABEL tag’s content into the text field using VALUE attribute. How’s that different from the straightforward non-semantic solution from the beginning of this article, you’ll say… Well, take a look at the form markup again. This form is accessible and semantically correct to begin with. JS disabled browsers will still have meaningful interpretation of this form.
Lets see the script already
This is and unobtrusive JavaScript code powered by fabulous jQuery. You don’t have to understand jQuery to use this form (but still this script requires it), I will try to explain each line. Here’s the entire thing:
this.label2value = function(){
var inactive = "inactive";
var active = "active";
var focused = "focused";
$("label").each(function(){
obj = document.getElementById($(this).attr("for"));
if(($(obj).attr("type") == "text") || (obj.tagName.toLowerCase() == "textarea")){
$(obj).addClass(inactive);
var text = $(this).text();
$(this).css("display","none");
$(obj).val(text);
$(obj).focus(function(){
$(this).addClass(focused);
$(this).removeClass(inactive);
$(this).removeClass(active);
if($(this).val() == text) $(this).val("");
});
$(obj).blur(function(){
$(this).removeClass(focused);
if($(this).val() == "") {
$(this).val(text);
$(this).addClass(inactive);
} else {
$(this).addClass(active);
};
});
};
});
};
$(document).ready(function(){
label2value();
});
As you may notice from the code I have added css classes and attached some behavior to the fields to make a complete solution. Let’s take it step by step.
$(document).ready(function(){
label2value();
});
This initiates the script called label2value (that’s our script here
) on page load using jQuery’s $(document).ready function. First lines in our function:
var inactive = "inactive"; var active = "active"; var focused = "focused";
define the variables containing class names that we will use to style 3 states of the text field or text area:
- Inactive state – default state with no input from the user. With this state the label text inside the text field is used.
- Active state – when user provides some input and clicks away from the text field (on blur)
- Focused state – when user clicks on the field (on focus)
Classes should be styled to your preferences, in external css file or inside a STYLE tag on the document.
Moving on:
$("label").each(function(){
obj = document.getElementById($(this).attr("for"));
if(($(obj).attr("type") == "text") || (obj.tagName.toLowerCase() == "textarea")){
These lines basically select each LABEL tag and find matching text field or textarea based on the FOR attribute of the LABEL tag.
$(obj).addClass(inactive);
var text = $(this).text();
$(this).css("display","none");
$(obj).val(text);
Then it assigns default state class name to the text field, hides the label, gets the text from the label and puts it into text field.
$(obj).focus(function(){
$(this).addClass(focused);
$(this).removeClass(inactive);
$(this).removeClass(active);
if($(this).val() == text) $(this).val("");
});
On focus function (when user clicks on the text field) changes the class name and if the user haven’t provided any text, it clears the field.
$(obj).blur(function(){
$(this).removeClass(focused);
if($(this).val() == "") {
$(this).val(text);
$(this).addClass(inactive);
} else {
$(this).addClass(active);
};
});
On blur function (when user clicks out from of field) checks if user has provided some input and if so it assigns active class name. If user left the field blank, script switches back to default mode with initial text and initial (inactive) class name.
See this script in action or download the package.
Enjoyed the article?
Then don't miss our next one! Subscribe to our RSS feed or share it with your friends.
Share on FacebookTweet thisDeliciousStumbleUpon RedditSubscribe
Comments (13 Comments)
Sorry, the comment form is closed at this time.
dappleyard
September 10, 2008
Eric Fields
September 10, 2008
cssglobe
September 10, 2008
Nacho
September 10, 2008
Dainis Graveris
September 11, 2008
Felipe Uribe
October 7, 2008
Gabe
November 8, 2008
Lush
December 5, 2008
Andrea
January 9, 2009
Zoran
February 19, 2009
Igor
April 15, 2009
Jonas Wagner
April 16, 2009
Kyle Rush
May 1, 2009