jQuery Inline Form Labels
I’ve been seeing the trend of applying inline labels on form elements more and more these days. So I definitely needed to come up with a solid solution that would help me easily apply this effect.
Maybe I need to explain a little better what I am referring to. Instead of using a label that is next to or above the input element, the label is actually within the input. Then, when the input is focused, the label goes away and you can enter your value into it. Finally, when the input is no longer focused, if there is no value entered, the inline label is then added back in.
My Solution
The title attribute.
It’s so simple, but perfect. A great benefit of using the title attribute, is that when you hover over the input, you get a little tooltip displaying the inline label. So all I need to do is add a title attribute with the text that we want to have show up as the inline label. Then, we just use a little jQuery to make it all happen.
The jQuery
First, we want to select each input that has a title attribute, once the document is loaded:
$(document).ready(function() {
$('input[title]').each(function() {
…
});
});
Next, if the value of the input element is empty, we want to take the title attribute and add it as the value of the input.
$(document).ready(function() {
$('input[title]').each(function() {
if($(this).val() === '') {
$(this).val($(this).attr('title'));
}
});
});
After that, we want to setup a function that will fire once the input is focused. When it is focused, if the value is equal to the title attribute, we want to set the value to nothing and add a class of focused:
$(document).ready(function() {
$('input[title]').each(function() {
if($(this).val() === '') {
$(this).val($(this).attr('title'));
}
$(this).focus(function() {
if($(this).val() === $(this).attr('title')) {
$(this).val('').addClass('focused');
}
});
});
});
The reason why we add the class of focused is so that we can change the text color, border or anything to make it noticeable that the input is being focused. You can see this effect in the demo.
Finally, we want to add a function that will fire when the input loses focus. When it does, if the input value is empty, we want to set the value back to the title attribute and remove the class of focused:
$(document).ready(function() {
$('input[title]').each(function() {
if($(this).val() === '') {
$(this).val($(this).attr('title'));
}
$(this).focus(function() {
if($(this).val() === $(this).attr('title')) {
$(this).val('').addClass('focused');
}
});
$(this).blur(function() {
if($(this).val() === '') {
$(this).val($(this).attr('title')).removeClass('focused');
}
});
});
});
And that’s it. It’s just a little bit of code, but it can go a long way. So take it and build on it.








check also jQuery.fieldtag.js: http://ajaxcssblog.com/jquery/fieldtag-watermark-inputfields/
Nice idea.
I would add real label elements as well. You can then position those labels off screen with jQuery. That way you have an accessible form that still makes sense when js is not available.
First, good job on explaining the steps to building this, they are really well written.
I’ve been using the jQuery example plugin to do something similar but you have to specify each input field in the JS. Your method using the title attr’ is great and I’ll definitely be using this sort of method in the future.
Thanks for posting.
:)
Agreed; this is a cool technique but I’d prefer using the element over the input title for accessibility and semantics.
@Joost-
Absolutely. I would recommend using a regular label as well. Just wanted to focus everyone on the task at hand.
@Benjamin Reid-
Excellent, glad you found it useful.
@Andy Pemberton-
Yeah, I would use both.
Thanks I’ll be using this!
Thanks Trevor! I do a lot of form design and have been looking for something like this. Many scripts I come across seem way too large to accomplish something simple. You’ve done it it a clean, concise manner.
Looks good. Thanks for sharing!
This is a great technique, but what do you do when you need the field to be “required”? Since there is already text in the field it will pass validation. I’m really hoping you have an answer because it’s what’s kept me from using this idea in past situations.
Thanks for sharing!
@Jules-
You will just need to change your validation rules so that it would use JavaScript on submit to check to see if the value is equal to the title attribute.
I think most of us end up doing something similar. The only difference in mine is I invert your ‘class’ usage. Instead of toggling a ‘focus’ class which is set when the element is focused, I toggle an ‘inlinetip’ class which is set only when the tip is being displayed.
That way, I can strip off the values of any element with class ‘inlinetip’ at submission (and immediately re-add it if it’s an AJAX submit).
That said, I’ve considered doing something fancy like overlaying a div above the element with the title-tip. That way you don’t have to deal with ‘data-fixup’ at all. Hmm… perhaps that’s an idea for my first ‘real’ jquery plugin :)
Try using the input’s defaultValue property instead, then there’s no need to rely on title.
$(‘input’).get(0).defaultValue
@Brian Cray-
I’m not sure what you mean. So are you saying to add the value attribute to the input? I was trying to avoid that.
Trevor: Do you mean you were trying to avoid:
Retyping with encoding:
<input type=”text” value=”value that will erase on focus />
@Brian Cray-
Correct, I do not want to add the value into the actual HTML.
ahhh… okay, didn’t realize that sorry
It’s a nice approach, but I need to make sure that a) required fields don’t have the default text and b) the optional fields are reset to blank on submit.
I know you said to Jules that we’ll need to change our JavaScript validation rules to cater for this stuff. That’s not a problem, but really we need to modify our server side validation as well, which makes it a little more complicated.
I’m thinking about clever ways to do this – perhaps assign the descriptions to variables, then use them in both processing the _POST values and in generating the form…
Anyway, thanks!
GREAT example! Thanks for sharing!
Admirable your explanation, I like your style of describing things. I suggest this code reformulation:
Thanx your work. good src!
Good idea, I will use it in my project!
why all that code when you can just add a form value and:
onclick=”this.value=” ”
No Jquery or anything else needed..just one line of code in the form.
Am I missing something here??
@omar-
Whenever you use JavaScript, you should use it unobtrusively. You should always separate the behavior layer from the content layer.
@Trevor, this is a simple piece of code. Just getting into jQuery, and was able to easily adjust this to work with a textarea object.
Thanks for the simple walk through!
@Matt Richardson-
Excellent, glad you were able to figure out how to adjust it on your own!
how would you keep the label being passed as the field value on form submit?
@Eric-
I guess you would have to account for it in the JavaScript validation.
A simple and perfect solution. Instead of add a class to focused input, you can use the css atribute :focus.
Awesome; But how do you handle passwords and password confirmation fields?
@Mark-
You would have to modify the code so that you copy a password field as a regular text field and show that. Then on focus, you want to hide the text field and show the password field.
Trevor this was a very useful bit of code–thank you for sharing! I implemented it and it worked great.
One thing I discovered later, though: HTML 5 supports an attribute called “placeholder” that does the same thing as your jQuery code. Of course, your approach works in all browsers that support jQuery; currently, only the latest versions of Safari and Chrome support the “placeholder” attribute.
Here are the details:
http://www.whatwg.org/specs/web-apps/current-work/multipage/common-input-element-attributes.html#the-placeholder-attribute
@Scott Bush-
Yep, I have seen the placeholder attribute. I have actually started to shy away from this type of inline label because then you have to deal with validating the data. I have actually started absolutely positioning the labels on top of the input field and hiding it when it’s been clicked.