thoughts
[HTML] coding clean forms
2004-10-31 modified: 2005-05-21
I need to rewrite this a bit, due to various updates it has become very unclear and outdated.
I usually see forms layed out in this way (attributes omitted):
<form>
<table>
<tr>
<td>input label</td>
<td><input></td>
</tr>
<tr>
<td>input label</td>
<td><input></td>
</tr>
</table>
</form>
Which is very ugly code if you ask me. There are elements like fieldset, label and legend to structure your form data. With some simple CSS this is enough to make a nice layout. A simple form could be structured like this (trivial attributes omitted):
<form>
<fieldset>
<legend>Legend of the fieldset</legend>
<label for="input1">label for input1</label>
<input id="input1" type="text">
<label for="input2">label for input2</label>
<input id="input2" type="text">
</fieldset>
<fieldset class="process">
<input type="submit">
</fieldset>
</form>
This is the most simple case, but it has some disadvantages. Without styles
for example, these are all inline blocks, so they're displayed after eachother.
This can be solved by adding <br> elements after each <input>.
Note the <label> element which defines the label text for
an input, coupled through the for and id
attributes. The submit button is placed outside the fieldset, because mostly
it has nothing to do with the group of inputs in it (note that there can be
several fieldsets).
This setup can now be layed out using CSS. Applying left floating to the <label>
and <input> elements, clearing the <br>
elements and defining some width for the relevant elements does most of the trick.
Another setup also possible is to put a definition list inside the fieldset,
putting labels in <dt> elements and inputs in <dd>
elements. This produces a somewhat different layout without styles applied.
Semantically this also makes some sense, it ties the <input>
and <label> elements together (although this was also done
by the for attribute).
Update 2005-02-07
I have changed the example above: the submit button is now placed in it's own fieldset, because form elements only allow block (and script) elements inside. I could have placed the submit button in the existing fieldset but, as said, this button usually has nothing to do with any of the fieldsets present (it submits all of them). A class is added to indicate it's a different kind of fieldset (not containing user input, but processing elements).
Update 2005-02-15
As I recently found out, all browsers support display: inline-block for native inline elements, so this is also true for label and input elements. So what I said before could be done in a better way:
This setup can now be layed out using CSS. Applying left floating to the
<label>and<input>elements, clearing the<br>elements and defining some width for the relevant elements does most of the trick.
Instead of floating and clearing, you'd better apply inline-block for the label and input elements. The br's should still be there (remember the useragents that do not apply stylesheets), but you do not need to clear them.
Update 2005-05-21
In the light of the Web Applications 1.0 (HTML 5) working draft, maybe using <br> is not that good an idea. In fact I agree with the examples stated there. HTML is al about content, not visual appearance. So instead of using <br> to display things the way you want in non-CSS user agents (remember that you do not need them anyway in CSS supporting UA's - a fact that supports the idea <br> is not at its place here). So, following the Whatwg example, you could use <p> to seperate fields, but I think a <dl> constuct is more apropriate.
Additional resources (top 15)
Below is a list of additional resources that might contain extra information about the subject at hand. These are all sites linking to this one (i.e. backtracking).
