How to use tables to structurize forms in HTML and about alternatives, like fieldset

Often viewed as a layout tool, tables are more properly treated as a method for expressing structural relations. For example, tables can be used to indicate the relationships between input fields and their explanations within a form. This document discusses the technical details involved.

Content

Tables, forms, and nesting them

Tables and forms are separate concepts in HTML. People sometimes confuse them with each other. The conceptual confusion is often accompanied with confused markup. On the other hand, tables and forms can be "mixed" in a sense. Specifically, you can put a table inside a form or vice versa, and it is often useful to do so. But you need to understand what you are doing.

Tables and forms can be nested either way. But if you put forms into tables, each form must be completely included into a single table cell (one TD element in practice). Thereby the forms are each completely independent. See my document on choices in HTML forms for some simple examples.

What people probably want to do more often is to nest them the other way: a TABLE element inside a FORM element. Then all form fields within the table cells, being in TR elements within the TABLE element which is within the FORM element, are fields of the same form.

Should tables be used to structurize forms?

Whether it is useful to put the fields of a form into a table (within the FORM element) really depends on the form. For some odd reason, people who design HTML forms are often stuck with ideas of how forms are designed for paper. They put several unrelated questions to one row as if it were important to save paper. As a result, forms become harder to fill, since the intended order of filling it is not obvious. Rowwise or columnwise? Users may even fail to notice some questions. And having created a confused order, authors start wondering how to define tabbing order and things like that.

It is best to organize forms simply: don't use tables to force some particular layout but to indicate the structure when needed. Browsers are expected to present tables, and HTML documents in general, in a manner which corresponds to the structure expressed in HTML.

To take a fairly common example: Assume that you wish to let the user pick up a product from a list in and order form. Probably the product information consists of some fields like product name, order number, and unit price for each product. This means that the data itself is inherently tabular. Why not make it table? That would make the appearance reflect the structure. There are some technicalities involved here; see notes on using checkboxes or radio buttons (instead of SELECT) for such purposes.

An example

As a simple example, consider the situation where some text (field label or something like that) is associated with an input field. (There are better ways for doing that in principle in HTML 4.0, but currently the table idea might be better.) You could set up a table where the first column contains the texts and the second column contains the corresponding input fields:

<FORM METHOD="POST" ACTION="http://jkorpela.fi/cgi-bin/echo.cgi">
<TABLE BORDER="1">
  <TR>
    <TD>Your name</TD>
    <TD>
      <INPUT TYPE="TEXT" NAME="name" SIZE="20">
    </TD>
  </TR>
  <TR>
    <TD>Your E-mail address</TD>
    <TD><INPUT TYPE="TEXT" NAME="email" SIZE="25"></TD>
  </TR>
</TABLE>
<P><INPUT TYPE="SUBMIT" VALUE="Submit" NAME="B1"></P>
</FORM>

On your current browser with its current settings, this would appear as follows:

Your name
Your E-mail address

The presentation can be affected by style sheets. In particular, this document comes with a style sheet which makes some presentational suggestions, so presentation may differ from your browser's usual way of displaying forms. See the document Affecting the presentation of form fields on Web pages.

Another typical case for using a table is to organize a set of radio buttons. There is an example of this in Choices in HTML forms as well as at the end of the current document.

Notes

Avoid too large tables

Although this method can be used for a form with a large number of fields, a practical word of warning is in order: the larger a table is, the longer it takes from a browser to display it. (The browser has to process the entire table before displaying anything of it, since it must take all cells into account when selecting suitable column widths.) Perhaps you can divide the content of a form into major sections, with headings, and structurize each section separately as a small table.

Positioning the submit button

Notice that in our example the submit button is outside the table. The reason is that it has a different role than the other fields. It could be within the table too, but perhaps it is easier to find if it isn't.

Also notice that contrary to popular belief among authors, a reset button is not obligatory or even useful, as a rule. It is especially dangerous when presented alongside with a submit button!

Using table header cells

Our example uses the TD (table data cell) element markup for all cells, both those containing form fields and those containing titles for fields. It might be more logical to regard the latter as headings and use the TH (table heading cell) markup. For example:

  <TR>
    <TH>Your name</TH>
    <TD>
      <INPUT TYPE="TEXT" NAME="name" SIZE="20">
    </TD>
  </TR>

A typical presentation of TH elements uses more emphatic style than for TD cells, e.g. by using bold face. Moreover, by default the content of a heading cell is centered whereas normal cells are left-aligned; this can be affected by using the ALIGN attribute if desired. The following shows how your browser displays (perhaps affected by a style sheet suggested in this document) our sample form when TH markup is used for the texts which are logically field titles:

Your name
Your E-mail address

Tuning the visual appearance

When tables and forms are nested (either way), there is an especially large number of factors that affect the way the page looks like, such as

The document Affecting the presentation of form fields on Web pages discusses the form-related issues in some details. For tables, see section on tables in my material on HTML 3.2 for basics, and e.g. section Tables in Mikodocs for more advanced issues.

As regards to issues specific to the combination of tables and forms, note that if you put a form into a table cell, then you there might be some unwanted extra vertical space below the form. There are various ways to try to suppress that. If there is only one form in the table, one of the ways is to change the structure so that the form and the table are nested the other way around: the form contains the table, even though only one cell contains fields of the form. Technically you'd just move the start and end tags of the form. This means something like the following (in a case where the form appears in the last cell of the table):

Unmodified markup Modified markup
<table>
<tr><td>...</td><td>...</td>...</tr>
<tr><td>...</td><td>...</td>...</tr>
...
<tr><td>...</td><td>...</td>...
 <td>
 <form action="...">
  <input ...>
  <input ...>
  ...
 </form>
 </td>
</tr>
</table>
<form action="...">
<table>
<tr><td>...</td><td>...</td>...</tr>
<tr><td>...</td><td>...</td>...</tr>
...
<tr><td>...</td><td>...</td>...
 <td>
  <input ...>
  <input ...>
  ...
 </td>
</tr>
</table>
</form>

The modified markup may look illogical, since structurally there is no need to have all the stuff in the other cells inside the form. But it can be done in valid HTML and with well-defined meaning: when the form is submitted, only the form fields matter, so the other content in the form has no effect on how form submission works. And since the (probable) extra spacing after a form appears only after the entire table, the presentational problem is removed, or at least made less important.

There are, however, the following problems with this approach, where the form element contains much more than what logically constitutes a form: A visual browser might have (e.g., due to a user style sheet) a special presentation for a form as a whole, e.g. using a distinctive background color or image to make the structure clear. When the markup is illogical, the user will be confused. Similarly, a speech-based user agent probably indicates the start of a form by saying, for example, "start of form 1". This is confusing, if the actual start of the form is far ahead.

An alternative: using just line breaks

Of course, you could dispense with tables within forms. You could simply write e.g.

<FORM METHOD="POST" ACTION="http://jkorpela.fi/cgi-bin/echo.cgi">
Your name: <INPUT TYPE="TEXT" NAME="name" SIZE="20"><BR>
Your E-mail address:
<INPUT TYPE="TEXT" NAME="email" SIZE="25"><BR>
<INPUT TYPE="SUBMIT" VALUE="Submit" NAME="B1"><BR>
</FORM>

On your current browser with its current settings, this would appear as follows:

Your name:
Your E-mail address:

The BR elements cause line breaks. It is largely a matter of taste whether you prefer this style to using tables. The main difference in typical presentation is that when using a table, the input fields "line up" forming a column. And style sheets or presentational attributes in table-related elements could be used to suggest the details of the presentation.

Another alternative: using paragraphs

You could also make each pair of field title and field element into a separate paragraph, a P element, e.g.

<FORM METHOD="POST" ACTION="http://jkorpela.fi/cgi-bin/echo.cgi">
<P>
Your name: <INPUT TYPE="TEXT" NAME="name" SIZE="20">
</P>
<P>
Your E-mail address:
<INPUT TYPE="TEXT" NAME="email" SIZE="25">
</P>
<P><INPUT TYPE="SUBMIT" VALUE="Submit" NAME="B1"></P>
</FORM>

On your current browser with its current settings, this would appear as follows:

Your name:

Your E-mail address:

Although some people might say this would be waste of space, the use of some empty vertical space (as caused by browsers' way of presenting paragraphs) isn't really wasteful.

But since it might be argued that a field name and a field do not constitute a paragraph, you could alternatively use DIV elements instead of P elements. This would introduce no extra vertical spacing.

Yet another alternative: FIELDSET

One way of structuring a form is the FIELDSET element.

<form method="post" action="http://jkorpela.fi/cgi-bin/echo.cgi">
<fieldset>
  <legend>Your name</legend>
  <input type="text" name="name" size="20">
</fieldset>
<fieldset>
  <legend>Your E-mail address</legend>
  <input type="text" name="email" size="25">
</fieldset>
<input type="submit" value="submit" name="b1">
</form>

The following shows the presentation of the form on your current browser (on the left) and on IE 4 (on the right):

Your name

Your E-mail address

[A presentation where the input fields appear in boxes of a special kind with the legends as headings over the top borders of the boxes.]

It is also possible to combine the use of FIELDSET with the use of a table to structurize e.g. a set of radio buttons. For radio buttons, and for checkboxes, the conventional method is to put the associated text after the radio button or checkbox. This is somewhat illogical but so common that accessibility tools might handle it better than the logical order. Example:

<FIELDSET><LEGEND><strong>Gender</strong></LEGEND>
<TABLE BORDER="1" CELLSPACING="0" CELLPADDING="5">
<TR><TD>
<LABEL><INPUT TYPE="RADIO" NAME="gender" CHECKED
VALUE="Unspecified">Unspecified
</LABEL><TD>
<LABEL><INPUT TYPE="RADIO" NAME="gender"
VALUE="Female">Female</LABEL>
<TD>
<LABEL><INPUT TYPE="RADIO" NAME="gender" VALUE="Male">Male</LABEL>
</TABLE>
</FIELDSET>

This results in the following presentation on your current browser:

Gender

It would perhaps be better (in cases like this at least, when there is a small number of alternatives) if the legend (which is logically a heading for the set of radio buttons) appeared at the same line as the alternatives. But the syntax of FIELDSET makes this impossible: the first element there must be LEGEND, so one cannot organize the legend and the buttons with their labels as one row in a table.

For accessibility reasons, and for clarity, it would be better to make each alternative appear on a line (row) of its own, using the same approach as above but a one-column table instead of a one-row table. Example:

Gender

In this approach, on the other hand, the table markup is rather unnecessary. You could just wrap each LABEL element inside a DIV element.

Using CSS to create tabular look

I have often argued that such a construct is a structural table (tabular data), not a layout table. It expresses the two-dimensional structure of the data in the form, including input fields. But many people disagree. Anyway, let's consider how you could achieve tabular layout for a form without using a table.

There are different approaches, but a simple one is like this: In HTML, inside a form element, use something like

<div><label for="a">a</label><input id="a" name="x"></div>
<div><label for="b">abracadabra</label><input id="b" name="y"></div>
etc.

This works without CSS, though not with a nice layout. For the layout, you could use CSS to suggest a common width for the label elements. This is guesswork to some extent, since you'd like to have width that is sufficient for all labels, but not wider than needed. Example:

label { display: block; width: 6em; float: left; }

This is how it looks like on your browser: