CSS table model ideas

22 June 1997

Bert Bos

Status of this document

This is a personal memo for consideration by the CSS&FP WG.

Abstract

This memo outlines the constraints for the CSS table model, suggests (part of) a possible model and the accompanying syntax.

Requirements

The requirements for the CSS table model are as follows. Some requirements may be more important than others.

  1. Handle the full HTML table model (RFC ????).
  2. Be able to turn HTML description lists into tables.
  3. Be able to transpose HTML tables.
  4. Not be able to change the number of columns/rows/cells or the rowspan/colspan of cells.
  5. Be easy to understand.
  6. Support all table styles as found on screen and in print. (See examples.)
  7. Allow easy conversion from as many as possible popular text processors.
  8. Not require changes to the CSS cascading model, datastructures, or syntax.
  9. Allow progresive rendering, at least if the table author has made provisions for it.
  10. Allow all table styles without requiring extra markup in the source.
  11. Support as many SGML table models as possible, in view of XML support.
  12. Be easy to implement.
  13. Have good fallback behavior for less powerful display devices and software.

SGML table models

There are essentially three possible ways in which a table can be marked up in an SGML document:

  1. Row-oriented

    The markup represents the desired visual structure, with cells sorted by row. The HTML table model is of this type, as is the TEI model. This is the most common type.

  2. Column-oriented

    The cells are sorted by column. This is rare. (Note that the HTML table model has elements that represent the columns, but they don't contain the cells.)

  3. Semantic markup

    The markup represents relationships between elements, but without referring to the visual relations of rows and columns. The visual representation doesn't have to be a table, but could be. The DL element in HTML is of this type.

To make things a bit simpler, we assume that a cell in the table corresponds to an element in the source. A cell may span several columns and rows, but its contents come from a single element, and all that element's content go into the same cell. An element that acts as a cell cannot contain descendants that are also cells in the same table.

To make it easier to know when a table ends, we also assume that all cells have a common ancestor, and that all descendants of that element are either ignored (i.e., not displayed) or can be assigned one of the roles discussed below.

Visual table model

In a visual table, we can distinguish the following elements:

In right-to-left text, the words `left' and `right' above should be reversed.

There are at least three ways of rendering the separators:

  1. Cells have their own borders, which are distinct from the borders of neighbouring cells:

  2. Borders are separators between cells; they are, in a way, shared:

  3. Borders are centered on the edges of the cells, and overlap with the cells:

Methods 2 and 3 are common in desktop publishing, method 1 is used in some Web browsers, because it works well with the Motif 2½D-look.

Real world examples

A number of examples of tables were collected over a year ago.

CSS syntax to refer to the visual parts

In CSS, properties are primarily attached to elements in the source tree. When there are visual areas that do not directly correspond to an element, a pseudo-element may solve the problem. Examples are ":first-letter" and ":marker" (a proposal in WD-frosting).

If there are areas shared by a number of elements, cascading and inheritance are the usual solution.

However, if the shared area is shared among elements that are not in a parent-child relation, an ad-hoc rule is introduced. An example is the treatment of whitespace between paragraphs: the rule is that the largest whitespace wins.

In tables, we have this problem with regard to the borders, if we accept that they are shared, and with regard to the fact that columns and rows both describe the same area, but only one of them is a parent of the cell in the SGML sense.

For borders, I propose to use a rule similar to the vertical margin one: the thickest border wins.

For columns and rows I propose simply that they are regarded as not corresponding to a visual area. That is, (almost) none of the CSS1 properties applies to rows and columns, although they are inherited normally.

How this works out in detail can be seen in a draft specification and in the examples.

Mapping the document structure to the visual structure

Rendering the document structure as a table requires mapping each of the elements that represent a cell to the right column(s) and row(s). Other elements must be mapped to other roles, or be ignored.

Rows and columns can be identified by numbers or by names. Mapping involves finding the right names or numbers for each cell. In some cells the right column or row may be given explicitly, such as in an attribute. Usually, however, the row and column is implicit in the order of the cells. This is the case, e.g., in the HTML table model.

The HTML table model also shows how explicit assignment of cells to rows and columns can be done: AXIS attributes define symnolic names for the rows and columns, while AXES attributes specify the rows and columns to which a cell belongs. But in HTML these attributes are not required, so the renderer cannot rely on them.

Example using explicit axes

This XML fragment shows how explicit (named) relationships between elements could be used to build a table:

<measurements>
<time>
<label axis="may">May</label>
<label axis="jun">June</label>
<label axis="jul">July</label>
</time>
<molecule>
<label axis="CO2">CO<sub>2</sub></label>
<label axis="NOx">NO<sub>x</sub></label>
</molecule>
<place>
<label axis="ams">Amsterdam</label>
<label axis="par">Paris</label>
</place>
<data>
<data axes="may,CO2,ams">327</data>
<data axes="may,NOx,ams">12</data>
...
</data>
</measurements>

There are actually three axes here, so we'll have to choose the main ones. The following renderings could all be made out of the same data:

  1. Rendering 1
    May June July
    CO2 NOx CO2 NOx CO2 NOx
    Amsterdam 327 12 ... ... ... ...
    Paris ... ... ... ... ... ...
  2. Rendering 2
    Amsterdam Paris
    CO2 May 327 ...
    June ... ...
    July ... ...
    NOx May 12 ...
    June ... ...
    July ... ...

Note that some of the labels had to be repeated, since a 3D table wasn't possible.

Example using implicit numbering

The following fragment of HTML shows how implicit ordering of elements defines the position in a table:

<table>
<tr><th>       <th>Head A  <th>Head B  <th>Head C
<tr><th>Head 1 <td>Data A1 <td>Data B1 <td>Data C1
<tr><th>Head 2 <td>Data A2 <td>Data B2 <td>Data C2
</table>

One rendering could be like this:
Head 1 Head 2
Head A Data A1 Data A2
Head B Data B1 Data B2
Head C Data C1 Data C2

"Data B1", for example, is the 3rd child of the 2nd child of TABLE, so it it assigned to the 3rd row and the 2nd column.

When elements span columns and rows, the counting can become more difficult.


Bert Bos












Last modified: Fri Jun 27 18:39:28 MET DST