CSS Table Properties
2008 Oct 19
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:
- Every row box surrounds is one row of grid cells. All the row boxes in a table 
fill the table vertically from top to bottom in the order specified plus an 
optional table header row boxes at the top of the table or optional table footer 
row boxes at the bottom of the table.
- A row group's box is same as the row box of grid cells in the row.
- A column box surrounds one or more columns of grid cells. The column boxes 
are placed next to each other in the order they occur. The first column is on the 
left for left-to-right languages, and on the right for right-to-left languages.
- A column group's box contains the same grid cells of the columns boxes it contains.
- Each spanned cell is one or more grid cells wide and high. Overlap of cells is 
not allowed. In left-to right (right-ro-left) langauges each spanned cell must be 
as far to the left (right) as possible.
- A cell's box cannot extend beyond the last row box of a table or row group (i.e. 
the cell must be shortened if this would happen).
- All grid cells in a row are the same height, and all grid cells in a column 
are the same width. Rows can be different heights and columns can be different 
widths.
- Although it is possible to position a table cell anywhere, this feature is not well supported by most browsers.
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.
- border:  Borders for columns and column groups can be set only if the 
property border-collapse has the value collapse.
- background:  The background of a column or column group is visible only 
in cells where both the cell and row have transparanet backgrounds.
- width:  This property defines the minimum (not actual) width of 
a column or column group. The needed width is also determined by the content.
- visibility:  If this property value is collapse then none of 
the cells in the column (or group) are rendered. Cells that span from a collapsed 
column are clipped, as are cell that span from other columns to the hidden column. 
A declaration of any value for visibility other than hidden is 
ignored.
Table Display (property) Values
- inline-table : Different than 
float, but analagous to 
inline-block (IE gets it wrong):
| CSS+HTML | Results | 
| 
<p>This sentence has a table
<table style="display: inline-table;"
  border=2 bgcolor=#6699CC>
<tr bgcolor=#CC66FF>
<td>embedded (but not</td>
</tr>
<tr bgcolor=#CC66FF>
<td>on the baseline)</td>
</tr>
</table>
in it.</p>
 | This sentence has a table
 
in it.
| embedded (but not |  
| on the baseline) |  | 
- table : the element is a block-level table, in HTML this is the 
table element; in XML could be any element.
| CSS+HTML | Results | 
| 
<p>This sentence has a table
<table border=2 bgcolor=#6699CC>
<tr bgcolor=#CC66FF>
<td>embedded</td>
</tr>
<tr bgcolor=#CC66FF>
<td>(but not inline)</td>
</tr>
</table>
in it.</p>
 | This sentence has a table
 
in it.
| embedded |  
| (but not inline) |  | 
- table-caption : Specifies content for caption, see 
caption-side.
- table-cell : Specifies an element represnting a 
singe cell. Equivalent to HTML <td> and <th> elements.
- table-column : An element which describes a column of 
cells. Has no associated renedering (like value none). Is used to defined the 
presentation of cells within the column. Equivalent to HTML <col> element.
- table-column-group : Specifies an element which 
groups one or more columns (also not rendered). Used for defining presentation of 
elements within group. Equivalent to HTML <colgroup> element.
- table-footer-group : Like table-header-group, 
except displays after all other rows and row groups and before bottom caption. 
In print may be repeated on bottom of  page
- table-header-group : Like table-row-group, 
except this group is displayed before other rows and row groups and after 
top caption. In print may be repeated at top of every page.
- table-row : Specifies an element that is a row of cells, 
corresponds to HTML <tr> element.
- table-row-group : Specifies an element groups one or more 
rows, corresponds to HTML <tbody> element.
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:
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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:
- Table (bottom)
- Columns groups
- Columns
- Row groups
- Rows
- Cells (top)
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
- Table elements cannot have padding but can have margins. This results in no separation between the border around the outseid of the table and its outermost or 
boundary cells.
- Borders can be applied to cells, rows, row groups, columns, columns groups and 
the table as a whole.
- There is never any separation between cell borders. Adjacent borders collapse 
into each other or merge into one border. This is like margin collapsing where the 
largest margin wins. Cells with the higher precedence border wins (see below).
- Once collapsed, the borders between cells are centered on theoretical grid lines 
between the cells.
- When splitting even sized numbers the agent is free to round up or down or 
displace slightly.
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:
- If one of the collapsing borders has a border-style value of hidden 
it takes precedence over all others. All borders at this location are hidden.
- A border border-style value of none has lowest precedence. This 
is the default border-style.
- If at least one of the adjacent collapsing borders has a value other than 
none or hidden the wider border wins over the narrower border. If more 
than one of the borders have the same width then the border style is taken in the 
following precedence from from most to least preffered: double solid dashed 
dotted ridge outset groove inset.
- If collapsing borders have the ssme style and width but have differing colors, 
then the colr used is taken from an element in the following precedence from most 
to least preffered: cell, row, row group, column, column group, table.
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>
 | 
| r1c1 | r1c2 | r1c3 | r1c4 |  
| r2c1 | r2c2 | r2c3 | r2c4 |  
| r3c1 | r3c2 | r1c3 | r3c4 |  
| r4c1 | r4c2 | r4c3 | r4c4 |  | 
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>
 | 
| r1c1 | r1c2 | r1c3 | r1c4 |  
| r2c1 | r2c2 | r2c3 | r2c4 |  
| r3c1 | r3c2 | r1c3 | r3c4 |  
| r4c1 | r4c2 | r4c3 | r4c4 |  | 
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>
 |  | 
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:
- A column element whose width property whose value is not auto sets 
the width for the column.
- 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.
- Any coluns that are still have width of auto are sized so that their widths 
are equal as possible.
- 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.
- For each cell in a column calculate the minimum and maximum width.
  - Determine minimum width for the content allowing that content to flow across
      multiple lines (but not just out of the cell's box). If the width value
      is greater than the minimum value set the minimum to that larger value. If the 
      cell's width value is auto then the minimum cell width is the minimum 
      content width.
- For the maximum width determine the width required to display the content 
      without any non forced line breaking, i.e. by <br>.
- For each column calculate the min and max width.
  - The column's minimum width is the largest cell width in the column. 
      If the column has been given an explicit width which is larger than this 
      minimum width then that is the minimum column width.
- For the maximum column width talke the largest cell width in the column. 
      If the column has been given an explicit width which is larger than this 
      maximum width then that is the maximum column width.
- 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:
- 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.
- 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:
- The effect pf percentage height for table cells.
- The effect of percentage height for table rows and row groups.
- How a row-spanning cell effects the heights of the spanned rows, 
excpet that the rows must contain the spanned cell.
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:
- If any of the cells is baseline aligned then the row's baseline is 
determined and the content of baseline aligned cells are placed.
- 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.
- 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.
- 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.
- 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.