Your friends at Viget present Inspire, a Design & Interaction Blog

Making Infield Form Labels Suck Less II

Hopefully you’ve already read Jackson Fox’s post on Making Infield Form Labels Suck Less from a UX perspective. If you haven’t, I recommend that you check it out before reading my thoughts from the front-end development perspective.

Can't wait to check out the code? Head down to the jsFiddle at the end of the post.

So often in web design and development, things that are easy to implement aren’t appropriately examined. In this case, placing the label for a text field within the field is a common practice to make form layouts more compact. The implications of that choice create interaction and technical challenges that need to be considered carefully.

Since Jackson covered usability issues with this approach, I want to discuss some of the technical and accessibility considerations. Trevor covered this a few years ago, and while the browser landscape has changed quite a bit, it’s still a good read on the subject. My issue with the popular techniques is more semantic than technical. There are a bunch of ways to get text into a text field to serve as a label, but most of these techniques only solve it visually. Let’s take a look at the two most popular.

Value Attribute

One of the most popular implementations of this pattern is to use the value attribute of the text field for the label. JavaScript is then used to remove the value when the field is either focused or typing begins. This method is full of issues, including:

  • When JavaScript fails or is unavailable, the interaction breaks. Either the value isn’t set at all leaving no label (worse) or the user has to remove the label before they can enter their information (annoying) and the label is gone forever if they forget what the field is for.
  • Extra care must be taken by the developer to ensure that values for fields not filled in by the user aren't sent along to the server when the form is submitted.

The most problematic part of this method, though, is that the value attribute does not provide proper accessibility for users navigating with a keyboard or screen reader. According to WebAIM’s article on Creating Accessible Forms:

When a screen reader accesses a form item that has a <label> element associated with it, it will read the text within the <label> element and indicate the type of form item it is (e.g., "First Name. Text box" or "Age. Check box").

Using anything other than a <label> creates extra work, at best, and confusion, at worst, for users that have vision or mobility impairments.

Placeholder Attribute

The HTML5 placeholder attribute seems to be the perfect native solution to the problem. According to caniuse.com, the placeholder now has over 68% support among browsers. That makes it a much more viable option than when Trevor wrote his article. The problem with the placeholder is that it’s not an alternative to the label. The W3C puts it very bluntly:

The placeholder attribute should not be used as an alternative to a label.

This issue is described in great detail by Roger Johansson on his blog 456 Berea St.

The placeholder is also an accessibility can of worms. From low visual contrast to no reference once a field has been focused or filled in, placeholders have lots of issues.

Solution

To solve this problem and make the infield label pattern suck a little less, Jackson and I came up with a list of requirements:

  • The label needed to be visible while the user was filling out that field.
  • The placement of the label needed to work within the layout of the form and page.
  • It had to use the <label> tag to ensure good accessibility and semantics.
  • It had to be useable if JavaScript is not available.

What we came up with wasn’t revolutionary. A lot of smart people have headed in this direction before. Instead, our solution was an iteration toward a cleaner and less obtrusive implementation.

The Code

The JavaScript is in the form of a jQuery plugin so it can be easily dropped into any project and bound to any text inputs currently on the page or if they're added to the DOM later. The goal was to keep it very simple and leverage the native events provided by the browser.

For example, when a <label> is correctly set up with a for attribute that matches the id attribute on an input field, clicking on the label will automatically bring focus to the input. Because of that, the focus and blur events on the input only need to be bound.

For the CSS, a .js class is being set on the <html> or <body> to determine if JavaScript is available. Using that class, the <label> is positioned on top of the input if JavaScript is available or above as a fallback if it isn't.

Play around with the jsFiddle below or head over to GitHub and download the code.


Get More From Viget

Subscribe to get our monthly newsletter and occasional special announcements.