Table Formatting
Tables are the most complex elements in HTML, and table formatting is among the most complex parts of CSS.
CSS defines a number of objects that are involved in table formatting, as Figure 1 reveals.
A table may contain a caption, row groups, and column groups. A row group contains rows, while a column group contains columns. Rows and columns contain cells. Tables are rendered as layers in a specified order from the bottom up: table, column groups, columns, row groups, rows, and cells.
The table model in HTML is row-centric. Although you can specify columns and column groups in markup, cells are structurally contained within rows. Columns and column groups are more esoteric items that are derived from the set of cells in all rows of the table.
A table can be included in a formatting context as either a block-level or inline-level box. It can have padding, borders, and margins.
A table element generates an anonymous box that encompasses the table box and the caption box (if they’re present). The caption box is rendered outside the table box, but is inextricably tied to it. When a table is repositioned, it’s the outer anonymous box that’s moved to enable the caption to follow the table.
Captions inherit inheritable properties from the table. A caption is formatted as a block box, but it doesn’t behave like general block boxes in all respects. If a run-in element precedes the table, it will not run into a caption box.
The placement of the caption can be controlled via the
caption-side property. The valid values in CSS2.1 are
top and bottom, which should be
fairly self-explanatory.
The internal elements of tables—row groups, column groups, rows, columns, and cells—generate regular boxes that can have borders. Cells can also have padding, but internal table objects don’t have margins.
Ten of the valid values for the display property
denote table-related formatting styles. These values, and the HTML element
types with which they’re associated by default, are shown in Table display Property Values.
| Element Type | Property Value | HTML Element |
|---|---|---|
| Table | table |
table |
inline-table |
n/a | |
| Caption | table-caption |
caption |
| Row group | table-header-group |
thead |
table-footer-group |
tfoot |
|
table-row-group |
tbody |
|
| Row | table-row |
tr |
| Column group | table-column-group |
colgroup |
| Column | table-column |
col |
| Cell | table-cell |
td |
th |
These display values can also be specified for other element types than those that belong to the HTML table model; however, Internet Explorer versions up to and including 7 don’t support these values.
When table-related display values are used for
non-table elements, anonymous table-related elements may have to be
generated in order to render the elements correctly. Here, we’ve listed
situations in which anonymous table-related elements may be created:
- Cells must have a row as their parent. A row object will be generated as the parent of one or more consecutive cells that don’t have a row as their parent.
- Rows must have a row group or a table as their parent. Columns must have a column group or a table as their parent. Row groups and column groups must have a table as their parent. A table object will be generated as the parent of one or more consecutive objects of those types that don’t have the required parent.
- If a child of a table object is not a caption, row group, column group, row, or column, a row object will be generated as the parent of that child, and any consecutive siblings that require a row as their parent.
- If a child of a row group object isn’t a row, a row object will be generated as the parent of that child and any consecutive siblings that require a row as their parent.
- If a child of a row object is not a cell, a cell object will be generated as the parent of that child and any consecutive siblings that are not cells.
Properties that Apply to Column and Column-group Elements
Only a few properties can be applied to elements with a
display property value of
table-column or
table-column-group:
- the
borderproperties, but only in the collapsing borders model (see below) - the
backgroundproperties, where cells and rows have transparent backgrounds - the
widthproperty - the
visibilityproperty valuecollapse—any other visibility values are ignored for columns and column groups
Table Width Algorithms
Unlike other block
boxes, a table with zero horizontal margins and a width
property that’s set to auto doesn’t size to fill its
containing block. Instead, the table size will be determined by its
contents. A table can be horizontally centered by setting
margin-left and margin-right to
auto, though.
There are two very different
algorithms for determining the widths of table columns: the fixed table
layout algorithm and the automatic table layout algorithm. These are
specified with the table-layout property (which takes
values of fixed, for fixed layouts, and
auto, for automatic layouts); its initial value is
auto. If the table’s width is
specified as auto, the automatic table layout
algorithm is normally used. In the case of block-level tables (when
display is set to table), user
agents are allowed to use the fixed table layout algorithm anyway, but
they aren’t required to.
With the fixed table layout algorithm, the widths of columns and of the table are not governed by the contents of the table’s cells. Instead, the width of each column is determined as follows:
- Column objects whose
widthis notautoset the width for that column. - A cell in the first row, whose
widthis notauto, sets the width of the column it belongs to. If the cell spans more than one column, the width is divided over the columns. - Any remaining columns equally divide the remaining horizontal space, minus any borders or cell spacing.
The width of the table is the greater of the value of the
table’s width property, and the sum of the column
widths (plus borders or cell spacing). If the table is wider than the
columns, the extra space will be distributed over the
columns.
Since the cells in the first row of the table are used to determine the column widths, you shouldn’t omit any cells from the first row if you use the fixed table layout algorithm. The behavior in such case is undefined by the CSS2.1 specification.
The automatic table layout algorithm usually requires more than one pass. The CSS2.1 specification suggests an algorithm for determining column widths, but user agents are not required to use it.
The suggested algorithm for determining column widths examines every cell in the entire table, computing the minimum and maximum widths required for rendering each cell. These values are then used to determine how wide each column should be, which in turn may decide the width of the table itself.
Since every single cell must be inspected, the automatic table layout algorithm can become very time-consuming when it’s calculated for a table with a large number of rows and/or columns.
Table Height Algorithms
If the table’s
height property has a value other than
auto, and the specified height differs from the sum
of the row heights plus borders or cell spacing, the behavior is
undefined.
Percentage values for the height
property are undefined for rows, row groups, and cells.
The
vertical-align property of each cell determines its
alignment within the row. Only the values baseline,
top, bottom, and
middle are allowed. For any other value,
baseline will be used.
Borders On Table Objects
There are two
different models in CSS2 for rendering borders around internal table
objects: the separated borders model and the collapsing borders model. We
can choose the model we prefer by using the
border-collapse property, and setting the value to
separate (the initial value) or
collapse.
In the separated borders model only
cells (and the table itself) can have borders; rows, row groups, columns,
and column groups cannot. Borders are drawn individually around the cells
and the cells are separated by the vertical and horizontal distances
specified by the border-spacing property. In the space
between cell borders, the backgrounds of rows, row groups, columns, and
column groups are invisible. Only the table background is visible in the
inter-cell spacing. Figure 2 shows an
example of a table that’s rendered using the separated borders
model.
Here’s the relevant CSS for the table:
table {
border-collapse: separate;
border-spacing: 1em 0.5em;
background-color: #ddd;
}
Another property that applies in the separated borders model is
the empty-cells property. It controls whether cells
that lack visible content have borders and backgrounds (if the value is
show, the initial value) or not (if the value is
hide). Carriage returns, line feeds, tabs, and blanks
are not considered to be visible content, although a non-breaking space
is.
In the collapsing borders model, the cells aren’t separated from one another and their borders—along with borders of rows, row groups, columns, column groups and the table itself—collapse (or overlap) in a rather complicated way. An example of a table to which the collapsing borders model is applied is shown in Figure 3.
With this model, quite a few borders may be specified in such a
way that they would be rendered in the same place. The CSS2.1
specification provides an algorithm for border conflict resolution—that
is, which border will win, or be rendered, in these situations. Very
broadly speaking, the most eye-catching border will be rendered, unless at
least one of the borders has border-style set to
hidden, in which case no border will be
rendered.
If none of the borders are hidden, wide borders win over
narrow borders. If two or more borders have the same width, the
border-style property decides which one will be
rendered. The styles are preferred in the following order:
double, solid,
dashed, dotted,
ridge, outset,
groove, and inset. Borders with
border-style set to none have the
lowest priority, and will never win over other border styles—even if they
have a large width value.
If there is still no winner, the algorithm looks at the objects for which the borders are set. The preferred order is: cell, row, row group, column, column group, and table.
The
border-spacing and empty-cells
properties are ignored when the collapsing borders model is
used.
User-contributed notes
Add a note
To post a note on this topic, please log in with your SitePoint username and password. If you don't have an account yet, you can create a new account for free.
