Typically I style forms with the unordered list tag e.g.
I tend to use ordered lists
<fieldset>
<ol>
<li>
<label for="txtNameFirst">Name</label>
<input type="text" id="txtNameFirst" />
</li>
<li>
<label for="txtNameLast">Name</label>
<input type="text" id="txtNameLast" />
</li>
</ol>
</fieldset>
My semantic reasoning for using ordered lists is that a good deal of forms in print are actually numbered and are therefore an ordered list of form inputs.
Semantically, I think a definition list holds water as well, and it does have the added benefit of supplying a wrapper for every label/input pairing as well as each individual label and input which can give you a lot of design control (if you can live with the slight heavy-handedness of wrapping a DL around each label/input pair)
<fieldset>
<dl>
<dt><label for="txtNameFirst">Name</label></dt>
<dd><input type="text" id="txtNameFirst" /></dd>
</dl>
<dl>
<dt><label for="txtNameLast">Name</label></dt>
<dd><input type="text" id="txtNameLast" /></dd>
</dl>
</fieldset>
If ordered/unordered/definition lists just aren't your thing, then I'd go with divs. Their only implied semantics are "a division" so they are fine for the job.
I have a hard time justifying the use of paragraph (p) elements to wrap label/input pairs as the implied semantics of the p element just don't apply in my opinion. (also, it's nice to keep the p element available for use inside the form for explanatory text if needed)
Generally, forms fields are neither paragraphs nor list items, semantically speaking. If you require your form fields to be grouped together, <div>
s with classes are likely most appropriate, but if you're just looking for a container around the <label>
/<input>
pair, consider the alternate method for associating a label with a field:
<fieldset>
<label>Name <input type="text" id="txtName"/></label>
<label>Location <input type="text" id="txtLocation"/></label>
</fieldset>
You can then style or manipulate them together without an artificial wrapper (and without ever having to worry about for=
again).
I tended to use one <div>
per <label>
and <input>
combo, until I got a new job where the norm was an unordered list. I have a coworker who swears by tables (one column for labels, one for fields) claiming that it's just tabular data with edit capabilities.
At this point I believe inputs as an unordered list is the best semantic fit, but as you note there are many opinions on the subject.
In my opinion a group of form controls is neither a list item or a paragraph. When I mark up forms, I separate my groups of label/input by wrapping them in <div>
s. If you're trying to mark up a division between form controls, then don't be afraid of using a <div>
.
<fieldset>
<div class="field">
<label for="txtName">Name</label>
<input type="text" id="txtName" />
</div>
<div class="field">
<label for="txtTitle">Title</label>
<input type="text" id="txtTitle" />
</div>
</fieldset>
From your given examples, <p>
probably degrades "better" because you won't see bullets next to your items if CSS was unavailable, and the groups of controls would probably be spaced out fairly well.
The WHATWG actually considers each part of a form to be a paragraph:
Each part of a form is considered a paragraph, and is typically separated from other parts using p elements.
I'm not sure whether I agree with this, but it seems to be most "official" answer to the problem you can get. Sadly I couldn't find any explanation.
The key things that the W3C lay out for forms is that the Form is set up in a way that the labels and form elements can be easily grouped programatically:
1.3.1 Info and Relationships: Information, structure, and relationships conveyed through presentation can be programmatically determined or are available in text.
In particular HTML Technique 44: Using label elements and HTML Technique 71: Providing a description.
The advantage you get from wrapping each label and input in a list item is that the user with a screen reader may well get some indication at the begining that the list has x items in it, which might be useful.
Generally though our designers are with Zack - our form rows are wrapped in a div, with a class of "formrow" or similar.