Better Form Input Fields

Here are some demonstrations of ways to make more accessible form input fields that appear to have default text but really have valid labels. Read the related blog entry at christianmontoya.com

For WCAG reference, please see HTML Techniques for WCAG 1.0, section 11.3: Labeling form controls.

Bad Form

This is what should not be done.

The relevant markup for the input field in this example is:

<input type="text" value="Search">

This markup is bad for two reasons:

Good Form

The (far) better way to implement this is:

Notice the presence of the label in the markup:

<label>Search</label> <input type="text">

My goal is to make this version of the markup look like the first example.

Example 1

Here is one method with a zero-width:

This is the relevant CSS. As you can see, text is hard to control when it is overflowing its container. Also, the input field behaves funny when the background is set to transparent, so we have to force a solid border style.

#form3 label { 
	float:left; 
	width:0; 
}
#form3 input { 
	background:transparent; 
	border-style:solid; 
}
#form3 input:focus { 
	background:#fff; 
}

Example 2

Here is another method with a negative margin:

This works much better. The relevant CSS has some padding to make it look right:

#form4 label { 
	display:block;
	float:left; 
	width:5em; 
	padding-top:.2em; 
	padding-left:.2em; 
}
#form4 input { 
	display:block; 
	float:left; 
	margin-left:-5.2em; 
	margin-right:.4em; 
	background:transparent; 
	border-style:solid; 
}
#form4 input:focus { 
	background:#fff; 
}

Example 3

Here is one more example with a negative margin:

The markup is a little different on this one. The input and button have been wrapped in a span. The CSS is:

#form5 label { 
	display:block; 
	line-height:1.2em; 
	padding-left:.2em; 
}
#form5 span { 
	display:block; 
	margin-top:-1.4em; 
}
#form5 input { 
	background:transparent; 
	border-style:solid; 
}
#form5 input:focus {
	background:#fff; 
}

Disclaimer

A quick word on accessibility: all labels should include a "for" attribute, like so:

<label for="search">Search</label>
<input type="text" name="search">

It is assumed that most accessible-site designers know this. This disclaimer is here for the snooty visitor.

The Final Word

No technique is perfect, but examples 2 and 3 come close in good browsers.

This is easier to pull off when the label, input, and button are stacked. It is impossible when the label, input, and button are inline and aligned to the center, at least with current CSS support.

Example 1 does not work in IE at all, and IE up to version 6 does not support the "focus" pseudoclass on input elements, so IE support is problematic as usual. It's possible to force support for it with Javascript, or just give IE graceful degradation. I would probably do something like this, taken from example 2:

#form4 label { 
	display:block;
	float:left; 
	width:5em; 
	padding-top:.2em; 
	padding-left:.2em; 
}
#form4 input { 
	display:block; 
	float:left; 
	margin-left:-5.2em; 
	margin-right:.4em; 
}
#form4 fieldset>input { 
	background:transparent; 
	border-style:solid; 
}
#form4 input:focus { 
	background:#fff; 
}

With this CSS, IE version 6 and older would get a typical form with hidden label, while all other browsers would get the cool technique.

In any case, what we have here is a "CSS Trick," which might just become very useful years from now when IE 6 is far behind us. I hope you enjoyed it.

Christian Montoya