Making The Form Accessible

In order for a form to be considered accessible, each input needs to be associated with some text. In the case of groups of radio buttons and check boxes, the group must also be formally tagged and represented by some text. The label tag can be used to associate text with a single form input and the legend tag can be used to associate text with a group wrapped by a fieldset tag. Out of the questions that already exist on the form, all of the text boxes and the select list are wrapped together with the associated question or text label with a "p" tag. Simply changing the paragraph (P) tag to a label tag makes those form inputs accessible.

Replace paragraph tags with labels tags for the text, text area, and select list inputs.

Next wrap a fieldset tag around the two paragraph tags that make the grouped inputs. The first paragraph can be converted to a legend tag.

The resulting form will look like this:

<form action="script.php" method="post" title="Personal Information">
<label>Your Name
<input type="text" name="name">
</label>
<label>Nickname
<input type="text" name="nick" value="no nickname">
</label>
<label> Short Bio
<textarea name="bio"></textarea>
</label> <fieldset> <legend>What flavors of ice cream do you like?</legend>
<p>
<input type="checkbox" name="icecream[]" value="vanilla">
Vanilla
<input type="checkbox" name="icecream[]" value="chocolate">
Chocolate
<input type="checkbox" name="icecream[]" value="strawberry">
Strawberry<br>
<input type="checkbox" name="icecream[]" value="other">
Other
<input type="text" name="other icecream">
</p> </fieldset> <fieldset> <legend>If you could get a pet it would be a:</legend>
<p>
<input name="pet" type="radio" value="no pet">
I do not want a pet <br>
<input name="pet" type="radio" value="kitten">
Kitten
<input name="pet" type="radio" value="cat">
Adult Cat
<input name="pet" type="radio" value="puppy">
Puppy
<input name="pet" type="radio" value="dog">
Adult Dog
<input name="pet" type="radio" value="bird">
Bird
<input name="pet" type="radio" value="fish">
Fish<br>
<input name="pet" type="radio" value="other">
Other
<input type="text" name="other pet">
</p> </fieldset> <label> State of Birth
<select name="birth state">
<option value="NC">North Carolina</option>
<option value="GA">Georgia</option>
<option value="SC">South Carolina</option>
<option value="TN">Tennessee</option>
<option value="VA">Virginia</option>
<option value="O">Other</option>
</select>
</label> <label>Phone Number <input type="text" name="phone">
</label> <p>
<input type="submit" name="submit" value="Send">
<input type="reset" name="reset" value="Reset"> </p>
</form>

Removing the paragraph tags changes the formatting of the form. For now this is not a concern, the formatting will be changed when CSS is applied.

Inside the fieldset groups, there is still text that needs to be associated with form inputs. Remove the remaining paragraph tags in the two fieldsets and wrap a label tag around each input tag and its accompanying text. The text "other" is shared by two inputs, one radio button and one text field. This will be corrected in the next step.

<form action="script.php" method="post" title="Personal Information">
... <fieldset> <legend>What flavors of ice cream do you like?</legend>
<label>
<input type="checkbox" name="icecream[]" value="vanilla">
Vanilla </label>
<label>
<input type="checkbox" name="icecream[]" value="chocolate">
Chocolate </label>
<label>
<input type="checkbox" name="icecream[]" value="strawberry">
Strawberry<br> </label>
<label>
<input type="checkbox" name="icecream[]" value="other">
Other
<input type="text" name="other icecream"> </label> </fieldset> <fieldset> <legend>If you could get a pet it would be a:</legend>
<label>
<input name="pet" type="radio" value="no pet">
I do not want a pet <br> </label>
<label>
<input name="pet" type="radio" value="kitten">
Kitten </label>
<label>
<input name="pet" type="radio" value="cat">
Adult Cat </label>
<label>
<input name="pet" type="radio" value="puppy">
Puppy </label>
<label>
<input name="pet" type="radio" value="dog">
Adult Dog </label>
<label>
<input name="pet" type="radio" value="bird">
Bird </label>
<label>
<input name="pet" type="radio" value="fish">
Fish<br> </label>
<label>
<input name="pet" type="radio" value="other">
Other
<input type="text" name="other pet"> </label>
</fieldset> ...
</form>

To correct the problem of two inputs sharing a text description, more text must be added. It can later be obscured by CSS if the label really isn't needed, but in most cases the one label per input is a good idea and makes form design more solid. In form design, exceptions are best handled by separate follow up questions. Move the "other" textfield input out of the fieldset, give it it's own text, and wrap the input and text with a label.

  <fieldset>
    ...
<label>
<input type="checkbox" name="icecream[]" value="other">
Other </label> </fieldset> <label> If other please specify <input type="text" name="other icecream"></label> <fieldset> ...
<label>
<input name="pet" type="radio" value="other">
Other
</label>
</fieldset>
<label> If other please specify <input type="text" name="other pet"></label>

Now the form is accessible. This example covers most of the formats of question commonly encountered. Fieldset tags can wrap more than just groups of radio buttons and check boxes. Any group with a common context could be handled with a fieldset. Consider the following form:

  <label>Height
<input type="text" name="height">
</label>
<label>Weight
<input type="text" name="nick" value="no nickname">
</label>
<label> Blood Type
<select name="birth state">
<option value="o-">O positive</option>
<option value="o+">O Negative</option>
<option value="a">A</option>
<option value="b">B</option>
<option value="ab">AB</option>
</select>
</label>

This form is perfectly accessible, but it's not perfectly clear. The logical assumption would be that the form is asking the user for their vital information, but perhaps that was not the author's intent. A fieldset can give these questions a clearer context without having to repeat a phrase or question in every label.

  <fieldset><legend>Your spouse's vital information.</legend>
     <label>Height
<input type="text" name="height">
</label>
<label>Weight
<input type="text" name="nick" value="no nickname">
</label>
<label> Blood Type
<select name="birth state">
<option value="o-">O positive</option>
<option value="o+">O Negative</option>
<option value="a">A</option>
<option value="b">B</option>
<option value="ab">AB</option>
</select>
</label> </fieldset>

Is less monotonous than:

  <label>Your spouse's Height
<input type="text" name="height">
</label>
<label>Your spouse's Weight
<input type="text" name="nick" value="no nickname">
</label>
<label>Your spouse's Blood Type
<select name="birth state">
<option value="o-">O positive</option>
<option value="o+">O Negative</option>
<option value="a">A</option>
<option value="b">B</option>
<option value="ab">AB</option>
</select>
</label>

Other ways to make form inputs accessible.

If design-wise it is not possible to wrap a label tag around both a form element and it's descriptive text, there is a work around. Tags in HTML have to be properly nested, so there are occasionally times where a label tag cannot wrap the text and the input tag. The most common case of this is table layouts, which should be avoided. CSS can replace the need for tables in most forms. If this isn't possible, assign the form input tag an "id" attribute, and use a matching "for" attribute in the label tag. The id attribute may not be shared with any other tag, even of a different type, in the same document.

<table>
  <tr>
    <td> <label for="unique_id">Text Label</label> </td> ....
  </tr>
  <tr>
    <td> <input id="unique_id"> </td> ....
  </tr>
</table>

Fieldset legends cannot use the same "for-id" paradigm. They must appear in their fieldset, and should be before any text or other tags.

It is important to validate HTML documents. This helps to ensure that they will behave predictably in different browsers. While there is no guarantee of this, validation can sometimes make a subtle or not so subtle difference in older or less tolerant browsers. If you validate the accessible form, you will (should) be informed that the textarea tag requires both the "cols" and "rows" attribute indicating how many characters wide and lines tall it should be. This infringement doesn't break the form in any of the common browsers, but there may be one browser out there that does not handle this exception so gracefully. Validating a document can sometimes help debug an unruly page, especially when CSS styles are not behaving as expected or according to known bugs.

Sometimes accessibility problems arise in a web form that have nothing to do with the HTML. At the bottom of this "accessible form" is a question asking for a phone number. If this input field were required or even just important, it might cause problems. Suppose a user cannot talk on a normal phone. How will they inform the recipient of this data? There is no field for comments. They could add this information to the "bio", but that probably would not be appropriate. Suppose the phone number field is limited to 12 characters. This is more than enough for most phone numbers, but not enough for international numbers, and certainly not enough space for a phone number and a friendly note that the person can only be reached via TTY.

The important thing to realize from this scenario is that restrictions and requirements on web forms should be carefully considered. The whole point of a web form is to automate a process. In some cases the best way to handle exceptions may be providing a fall back, such as a comments field. This is a very useful tactic in handling un-anticipated barriers or problems.