How do you mark up forms?

posted by Kravimir at 9:06 PM on Nov. 5th, 2008

Categories: HTML, Semantics, Forms 6 comments
Many people who otherwise use tableless layouts still use tables for marking up forms. Yes, it makes getting things to line up correctly easy most of the time, but it's hardly semantically correct. You see, a table should have at least 2 rows and 2 columns of data. And they usually have a column of headers for the rows and a row of headers for the columns. Now, if you think about it, the labels for form controls make up a column of headers for the rows; that leaves you with one column of data which hardly could be called tabular data.

Now please don't just write me off as a "table basher" or something similar. I'm talking about using semantic markup as best you can. I accept that many people will have a period of transition as they move away from using tables for layout. My point is that many people seem to have stopped their transition prematurely. This would be a good time to mention CSS Tables, since IE8 will support them. Therefore, we can start using them and just use an alternate layout technique for IE6 and 7.

Some people are in the habit of using paragraph elements (<p>) for grouping each label with its form control. How does a label and its form control constitute a paragraph? Sometimes you may want to have a paragraph of text explaining part of the form though.

After having discussed how tables are inappropriate for marking up form controls, how should it be done? Other people like using definition lists (<dl>). This is where we've reached the gray area. I don't like using <dl>s for this myself, but I can see how other people would. For one thing, I prefer having an element to contain each label and form control pair.

Some people use ordered or unordered lists (<ol>s and <ul>s, respectively). I like using them for radio button and checkbox groups sometimes, but prefer just using <div>s for much of marking up forms.

Now I should point out that each form control should have its own <label> element and that it's good to group related groups of form controls with <fieldset> elements. Some people go wrong by using a <label> for the question that is answered by clicking on one of the radio buttons in a group of them. That's what a fieldset's legend element is good for. Styling those can be tricky, but that's a topic for another post.

So to summarize. Don't misuse <table>s or <p>s, always use <label>s, and use <fieldset>s where appropriate.
#1 Arem 5:34 AM on Nov. 6th, 2008
Thanks again Kravvitz.

I heartily agree with your comments about containing each label and form control pair together and using <div>s for much of marking up forms. Nothing else I've tried really matches this method.

Could I just ask you to clarify what you meant by this:

"Some people go wrong by using a <label> for the question that is answered by clicking on one of the radio buttons in a group of them."

Do you mean that each radio button should be accompanied by a label, but that the "topic" of the radio buttons should be in the form of a fieldset legend? I.e.

Pick a drink [legend]
- beer [radio button + label]
- wine
- water

I was looking a form layout like this today. Is there any point in what is done in the first two lines? i.e. giving a div an id and the label a 'for' attribute:


Code:
<div class="buttongroup" id="radiochoices">
<label for="radiochoices">Form Layout</label>
<div class="selection">
<input id="first" name="radioset" type="radio" value="Labels above" />
<label for="first">Labels above inputs</label>
</div>
<div class="selection">
<input id="second" name="radioset" type="radio" value="Labels left" />
<label for="second">Labels left of inputs</label>
</div>
<div class="selection">
<input id="third" name="radioset" type="radio" value="Labels right" />
<label for="third">Labels right of inputs</label>
</div>
</div> <!-- end buttongroup div -->


Would a screen reader understand this layout?
#2 Kravimir 2:44 PM on Nov. 6th, 2008
Thanks for your comment, Arem.

I should start by adding that it's best to always use the for attribute on <label> elements because IE6 won't correctly associate the label with its form control otherwise. Also I should mention that the value of the for attribute must be the ID of the form control, not its NAME.


Quote:
Do you mean that each radio button should be accompanied by a label, but that the "topic" of the radio buttons should be in the form of a fieldset legend?

Yes, that's what I mean.

Your code example is a good example of misusing a <label> in the place of a <fieldset>'s <legend>. As far as I know, setting the value of a <label>'s for attribute to an ID of an element that is not a form control will not do anything useful.

I would probably mark that up like this:

Code:
<fieldset class="buttongroup">
<legend>Form Layout</legend>
<ul>
<li>
<label for="first"><input id="first" name="radioset" type="radio" value="Labels above" />
Labels above inputs</label>
</li>
<li>
<label for="second"><input id="second" name="radioset" type="radio" value="Labels left" />
Labels left of inputs</label>
</li>
<li>
<label for="third"><input id="third" name="radioset" type="radio" value="Labels right" />
Labels right of inputs</label>
</li>
</ul>
</fieldset>

Note how I put each radio button inside its <label>. It's good to do that for radio buttons and checkboxes because it helps make a larger, continuous clickable area.
#3 Arem 5:24 PM on Nov. 6th, 2008
Thanks for that, Kravvitz. The code I posted was from a book, and I had doubts over the usefulness of an ID in the containing div. Did not make sense to me either.

As for nesting the radio button inside the label, there's recently been a discussion about this at DevShed (sorry I couldn't find the link). In my experience, even when the input is NOT nested the clickable area is larger, but perhaps this is only on some browsers. (I mainly test on a Mac.)
#4 Kravimir 5:30 PM on Nov. 6th, 2008
Quote:

In my experience, even when the input is NOT nested the clickable area is larger, but perhaps this is only on some browsers

Yes, but there might be a gap between two clickable areas if the radio button is not in its <label>. It depends of course on whether there is a margin on the <label> or form control between them and whether there is white-space characters between them in the markup.

#5 Arem 5:56 AM on Nov. 7th, 2008
Interesting point. And besides, it does make sense to tie button and label together like this. I've never really been happy to see them just 'floating' beside each other (literally or otherwise).

I'm now heading off to play with your list example. Thanks again.
#6

AFAIC that's the best asnwer so far!

Matty 4:49 PM on Jun. 12th, 2011

AFAIC that's the best asnwer so far!

Comment Form: