Thursday, November 15, 2007

Tables in forms: an [X]HTML conundrum

Question: what does this mean?


<!ELEMENT table
(caption?, (col*|colgroup*), thead?, tfoot?, (tbody+|tr+))>
<!ELEMENT caption %Inline;>
<!ELEMENT thead (tr)+>
<!ELEMENT tfoot (tr)+>
<!ELEMENT tbody (tr)+>
<!ELEMENT colgroup (col)*>
<!ELEMENT col EMPTY>
<!ELEMENT tr (th|td)+>
<!ELEMENT th %Flow;>
<!ELEMENT td %Flow;>

<!ELEMENT form %form.content;>

<!ENTITY % form.content "(%block; | %misc;)*">

<!ENTITY % block
"p | %heading; | div | %lists; | %blocktext; | fieldset | table">

<!ELEMENT fieldset (#PCDATA | legend | %block; | form | %inline; | %misc;)*>


Answer: it's a selection of parts of the XHTML 1.0 DTD[0] and it requires that:
  • table elements can only contain other table elements until you reach td and th elements (which are largely interchangeable in DTD terms);
  • fieldsets can only contain block elements like headings, paragraphs and entire tables.

In addition, accessibility concerns[1] require that:
  • fieldsets are used to group form inputs together[2], to create a human-comprehensible and navigable structure (this is analagous to the typographical and gestalt formatting tat we would use in a well-designed printed form). W3C advise HTML authors to 'Divide large blocks of information into more manageable groups';
  • the XHTML generated conforms to the DTD (is valid for the flavour of HTML used). Otherwise the page won't display predictably, so that's good.

The corollary of these requirements is that tables cannot be used to lay out a table form, unless each fieldset is contained within a single cell (td|th). Trouble is, the whole point of the table is usually to use the cells to discriminate between items; one of the chief discriminations would be between a 'container' like a category or a question and the elements that are contained, like the set of answers (usually represented by a set of checkboxes or radios, though there could be a mix including drop-downs, text boxes or whatever.

I think this is a real weakness in the XHTML DTD. It does not appear to be changing in XHTML2 or HTML5[3,4], and that's reasonable given that these are evolutionary updates and the problem here looks like it is part of the 'layout tables are bad' mantra (there's currently a note on http://www.w3.org/html/wg/html5/ that says 'we need some editorial text on how layout tables are bad practice and non-conforming' - and that's good). In fact, the problem is a different one: designers need to be able to rationise layout of complex data in various ways; tables can be legitimately used to do this; and sometimes that rationalisation is in the context of asking questions with a form. Because a form has its own, complex element structure, there's a problem when the form and the table are interleaved. Currently that problem is solved by restricting the degree to which the table and the form can be interleaved (wrap the form around the table and then place fieldsets inside td or th elements). I believe what's required is to allow fieldsets to wrap around tbody or tr elements.

One final point: it appears from the definition of fieldset in [0] that you can put a form inside it. Interesting, given that a form cannot contain another form (that's the intention of two comments: '<!-- forms shouldn't be nested -->' and '<!-- form uses %Block; excluding form -->', both in [0]). So should a fieldset go outside a form, and in this case what's the use? Explanations welcomed.

References


0. http://www.w3.org/TR/xhtml1/dtds.html#a_dtd_XHTML-1.0-Strict
1. http://www.w3.org/TR/WCAG10-HTML-TECHS/
2. http://www.w3.org/TR/WCAG10-HTML-TECHS/#forms-grouping
3. http://www.w3.org/html/wg/html5/#forms
4. http://www.w3.org/html/wg/html5/#tabular

Edits: 2008-07-08: corrected table to form

0 Comments:

Post a Comment

<< Home