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.
Designer, developer and a passionate standardista. Long time web professional with huge experience in all types of front-end work. Founder of Css Globe and creator of
dappleyard on 10 Sep, 2008 wrote:
Eric Fields on 10 Sep, 2008 wrote:
This would be really simple in jQuery. Off the top of my head, and not without further tweaking and optimization, you could do this in jQuery by something like the following:
$('form input[type="text"]').each(function(){
var theLabel = $(this).prev('label');
// Probably check to see if there's no value and then do the following
$(this).attr('value',theLabel.html());
// Regardless, then you want to hide the label:
theLabel.hide();
});
cssglobe on 10 Sep, 2008 wrote:
Nacho on 10 Sep, 2008 wrote:
I have a suggestion though.
How about applying the class "inside" for those labels, and the js just applies that to labels having the .inside class?
I think it would be better for people like me that don't know much js.
Nacho.
Dainis Graveris on 11 Sep, 2008 wrote:
Felipe Uribe on 7 Oct, 2008 wrote:
one question yet, i might be off but you said it was for a newsletter, but as i understand javascript doesn't works the most of the times on email clients. so, can you use it or not?
as i said i might be off but...
thanks
Gabe on 8 Nov, 2008 wrote:
Lush on 5 Dec, 2008 wrote:
Thanks.
Andrea on 9 Jan, 2009 wrote:
Zoran on 19 Feb, 2009 wrote:
Following code should be applied to INPUT tag:
<input name="Search" onfocus="if (this.value == 'Input text') this.value = '';" onblur="if (this.value == '') this.value = 'Input text';" value="Input text" type="text">
Igor on 15 Apr, 2009 wrote:
Jonas Wagner on 16 Apr, 2009 wrote:
Another issue is that when the form is submitted, the fields keep the values from their labels. This makes form validation quite a difficult task (your labels might be I18n'ized, etc...)
I wrote some code which fixes the issue, available for some time at http://www.pastie.org/447497
The code uses Prototype instead of JQuery, but is otherwise very similar to the code presented here. It works for normal forms and for forms submitted using Ajax. Finally, the labels are styled only if they're of class "inside" (thanks Nacho).
Kyle Rush on 1 May, 2009 wrote:
http://github.com/alexrabarts/jquery-clearinginput/tree/master
This is an otherwise great script. Thanks for sharing.