Authoring accessible web forms
September 7, 2006 · Chris Peters
HTML tags were designed to describe information, not necessarily to dictate how to display information.
As I’ve gotten better with XHTML and CSS, I’ve become more interested in figuring out which tag to use for each element on a web page. HTML tags were designed to describe information, not necessarily to dictate how to display information.
We developers should ask ourselves which tags we should use on our HTML forms. HTML forms are a crucial part of developing a web application, so why not form good habits in marking them up?
XHTML is the king of accessibility
If you go to Google Labs’ new Accessible Search, you’ll notice that they are considering the adoption of the XHTML Transitional doctype. If you view the HTML source for any of Google’s other pages, you’ll see that they don’t usually declare any kind of doctype or follow any kind of standards-based authoring practice.
I’ll venture to say that the developers at Google are pretty smart people. If they use XHTML on a product that they label as “accessible,” we should probably be using it ourselves if accessibility is a priority.
How most of us mark up forms
A simple form that you commonly see on the Web is coded like this:
<form action="action.cfm" method="post"> | |
<p> | |
<strong>Your Name</strong><br /> | |
<input type="text" name="yourName" /> | |
</p> | |
<p> | |
<strong>Gender</strong><br /> | |
<input type="radio" name="gender" value="M" /> | |
Male<br /> | |
<input type="radio" name="gender" value="F" /> | |
Female | |
</p> | |
<p> | |
<input type="submit" value="Submit" /> | |
</p> | |
</form> |
Provided that the rest of your HTML on the page is coded correctly, this will validate as proper XHTML. In this case, XHTML validation is not enough if we want for this form to be accessible. Let’s nit-pick this small bit of code.
What’s wrong with the code?
Let’s fix the form so we don’t exclude blind and low-vision users from being able to use our wonderful web applications.
Use <p>
for paragraphs
First, is the content marked as “Your Name” followed by an input box really a paragraph? Is anything in the form really a paragraph, justifying the use of <p>
tags? In this case, we want our fields to be defined at a block level, so let’s replace the <p>
s with <div>
s.
<form action="action.cfm" method="post"> | |
<div> | |
<strong>Your Name</strong><br /> | |
<input type="text" name="yourName" /> | |
</div> | |
<div> | |
<strong>Gender</strong><br /> | |
<input type="radio" name="gender" value="M" /> | |
Male<br /> | |
<input type="radio" name="gender" value="F" /> | |
Female | |
</div> | |
<div> | |
<input type="submit" value="Submit" /> | |
</div> | |
</form> |
You’ll notice that you lose spacing between lines provided by the
tags. You’ve heard the experts preach about using CSS to separate content from presentation, so let’s use it that way by writing this CSS in an included style sheet:
form div { | |
margin: 10px 0; | |
} |
<label>
your form fields
It’s very difficult for those using screen readers to be able to decipher which form control the “Your Name” text goes with. That’s why we have the <label>
tag, which pairs text with a form field. The <label>
links text to the id
attribute of a given form field. Let’s apply this to the HTML.
<form action="action.cfm" method="post"> | |
<div> | |
<label for="your-name">Your Name</label><br /> | |
<input id="your-name" type="text" name="yourName" /> | |
</div> | |
<div> | |
<strong>Gender</strong><br /> | |
<input id="gender-m" type="radio" name="gender" value="M" /> | |
<label for="gender-m">Male</label><br /> | |
<input id="gender-f" type="radio" name="gender" value="F" /> | |
<label for="gender-f">Female</label> | |
</div> | |
<div> | |
<input type="submit" value="Submit" /> | |
</div> | |
</form> |
You’ll notice one other key benefit on the radio button fields. If you click on the text that says “Male” or “Female,” you’ll notice that it selects the correct radio button, just like your favorite Windows or Mac applications. Also, please notice that those two radio buttons cannot have the same value defined in their id
attributes.
This will help tell screen readers and other HTML renderers which textual elements label which form controls.
Note that you can style the <label>
tag with CSS, thus making it unnecessary to use <strong>
tags to highlight the text.
Group related fields into <fieldset>
s
We can use more standard HTML tags to further describe this form. The two radio buttons for selection of gender can be grouped together. Use the <fieldset>
and <legend>
tags to describe that group of controls.
<form action="action.cfm" method="post"> | |
<div> | |
<label for="your-name">Your Name</label><br /> | |
<input id="your-name" type="text" name="yourName" /> | |
</div> | |
<fieldset> | |
<legend>Gender</legend> | |
<input id="gender-m" type="radio" name="gender" value="M" /> | |
<label for="gender-m">Male</label><br /> | |
<input id="gender-f" type="radio" name="gender" value="F" /> | |
<label for="gender-f">Female</label> | |
</fieldset> | |
<div> | |
<input type="submit" value="Submit" /> | |
</div> | |
</form> |
If you don’t like the standard border that your browser of choice puts around the fieldset, you can change its appearance by adjusting the <fieldset>
’s border
, padding
, and margin
CSS properties and the <legend>
’s margin
and font-weight
properties, among others. You may need to use some negative margin
/padding
properties to get things looking the way you want them to.
The point is that you’ve described your content more fully, thus enabling everyone to better understand it. If you don’t like the way something looks on the screen, you use CSS to change its appearance, not HTML.
Now you know your HTML
As you’ll find out, once you learn these simple techniques, it is easy to adopt them into your practices with little thought going forward.
I am constantly learning how to improve my HTML authoring practices, and I’ve found that it’s best to prioritize what I learn. Forms are all over the place on the Web. I hope that by sharing what I’ve learned about them, you will improve your habits as well!