Improved Current Field Highlighting in Forms

Avatar of Chris Coyier
Chris Coyier on (Updated on )

📣 Freelancers, Developers, and Part-Time Agency Owners: Kickstart Your Own Digital Agency with UACADEMY Launch by UGURUS 📣

currentfield

VIEW DEMO

As a matter of usability and aesthetics, it is a good thing to add some kind of visual feedback on web forms to indicate the currently active (or “focused“) field. Some browsers (Safari/Opera) have decided that is so important, that it take matters into it’s own hands and applies a glowy blue border around active form elements:

safari-search

For non-Safari/Opera browsers, CSS offers some help through the :focus pseudo-classes. You can declare your own focus styles like this:

input:focus {
      background: #fc9fff;   /* sexy hot pink */
}

That’s a good start, but it has some unfortunate weaknesses:

  • It doesn’t work in some browsers (IE)
  • It only highlights the field itself, and does nothing for its corresponding label

We are going to tackle both of these weaknesses, improving our current field highlighting, using jQuery. Our form HTML will look just like any other form markup, except that each label/input group will be wrapped in a DIV:

<form>
	<div class="single-field">
		<label for="Name">Name:</label>
		<input name="Name" type="text"></input>
	</div>
	<div class="single-field">
		<label for="Email">Email:</label>
		<input name="Email" type="text"></input>
	</div>
</form>

Using jQuery, we can watch for an event where an input form comes into focus:

$(document).ready(function(){
	$("input").focus(function() {
		....do something....
	});
});

This is where we can do something cool that CSS alone can’t do, we can jump up to the parent element of that input element, and affect that. In our case, the parent element is that div wrapper we put around each label/input pair. What we would like to do is apply a unique class to that div when the input comes in focus.

$(document).ready(function(){
	$("input").focus(function() {
		$(this).parent().addClass("curFocus");
	});
});

With CSS, we can style up that unique class however we would like!

div.curFocus {
	background: #fdecb2;
}

This works great, but if we just left this how it is, each field would have this class applied when it came into focus and it would never be removed. The whole point here is that this “current field highlighting” is only applied to the “current field”. Fortunately, jQuery gives us a “blur” event, which is the opposite of focus. Let’s put in code for that:

$(document).ready(function(){
	$("input").focus(function() {
		$(this).parent().addClass("curFocus")
	});
	$("input").blur(function() {
		$(this).parent().removeClass("curFocus")
	});
});

We wouldn’t necessarily need to to specify “curFocus” on the removeClass function, since leaving that blank will remove all classes, but just in case we have multiple classes let’s leave it at that.

But wait! Your example has super-cool rounded corners on the active fields! Haha, it does! I’ll never tell! Er. Ehm. OK I will.

Each of the four corners is a little div that needs to go inside of each of our field wrapper divs. Since they are all exactly the same and need to be inside each wrapper div, let’s apply them through jQuery and save ourselves unnecessary repeated markup.

…there is something deeply satisfying about having semantic markup dynamically generated by JavaScript. From: Learning JQuery by Karl Swedberg & Jonathan Chaffer

I agree. We can make any HTML snippet into an jQuery object. Then we’ll use the “appendTo” function to slip it inside each div. Check it out:

$('<div class="tl"></div><div class="tr"></div><div class="bl"></div><div class="br"></div>').appendTo("div.single-field");

In our CSS, we’ll style them up but leave their display values to “none” so they don’t show up until we want them.

.tl {
	position: absolute;
	top: 0;
	left: 0;
	width: 10px;
	height: 10px;
	background: url(images/corner-topleft.jpg);
	display: none;
}
.tr {
	position: absolute;
	top: 0;
	right: 0;
	width: 10px;
	height: 10px;
	background: url(images/corner-topright.jpg);
	display: none;
}
.bl {
	position: absolute;
	bottom: 0;
	left: 0;
	width: 10px;
	height: 10px;
	background: url(images/corner-bottomleft.jpg);
	display: none;
}
.br {
	position: absolute;
	bottom: 0;
	right: 0;
	width: 10px;
	height: 10px;
	background: url(images/corner-bottomright.jpg);
	display: none;
}

We’ll use jQuery to toggle the visibility of all those divs on and off when we need them. Here is the final javascript:

<script type="text/javascript" src="js/jquery.js"></script>
<script type="text/javascript">
	$(document).ready(function(){
		$("input").focus(function() {
			$(this)
				.parent()
					.addClass("curFocus")
				.children("div")
					.toggle();
		});
		$("input").blur(function() {
			$(this)
				.parent()
					.removeClass("curFocus")
				.children("div")
					.toggle();
		});
		$('<div class="tl"></div><div class="tr"></div><div class="bl"></div><div class="br"></div>').appendTo("div.single-field");
	});
</script>

VIEW DEMO