CSS Table Properties

2008 Oct 19

Anonymous
Table Objects
Table Display
(property) Values
Table
Layers
Table Cell
Borders
Table
Size
Table
Alignment

Property Values Initial
Value
Applies to elements
with display value
Inherited
caption-side top | bottom top table-caption no
border-collapse collapse | separate | inherit separate table or inline-table yes
border-spacing <length> <length>? | inherit 0 table or inline-table yes
empty-cells show | hide | inherit show table-cell yes
table-layout auto | fixed | inherit auto table or inline-table yes

There is currently no CSS property to center a table. A table can be centered either with the align attribute, or by emebedding the table in a <div> element (which can be centered using CSS).

While the CSS specifications do not forbid it, IE does not support assigning table related display property values to non table elements. Currently IE does not support property empty-cells.


There is a CSS distinction between table elements and internal table elements in that the latter do not have margins.

The rules for tables use the concept of a grid cell which is the rectangular space of a simple cell, <td>, ignoring merged cells because or colspan or rowspan. Thus actual borders will pass through merged cells. Table rules:

Rows are explicitly declared in table markup. Columns are implicit, or derived, by the sequence of cells within the rows. It is not possible to reverse this row orientation (e.g. in HTMl or XML). Columns and column groups can only accept four styles: border background width visibility - see constraints below.


Table Display (property) Values

In XML, where there is no predefined table, these display property values are essential.


caption-side

A caption is rendered as a block box placed immediately before (or after) the table's box, with some excpetions. (1) The caption can inhereit values from the table, and (2) the renedering agent ignores a caption's box when condidering what to do with a run-in element that precedes the table. Thus a run-in element before the table will not overlap the caption or the table, but will be treated as if its display value is block.


empty-cells

If a cell has no content and this propert value is show then the borders and background are rendered. If the value is hide then no part of the cell is rendered (same as a visibility of hidden). If all cells in a row are empty and all are hidden then the entire row is treated as if teh row element were set to display value of none.


Anonymous Table Objects

When there are not enough elements to fully represent a table (e.g. some rows do not have enough cells, or a row declartion is missing for some cells) then CSS defines a mechanism for inserting the missing parts. These object insertion rules follow:

  1. If a table-cell element's parent is not a table-row element then an anonymous table-row is inserted between the table-cell element and its parent and will include all following sibling table-cells. This applies also when the parent is a table-row-group.
  2. If a table-row element's parent is not a table, inline-table or table-row-group element then an anonymous table is inserted between the table-row element and its parent. The inserted table will include all consecutive siblings of the table-row element.
  3. If a table-column element's parent is not a table, inline-table or table-column-group element then an anonymous table is inserted between the table-column element and its parent.
  4. If the parent element of a table-row-group, table-header-group, table-footer-group or table-column-group element is not a table element then an anonymous table object is inserted between the element and its parent and contains the sequential partial table elements.
  5. If a child element of a table or inline-table element is not a table-row-group, table-header-group, table-footer-group or table-caption element then an anonymous table-row element is inserted between the table... element and the child elelemnt. This anonymous row object contains all consecutibe sibling of the child element that are not table-row-group, table-header-group, table-footer-group, table-row or table-caption elements.
  6. If a child element of a table-row-group, table-header-group or table-footer-group element then an anonyomous table-row object is inserted between the element and its child element. This anonymous object spans all consecuive siblings of the child element that are not table-row objects.
  7. If a child element of a table-row element is not a table-cell element then and anonymous table-cell object is inserted between the element and its child element. This inserted anonymous object contains all consecutive siblings of the child element that are not table-cell elements.

Table Layers

A table is rendered in the order from bottom to top. The six conceptual layers, from bottom to top, are:

By default all elements have transparent backgrounds thus allowing seeing through a layer.


Table Cell Borders

There are two border models in CSS. The separated border model is used when cells are separated from each other in the layout. The other model is the collapsed border model in which there is no visual separation between cells and cell borders merge (or collapse). The latter is the default model. The markup author chooses between the models with the border-collapse property.


Collapsed Cell Borders

This is illustrated for a single row of three cells:

Note that half the table border sticks out beyond the table width. The rules for border collapsing or merging are:

The above rules do not cover all cases which leaves it up to the rendering agent. Here is an example of what is covered by the above rules.

CSS+HTML Results
table.bc { border-collapse: collapse; border: 3px outset #990099; }
td.tdbc { border: 1px solid #00CC99; padding: 3px; }
#r2c1, #r2c2 { border-style: hidden; }
#r1c1, #r1c4 { border-width: 5px; }
#r2c4 { border-style: double; border-width: 3px; }
#r3c4 { border-style: dotted; border-width: 2px; }
#r4c1 { border-bottom-style: hidden; }
#r4c1 { border-top: 9px solid #996600; }
...
<table class=bc>
<tr>
<td class=tdbc id=r1c1>r1c1</td><td class=tdbc id=r1c2>r1c2</td>
<td class=tdbc id=r1c3>r1c3</td><td class=tdbc id=r1c4>r1c4</td>
</tr>
<tr>
<td class=tdbc id=r2c1>r2c1</td><td class=tdbc id=r2c2>r2c2</td>
<td class=tdbc id=r2c3>r2c3</td><td class=tdbc id=r2c4>r2c4</td>
</tr>
<tr>
<td class=tdbc id=r3c1>r3c1</td><td class=tdbc id=r3c2>r3c2</td>
<td class=tdbc id=r3c3>r1c3</td><td class=tdbc id=r3c4>r3c4</td>
</tr>
<tr>
<td class=tdbc id=r4c1>r4c1</td><td class=tdbc id=r4c2>r4c2</td>
<td class=tdbc id=r4c3>r4c3</td><td class=tdbc id=r4c4>r4c4</td>
</tr>
</table>
r1c1r1c2 r1c3r1c4
r2c1r2c2 r2c3r2c4
r3c1r3c2 r1c3r3c4
r4c1r4c2 r4c3r4c4

Separated Cell Borders

In this model every cell has its own border which is distinct from other (adjacent cells) - they are separated by a distance (which could be 0). Thus the borders do not collapse or merge into each other.
CSS+HTML Results
table.bs1 { border-collapse: collapse; 
            border: 3px outset #990099; }
/* all else same as border collapse example above */
...
<table cellspacing=0 class=bs1>
...
</table>
r1c1r1c2 r1c3r1c4
r2c1r2c2 r2c3r2c4
r3c1r3c2 r1c3r3c4
r4c1r4c2 r4c3r4c4

border-spacing

The borders may touch (as in this case since table attribute cellspacing=0) yet remain what they are for each cell. In CSS the cellspacing attribute is replaced or supplemented with the more flexible border-spacing property which is ignored unless table property border-collapse value is separate.

When one <length> is given all cells are separated by the specified amount. When two values are given the first value is the horizontal spacing and the second is the vertical spacing. These spacing values are also applied between boundary cells and the padding on the table element as a whole.
CSS+HTML Results
table.bs2 { border-collapse: separate; 
            border: 3px outset #990099; 
            border-spacing: 13px 3px; padding: 5px; }
#s1 { border: 1px solid; }
#s2 { border: 3px dotted; }
#s3 { border: 3px dashed; }
#s4 { border: 1px double; }
...
<table class=bs2>
<tr>
<td id=s1>S1</td><td id=s2>S2</td>
</tr>
<tr>
<td id=s3>S3</td><td id=s4>S4</td>
</tr>
</td>
</tr>
</table>
S1S2
S3S4


Table Size and table-layout

The calculation rules or algorithm for width and height are different.


Width

This property chooses between the two ways to specify width.

Fixed layout

The fixed width case is faster to calculate for the rendering agent. This is because layout does not depend on contents of cells only on the widths of cells and the table, as follows:

  1. A column element whose width property whose value is not auto sets the width for the column.
  2. If a column has an auto width, but the cell in the first row of the table in that column has a width other than auto the the cell sets the width for the column. If the cell spans multiple columns then the width is divided between the columns.
  3. Any coluns that are still have width of auto are sized so that their widths are equal as possible.
  4. The width of of the table is set to either the greater of (a) the width for the table (if specified) or (b) the sum of the columns widths. If the table is wider than the sum of the columns the difference is plit evenly among the columns.

The table width is thus determined primarily by the first row. The cells in rows after the first cannot affect the size. If the contents of these subsequent rows does not fit then oveflow value for the cell determines whether the contents are clipped, visible or generate a scroll bar.

Automatic layout

The automatic case is slower to calculate because all the contents of each cells have to be examined befroe widths can be known. This model is usually chosen for tables with a width of auto (though not guaranteed for all agents). Each cell whose width is larger than the current column width causes all cells above it in the column to effectively be layed out again.

  1. For each cell in a column calculate the minimum and maximum width.
  2. For each column calculate the min and max width.
  3. When a cell spans more than one column, the sum of the minimum column widths must be equal to the minimum cell width for the spanning cell. The sum of the maximum column widths has to equla the spanning cell's maximum width. Agents divide any changes in column width equally among spanned columns.

If any width is a percentage then it is calculated in relation to the width of the table as follows:

  1. If the computed width of the table is not auto then the table width is compared to the sum of all columns widths plus an borders and cell spacing. This is when any percentage width is used. If the table's computed width is greater than the sum of the column widths, borders and cell spacing then the excess is split equally among the columns.
  2. If the computed width of the table is auto then the table width is calculated by adding up the column widths, borders and cell spacing; talking int oaccount any width percentages.

Height

If the height is set explicitly then that is height. The specification does not specify what to do when the calculated height is larger or smaller than this value. Usually row hieght or expanded or shrunk to adjust.

If the hieght is auto then the height is the sum of the height of all the rows plus borders, cell spacing and caption. Thehieght of each row is calculated in a way similar to widths.

The specification does not define:


Table Alignment

To horizontally align with a cell use the text-align property. Similary the vertical alignment of a cell is controlled by the vertical-align property. Both of these treat the cell as a block level element.

If the vertical-align property is baseline then the baseline of the cell is aligned with the baseline of the first row it spans. A row's baseline is dfined by the baseline of the first line of text in the row (even if wrapped). The detailed rules for aligning cell contents within a row are:

  1. If any of the cells is baseline aligned then the row's baseline is determined and the content of baseline aligned cells are placed.
  2. Any top aligned cell has its content placed. This gives the row a minimum height value defined by the lowest cell bottom of the cells whose content has already been placed.
  3. If any remaining cells are middle or bottom aligned and the content height is greater than the current row height then the current row height is increased to this greater value.
  4. All reamining cells have their content placed. Any cell whose content is shorter than the row height has teh cell's padding increased to match the difference.
  5. The vertical-align values sub super text-top text-bottom are ignored when applied to table cells.

The table as a whole is still aligned using the align attribute.