CSSKarma

display your <style>

designing the web since 2002

Archive for the ‘Web Design’ Category

|

Sliding Labels v2 – Patch

Tuesday, February 2nd, 2010

banner

Last week I wrote an article about sliding form labels that got quite a bit of attention. Many of the commenters brought up a couple good points/bug in the Sliding Label code that I wanted to address and provide a patch for:

  • The sliding label was barfing out in Safari when auto-fill was active
  • The default scripting didn’t work on textareas

I sat down yesterday and wrote a patch/new version of sliding labels which I think addresses these two problems.

View the Demo

The new jQuery

$(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'
	});

	var inputval = $(this).next().val();

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

	// 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, textarea').focus(function(){
		var label = $(this).prev('label');
		var width = $(label).width();
		var adjust = width + 5 + 'px';
		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');
		}	

	});
}); // End "each" statement
}); // End loaded jQuery

Textarea HTML

The HTML for the textarea follows the same convention as the rest of the inputs, in only needing a wrapping element.

<div id="comment-wrap"  class="slider">
    <label for="comment">Comment</label>
    <textarea cols="53" rows="10" id="comment"></textarea>
</div><!--/#comment-wrap-->

There are no major changes to the plugin, just a few tweaks. If you find anymore bug, please let me know.

View the Demo

Tags: , , ,
Posted in Web Design | 42 Comments »

Form Design with Sliding Labels

Tuesday, January 19th, 2010

Sliding Label banner

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

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 1.1)

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 1.1)

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: , , ,
Posted in Web Design | 130 Comments »

Conditional Animation Speed in jQuery

Friday, January 8th, 2010

Turtle

For years (and by “years”, I most likely mean “the years since I started using jQuery… maybe 2″), there’s been one aspect of jQuery that’s bugged the crap out of me, the animation speed.

View demo

We’ve all probably seen the problem that happens in many drop down menus of varying height. We set slideDown(300) (or whatever you set it to) on all the submenus and leave like that. Inevitably, menus grow and shrink based on the content and we get this weird and mildly annoying behavior of really fast moving tall menus vs. shorter menus that move painfully slow just because there’s not much content in there.

This problem stems from where we set the speed of the animation; the value isn’t actually a speed, it’s how long it takes (in milliseconds, I think) for the animation to finish. So you can see why you get varying behaviors based on the element height.

It’s true, that you can use the built-in speed values like “fast” and “slow”, but if you want more fine-grained control over your animation, you’ll have to use a value.

Problem Child

This is what our problem menu looks like all collapsed, just 2 clickable headings (h2) that will slide open to expose content (p)

animation collapsed

Normally our jQuery would look something like this:

$(function(){

$('h2').toggle(function(){
    /* get the next element */
    var next_element = $(this).next();

    /* open it  if it's closed */
    next_element.slideDown(500);
},function(){
    /* get the next element again */
    var next_element = $(this).next();

    /* close it if it's open */
    next_element.slideUp(500);
});

});

Note: just example code, I didn’t check to see if it actually works

This is our menu fully expanded. As you can see, the first item has a lot more content then the second. Using the code above will make menu #1 move noticeably faster than menu #2; which, to me, creates an odd user experience. Because you’re like “Why’s is moving so slow?”

animation expanded

So let’s see if we can’t fix that.

Ben Healy (Solution)

What we’re looking to do here is get the height of each collapsed item, do some JS math, and set a speed (animation time) value based on the height.

jQuery functions we’ll need

  • next()
  • height()
  • slideDown() / slideUp()
  • The Code

    $(function(){
    
    	/* Variables to set */
    	var id = '#heightCheck';
    	var click_element = 'h2';
    	var height_value = '100';
    	var tall_menu_speed = 400;
    	var short_menu_speed = 250;
    
    	/* System variables, probably don't change */
    	var target = id +' '+ click_element;
    	var menu_content = $(target).next();
    
    	/* Hide the element after the click_element, whether it's a
    	div, p, ul, whatever you choose to wrap the items in */
    	menu_content.hide();
    
    	$(target).toggle(function(){
    		/* save the menu items in a variable */
    		var this_menu = $(this).next();
    
    		/* get the menu height and save it */
    		var menu_height = this_menu.height();
    
    		/* Calculate the animation speed based on the element height */
    		/* if the height is greater than the height set above use the
    		tall menu height */
    		if(menu_height > height_value){
    			var speed = tall_menu_speed;
    
    		/* If it's smaller, use the short menu height */
    		} else if(menu_height < height_value) {
    			var speed = short_menu_speed;
    		}
    
    		/* slide the menu down */
    		this_menu.slideDown(speed);
    
    	},function(){
    		/* this is the same but reversed to close the menu */
    		var this_menu = $(this).next();
    		var menu_height = $(this).next().height();
    
    		/* Calculate the animation speed based on the element height */
    		if(menu_height > height_value){
    			var speed = tall_menu_speed;
    		} else if(menu_height < height_value) {
    			var speed = short_menu_speed;
    		}
    		this_menu.slideUp(speed);
    
    	});
    
    });

    That should give you a little more control over the menu speed. I'm sure it needs to be tweaked based on the menu you're using, but the general concept is there, and it should work pretty well. I hope it was helpful. Let me know if you have any additions to the code or suggestions to improve it.

    View demo

    Tags: , , ,
    Posted in Web Design | 2 Comments »

What You Need to Know About Behavioral CSS

Monday, December 21st, 2009

Hi all,
I had a new article published over the weekend at Smashing Magazine. Check it out and let me know what you think!

Behavioral CSS

I wrote it quite a while ago and it seems to be showing a bit in the comments, but overall, I’m pretty happy with the way it came out and the reader responses it’s getting. Hope you enjoy Behavioral CSS

Tags: , ,
Posted in Web Design, Web Development | No Comments »

10 Videos for the Web Community

Friday, August 7th, 2009

I was poking around YouTube last night watching some design videos and I thought I’d share them since it’s been my RSS feed has been a bit stale lately (I’ve been working on a pretty big redesign for this site). Enjoy!

Web Design Mistakes

Duration: 3m 52s

Watching someone use a screen reader

Duration: 3m 31s

This is really boring but any designer/developer really should watch it.

SxSW 08 with Jeffrey Zeldman

Duration: 9m 12s

Design Coding

Duration: 3m 22s

Web Design in 2 Minutes

Duration: 2m 17s

CSS3 Rounded Corners

Duration: 3m 25s

ExpressionEngine 2.0 Preview

Duration: 7m 52s

Dan Rubin Singing Piano Man

Duration: 2m 55s

SxSW 2008 with Kevin Lawver

Duration: 9m 17s

Faster HTML and CSS: Layout Engine Internals for Web Developers

Duration: 1hr 1m

Tags: , , ,
Posted in Web Design, Web Development | 4 Comments »

10 Tips to Create a More Usable Web

Thursday, June 4th, 2009

article banner

My First usability article came out today on Web Designer Depot

10 Tips to Create a More Usable Web

Don’t get me wrong, I like writing about CSS, but this was a nice change of pace. Anyway, Let me know what you think!

Tags: ,
Posted in Web Design | 2 Comments »

|

New from the blog

Are My Sites Up? authenticjobs.com