CSSKarma

display your <style>

designing the web since 2002

Form Design with Sliding Labels

Sliding Label banner

Please use version 3 of sliding labels with updated options and bug fixes at: http://www.csskarma.com/blog/sliding-labels-plugin/

A few weeks ago I was reading an article on form UI by Luke Wroblewski of Yahoo!. For those who aren’t familiar with Luke, he (quite literally) wrote the book on good form design.

In the article, one certain section about placing labels inside of form fields stood out to me:

Because labels within fields need to go away when people are entering their answer into an input field, the context for the answer is gone. So if you suddenly forget what question you’re answering, tough luck—the label is nowhere to be found. As such, labels within inputs aren’t a good solution for long or even medium-length forms. When you’re done filling in the form, all the labels are gone! That makes it a bit hard to go back and check your answers. Luke Wroblewski

He brings up a good point. Generally speaking, you can look at a field that says “Tim Wright” and know that it was a field for your (my) name. But for long forms, yea, I do agree that you can forget some of the questions you answered.

For best practice, Luke talks about leaving your labels outside the form field so it’s always available to the user. I do think it’s a pretty good solution, but I think we can get a little more creative than that.

Enter: Sliding Labels

After reading that article it occurred to me that there’s no reason we can’t have the best of both worlds. I like how inline labels look, and I see Luke’s point about them disappearing as you fill out the form. But, we have jQuery, we know about progressive enhancement, and we have creative minds, so let’s build something that allows us to keep the label inline, but slide it off to the left (or up, whichever you prefer) rather than going away on click.

View demo (version 2)

The HTML

<form action="" method="post" id="info">
   <h2>Contact Information</h2>
   <div id="name-wrap" class="slider">
      <label for="name">Name</label>
      <input type="text" id="name" name="name">
   </div><!--/#name-wrap-->

   <div id="email-wrap"  class="slider">
      <label for="email">E&ndash;mail</label>
      <input type="text" id="email" name="email">
   </div><!--/#email-wrap-->

   <div id="street-wrap"  class="slider">
      <label for="st">Street</label>
      <input type="text" id="st" name="st">
   </div><!--/#street-wrap-->

   <div id="city-wrap"  class="slider">
      <label for="city">City &amp; State</label>
      <input type="text" id="city" name="city">
   </div><!--/#city-wrap-->

   <div id="zip-wrap"  class="slider">
      <label for="zip">Zip code</label>
      <input type="text" id="zip" name="zip">
   </div><!--/#zip-wrap-->

   <input type="submit" id="btn" name="btn" value="submit">
</form>

The only necessary items to make sliding labels (as I built it) work are the wrapper element (DIV in my case) and applying a class of “slider” to it (you can change this easily in the JavaScript).

At this point we have a pretty basic, and ugly form

slidinglabels no css

The CSS

body                       { font:12px/1.3 Arial, Sans-serif; }
form                       { width:380px;padding:0 90px 20px;margin:auto;background:#f7f7f7;border:1px solid #ddd; }
div                        { clear:both;position:relative;margin:0 0 10px; }
label                      { cursor:pointer;display:block; }
input[type="text"]         { width:300px;border:1px solid #999;padding:5px;-moz-border-radius:4px; }
input[type="text"]:focus   { border-color:#777; }
input[name="zip"]          { width:150px; }

/* submit button */
input[type="submit"]       { cursor:pointer;border:1px solid #999;padding:5px;-moz-border-radius:4px;background:#eee; }
input[type="submit"]:hover,
input[type="submit"]:focus { border-color:#333;background:#ddd; }
input[type="submit"]:active{ margin-top:1px; }

The only 100% necessary CSS in there is the position:relative on the wrapper element (DIV). The rest is basically cosmetic and you can mess with it as you see fit.

At this point you should have a pretty normal looking form with labels on top of their respective inputs.

labelslider no js

The jQuery

Now for the section everyone skipped to, provided you didn’t go straight to the demo (which I usually do).

$(function(){
$('form#info .slider label').each(function(){
	var labelColor = '#999';
	var restingPosition = '5px';

	// style the label with JS for progressive enhancement
	$(this).css({
		'color' : labelColor,
		 	'position' : 'absolute',
	 		'top' : '6px',
			'left' : restingPosition,
			'display' : 'inline',
    	               'z-index' : '99'
	});

	// grab the input value
	var inputval = $(this).next('input').val();

	// grab the label width, then add 5 pixels to it
	var labelwidth = $(this).width();
	var labelmove = labelwidth + 5;

	//onload, check if a field is filled out, if so, move the label out of the way
	if(inputval !== ''){
		$(this).stop().animate({ 'left':'-'+labelmove }, 1);
	}    	

	// if the input is empty on focus move the label to the left
	// if it's empty on blur, move it back
	$('input').focus(function(){
		var label = $(this).prev('label');
		var width = $(label).width();
		var adjust = width + 5;
		var value = $(this).val();

		if(value == ''){
			label.stop().animate({ 'left':'-'+adjust }, 'fast');
		} else {
			label.css({ 'left':'-'+adjust });
		}
	}).blur(function(){
		var label = $(this).prev('label');
		var value = $(this).val();
		if(value == ''){
			label.stop().animate({ 'left':restingPosition }, 'fast');
		}
	});
})
});

At this point, you should have a fully working sliding label form!

labelslider final

View demo (version 2)

Making sure everything is still usable without JavaScript is important (no matter what people say), it’s just a basic principle of progressive enhancement. Believe it or not, there are still people browsing without JavaScript (blackberry users – turned off by default). So creating the interaction in layers, as we did, will help it be past-proof.

Try it out and let me know what you think. So far I’ve used it on a password change form, so definitely let me know if you find a place to use it!

Tags: , , ,

You can leave a response, or trackback from your own site.

« Older Comments | Newer Comments »

Comments (110)

  1. Mary Lou says:

    Not all approaches in web design need to have a rigid function. If it would be like that, we wouldn’t need any Flash, JavaScript or any other effect-based solution. I think your idea is very creative and it gives the user something to play with, some dynamic eye-candy. Beautiful!

  2. James says:

    This is a really neat idea, and executed really well. Don’t listen to the naysayers above! Having a good, intuitive and original idea on your forms can only have a positive effect.

  3. calgary web design says:

    Love these will use thanks

  4. Hi,

    This is a really cool script. I’d like to use it in a contact page on a site i’m currently working on (commercial project).

    I can provide credit in all source code.

    Will this be ok?

    Thanks,
    Conor

  5. Illidan says:

    Beautiful, thank you

  6. K says:

    Useless, it’s pretty, but it’s all it is. Just leave the labels outside of the form, since they’re going the slide there anyway, it makes the form messy when some of the fields are left blank.

  7. Alex says:

    It’s look very good. Thank you!

  8. great work, thats so pro and nice lookin. sure gonna try that in my new website.

  9. hobs says:

    I also browse with javascript off, after thinking it was such a needed component, but the truth is js opens you to so many attack vectors.
    Noscript ftw.

  10. Tinny says:

    use $(‘input,textarea’).focus(function()

    top apply this great script to textareas too

  11. Tim Wright says:

    @conor All my code is open source, feel free to use it as you see fit. Credit in the code would be fine. Let me know what you come out with, I’d love to see it in action!

    Thanks for all the comments guys, even the ones from the Trolls ;)

  12. Tinny says:

    You need another edit:

    change

    var inputval = $(this).next(‘input’).val();

    to

    if ($(this).next(‘input’).length)
    var inputval = $(this).next(‘input’).val();
    else
    var inputval = $(this).next(‘textarea’).val();

  13. Tinny says:

    Ps: it’s a great idea, Tim :)

  14. Joe R. says:

    I like the concept. Definately something that I would not use everywhere for everyone, evertime. It is something I would file under Bells and Whistles. Perfect for showing off a designers abilities or for a portfolio site, fashion, etc…. Not something I would really suggest for an e-Commerce site, depending on the products being sold. However, its really cool and I like it very much. Keep on truckin! You have a great style sense for designing.

  15. Ven Francis says:

    Perfecto! Superb! Brilliant! :D

  16. Joseph Smith says:

    Pretty cool and useless ;)

  17. Jeff W says:

    Very cool. I’m in the process of learning jQuery and I’m loving the cool things you can do with it.

  18. WebBoy says:

    I’m surprised by all the negative comments. I think this is excellent for usability and it adds a little panache to forms. Excellent!

  19. Oscar Marvier says:

    Greetings and many thanks for a well-written article. I thank you what you posted.

  20. nathan says:

    i like it, elegant, but not over the top.

  21. While this does look like an okay effect, an effect is probably the most it should be, if you can have the labels besides the input controls, why do you need to distract the user by animating them. Surely this would have a negative impact on the usage of the forms?

  22. Chris Burd says:

    I agree that it’s over the top, sorry. The precise word for it is UNMOTIVATED: having the label move from inside to outside the field doesn’t represent any event, either mental or physical.

    Also, it misses the optimal (IMO) distinction between field labels and default text. In my view, the label should be a description of the field content, while the default text should model the format.

    So you might have something like this:

    Address [123 Main Street]
    City and State [Columbus OH]
    Phone Number [999-555-1234]

    You don’t need the formatting info, but I think it’s user-friendly.

  23. Quite impressive. It may be OTT and not strictly required but any cool effect on the form can increase the completion rate, which is the ultimate target.

    Frankly I very much agree that long forms need a similar feature that reminds one of the type of data one has entered in the field.

  24. saurabh shah says:

    This is damn awesome… !!!

  25. Remus says:

    imazing i like it but a sliding must large is must :)

  26. Szenti says:

    Hi,

    Sorry for my English. I’m a webdeveloper from Hungary. Thank you for this plugin, it’s very cool. If the browser remember your password (login form with this plugin), the browser autofill the password field, and the label stay in the password field below the password text.

    I modified a little your code: $(this).stop().animate({ ‘left’:'-’+labelmove+’px’ }, 1);
    The ‘px’ string is important.

    $(function(){
    $(‘form#loginForm .slider label’).each(function(){
    var labelColor = ‘#999′;
    var restingPosition = ’5px’;

    // style the label with JS for progressive enhancement
    $(this).css({
    ‘color’ : labelColor,
    ‘position’ : ‘absolute’,
    ‘top’ : ’6px’,
    ‘left’ : restingPosition,
    ‘display’ : ‘inline’,
    ‘z-index’ : ’99′
    });

    // grab the input value
    var inputval = $(this).next(‘input’).val();

    // grab the label width, then add 5 pixels to it
    var labelwidth = $(this).width();
    var labelmove = labelwidth + 5;

    //onload, check if a field is filled out, if so, move the label out of the way
    if(inputval !== ”){
    $(this).stop().animate({ ‘left’:'-’+labelmove+’px’ }, 1);
    }

    // if the input is empty on focus move the label to the left
    // if it’s empty on blur, move it back
    $(‘input’).focus(function(){
    var label = $(this).prev(‘label’);
    var width = $(label).width();
    var adjust = width + 5;
    var value = $(this).val();

    if(value == ”){
    label.stop().animate({ ‘left’:'-’+adjust+’px’ }, ‘fast’);
    } else {
    label.css({ ‘left’:'-’+adjust+’px’ });
    }
    }).blur(function(){
    var label = $(this).prev(‘label’);
    var value = $(this).val();
    if(value == ”){
    label.stop().animate({ ‘left’:restingPosition }, ‘fast’);
    }
    });
    })
    });

  27. Nick says:

    This is a very cool effect, but if the space is there to put the lables outside of the field, then put them outside of the field.

  28. Matt Hill says:

    A nice effect, but it’s a solution to a problem that doesn’t exist.

    Labels should be outside their input fields for all sorts of usability and accessibility reasons. I just don’t see that there is any practical application of this effect in the real world.

    • Because the raw HTML is semantically correct, the labels *are* outside of the input fields as far as usability, and most especially accessibility are concerned. However, they are *visually* enhanced to look more attractive (with CSS and a little JavaScript).

      Great solution!

      • Chris Burd says:

        Yes, it is accessible (or at least, not anti-accessible) and it is semantically correct, but that’s looking at it from a code view, not a user view. It’s more valid to say that the user view is the product than that code view is the product. The critics here (including me) see a conflict between attractiveness (coolness, anyway) and usability, both of which are primarily part of the user experience.

  29. That is a really cool effect.

  30. Andy Walpole says:

    Excellent tutorial. One to bookmark for future reference.

« Older Comments | Newer Comments »

Trackbacks & Pingbacks (33)

Leave a Reply

New from the blog

Are My Sites Up? authenticjobs.com