In HTML user-input forms, it is not uncommon to see text fields with “labels” as grayed-out text in the field itself which disappear when clicked. Unfortunately, it’s harder than it should be.
My search for “best practices” on this technique left me…wanting. Firstly, I wasn’t sure what to call it. Secondly, many implementations were riddled with problems, paramount of which was abominable degradation. I am no accessibility expert, but these solutions didn’t even try. After just a little thought, I came up with something better than any of them. (Not to say it’s the best, but I can’t find one better.) My goals were:
- Unobtrusive
- Graceful degradation (screen-readers and non-JS browsers can fall back on the labels or title attributes)
- Uses all field attributes for their intended purposes
- Places all responsibility/logic in one location, removing the need for controllers to treat certain values or fields specially
A possible draw-back is that users cannot submit a value that matches the field’s title. If that’s a real problem, you could probably add some more checks to hack around it. But how often is someone’s first name First?
My implementation uses >= jQuery 1.3. Since we’re on the Web anyway, I thought I’d throw in a working example below:
The HTML
<form id="form_field_label_example" action="" method="post"> <p> <label for="first_name">First</label> <input id="first_name" name="first" title="First" type="text" /> <label for="middle_name">Middle</label> <input id="middle_name" name="middle" title="Middle" type="text" /> <label for="last">Last</label> <input id="last" name="last" title="Last" type="text" /> </p> </form>
The JavaScript
<script type="text/javascript"> $(function() { auto_label("form#form_field_label_example input[title][type=text]") }) function auto_label(str) { $(str).each(function() { // Hide the field's real label $('label[for=' + this.id + ']').hide() // Set the label text and color for blank fields if ( !this.value || this.value == this.title ) { this.value = this.title $(this).css('color', '#999') } // On focus of blank fields, clear the label text and reset the color $(this).focus(function() { if ( this.value == this.title ) { this.value = '' $(this).css('color', 'inherit') } }) // On unfocus of blank fields, restore the label text and color $(this).blur(function() { if ( !this.value ) { this.value = this.title $(this).css('color', '#999') } }) }) // Clear label text when submitting form $(str).closest('form').submit(function() { $(str).each(function() { if ( this.title && this.value == this.title ) { this.value = '' } }) }) } </script>