Tables represent
relationships between data. Authors specify these relationships in the
document language and specify
their presentation in CSS, in two ways: visually and aurally.
Authors may specify the visual formatting of a table as a
rectangular grid of cells. Rows and columns of cells may be organized
into row groups and column groups. Rows, columns, row groups, row
columns, and cells may have borders drawn around them (there are two
border models in CSS2). Authors may align data vertically or
horizontally within a cell and align data in all cells of a row or
column.
Authors may also specify the aural rendering of a table; how
headers and data will be spoken. In the document language, authors may
label cells and groups of cells so that when rendered aurally, cell
headers are spoken before cell data. In effect, this "serializes" the
table: users browsing the table aurally hear a sequence of headers
followed by data.
Example(s):
Here is a simple three-row, three-column
table described in HTML 4.0:
<TABLE>
<CAPTION>This is a simple 3x3 table</CAPTION>
<TR id="row1">
<TH>Header 1 <TD>Cell 1 <TD>Cell 2
<TR id="row2">
<TH>Header 2 <TD>Cell 3 <TD>Cell 4
<TR id="row3">
<TH>Header 3 <TD>Cell 5 <TD>Cell 6
</TABLE>
This code creates one table (the TABLE element), three
rows (the TR elements), three header cells (the TH elements),
and six data cells (the TD elements). Note that the three columns
of this example are specified implicitly: there are as many
columns in the table as required by header and data cells.
The following CSS rule centers the text horizontally
in the header cells and present the data with a bold font weight:
TH { text-align: center; font-weight: bold }
The next rules align the text of the header cells on their baseline
and vertically centers the text in each data cell:
TH { vertical-align: baseline }
TD { vertical-align: middle }
The next rules specify that the top row will be surrounded by a 3px
solid blue border and each of the other rows will be surrounded by a
1px solid black border:
TABLE { border-collapse: collapse }
TR#row1 { border-top: 3px solid blue }
TR#row2 { border-top: 1px solid black }
TR#row3 { border-top: 1px solid black }
Note, however, that the borders around the rows overlap where the
rows meet. What color (black or blue) and thickness (1px or 3px) will
the border between row1 and row2 be? We discuss this in the section on
border conflict resolution.
The following rule puts the table caption above the table:
CAPTION { caption-side: top }
Finally, the following rule specifies that, when rendered aurally,
each row of data is to be spoken as a "Header, Data, Data":
TH { speak-header: once }
For instance, the first row would be spoken "Header1 Cell1 Cell2".
On the other hand, with the following rule:
TH { speak-header: always }
it would be spoken "Header1 Cell1 Header1 Cell2".
The preceding example shows how CSS works with HTML 4.0 elements;
in HTML 4.0, the semantics of the various table elements (TABLE,
CAPTION, THEAD, TBODY, TFOOT, COL, COLGROUP, TH, and TD) are
well-defined. In other document languages (such as XML applications),
there may not be pre-defined table elements. Therefore, CSS2 allows
authors to "map" document language elements to table elements via
the 'display' property. For
example, the following rule makes the FOO element act like an HTML
TABLE element and the BAR element act like a CAPTION element:
FOO { display : table }
BAR { display : table-caption }
We discuss the various table elements in the following section. In
this specification, the term table element refers to any element
involved in the creation of a table. An "internal"
table element is one that produces a row, row group, column,
column group, or cell.
The CSS table model is based on the HTML 4.0 table model, in which
the structure of a table closely parallels the visual layout of the
table. In this model, a table consists of an optional caption and any
number of rows of cells. The table model is said to be "row primary"
since authors specify rows, not columns, explicitly in the document
language. Columns are derived once all the rows have been specified --
the first cell of each row belongs to the first column, the second to
the second column, etc.). Rows and columns may be grouped structurally
and this grouping reflected in presentation (e.g., a border may
be drawn around a group of rows).
Thus, the table model consists of tables, captions,
rows, row groups, columns, column groups, and cells.
The CSS model does not require that the document language include elements
that correspond to each of these components. For document languages
(such as XML applications) that do not have pre-defined table
elements, authors must map document language elements to table
elements; this is done with the 'display' property. The following
'display' values assign table
semantics to an arbitrary element:
- table (In HTML: TABLE)
- Specifies that an element defines a block-level table: it
is a rectangular block that participates
in a block formatting
context.
- inline-table (In
HTML: TABLE)
- Specifies that an element defines an
inline-level table: it
is a rectangular block that participates
in an inline formatting
context).
- table-row (In HTML: TR)
- Specifies that an element is a row of cells.
- table-row-group
(In HTML: TBODY)
- Specifies that an element groups one or more
rows.
- table-header-group
(In HTML: THEAD)
- Like 'table-row-group', but for visual formatting,
the row group is always displayed before all other rows and rowgroups
and after any top captions. Print user agents may repeat
footer rows on each page spanned by a table.
- table-footer-group
(In HTML: TFOOT)
- Like 'table-row-group', but for visual formatting, the row group is
always displayed after all other rows and rowgroups and before any
bottom captions. Print user agents may repeat footer rows on each page
spanned by a table.
- table-column (In
HTML: COL)
- Specifies that an element describes a column of cells.
- table-column-group
(In HTML: COLGROUP)
- Specifies that an element groups one or more columns.
- table-cell (In HTML:
TD, TH)
- Specifies that an element represents a table cell.
- table-caption (In
HTML: CAPTION)
- Specifies a caption for the table.
Elements with 'display' set
to 'table-column' or 'table-column-group' are not rendered (exactly as
if they had 'display: none'), but they are useful, because they may
have attributes which induce a certain style for the columns they
represent.
The default style sheet for HTML 4.0
in the appendix illustrates the use of these values for HTML 4.0:
TABLE { display: table }
TR { display: table-row }
THEAD { display: table-header-group }
TBODY { display: table-row-group }
TFOOT { display: table-footer-group }
COL { display: table-column }
COLGROUP { display: table-column-group }
TD, TH { display: table-cell }
CAPTION { display: table-caption }
User agents may ignore these 'display' property values for HTML
documents, since authors should not alter an element's expected
behavior.
Document languages other than HTML may not contain all the elements
in the CSS2 table model. In these cases, the "missing" elements must
be assumed in order for the table model to work. The missing elements
generate anonymous objects (e.g.,
anonymous boxes in visual table layout) according to the following
rules:
- Any table element will automatically generate necessary anonymous
table objects around itself, consisting of at least three nested objects
corresponding to a 'table'/'inline-table' element, a 'table-row'
element, and a 'table-cell' element.
- If the parent P of a 'table-cell' element T is not a 'table-row',
an object corresponding to a 'table-row' will be generated between P
and T. This object will span all consecutive 'table-cell' siblings
(in the document tree) of T.
- If the parent P of a 'table-row' element T is not a 'table',
'inline-table', or 'table-row-group' element, an
object corresponding to a 'table' element will be
generated between P and T. This object will span all consecutive siblings
(in the document tree) of T that require a 'table' parent:
'table-row', 'table-row-group', 'table-header-group',
'table-footer-group', 'table-column', 'table-column-group', and 'caption'.
- If the parent P of a 'table-row-group' (or 'table-header-group' or
'table-footer-group') element T is not a 'table' or 'inline-table', an
object corresponding to a 'table' element will be generated between P
and T. This object will span all consecutive siblings (in the document
tree) of T that require a 'table' parent: 'table-row',
'table-row-group', 'table-header-group', 'table-footer-group',
'table-column', 'table-column-group', and 'caption'.
- If a child T of a 'table-row' element P is not a 'table-cell'
element, an object corresponding to a 'table-cell' element will be
generated between P and T. This object spans all consecutive siblings
of T that are not 'table-cell' elements.
Example(s):
In this XML example, a 'table' element is assumed
to contain the HBOX element:
<HBOX>
<VBOX>George</VBOX>
<VBOX>4287</VBOX>
<VBOX>1998</VBOX>
</HBOX>
because the associated style sheet is:
HBOX { display: table-row }
VBOX { display: table-cell }
Example(s):
In this example, three 'table-cell' elements are assumed
to contain the text in the ROWs. Note that the text is further
encapsulated in anonymous inline boxes, as explained in visual formatting model:
<STACK>
<ROW>This is the <D>top</D> row.</ROW>
<ROW>This is the <D>middle</D> row.</ROW>
<ROW>This is the <D>bottom</D> row.</ROW>
</STACK>
The style sheet is:
STACK { display: inline-table }
ROW { display: table-row }
D { display: inline; font-weight: bolder }
HTML user agents are not required to create
anonymous objects according to the above rules.
Table cells may belong to two contexts: rows and columns. However,
in the source document cells are descendants of rows, never of
columns. Nevertheless, some aspects of cells can be influenced by
setting properties on columns.
The following properties apply to column and column-group elements:
- 'border'
- The various border properties apply to columns only if 'border-collapse' is set to
'collapse' on the table element. In that case, borders set on columns and
column groups are input to the conflict resolution algorithm
that selects the border styles at every cell edge.
- 'background'
- The background properties set the background for cells in the
column, but only if both the cell and row have transparent
backgrounds. See "Table layers and
transparency."
- 'width'
- The 'width' property gives the
minimum width for the column.
- 'visibility'
- If the 'visibility' of a column is set to 'collapse', none of the
cells in the column are rendered, and cells that span into other
columns are clipped. In addition, the width of the table is diminished
by the width the column would have taken up. See "Dynamic effects" below. Other values for
'visibility' have no effect.
Example(s):
Here are some examples of style rules that set properties on
columns. The first two rules together implement the "rules" attribute
of HTML 4.0 with a value of "cols". The third rule makes the "totals"
column blue, the final two rules shows how to make a column a fixed
size, by using the fixed layout
algorithm.
COL { border-style: none solid }
TABLE { border-style: hidden }
COL.totals { background: blue }
TABLE { table-layout: fixed }
COL.totals { width: 5em }
In terms of the visual formatting model,
a table may behave like a block-level or replaced inline-level element. Tables have
content, padding, borders, and margins.
In both cases, the table element generates an anonymous box that contains the
table box itself and the caption's box (if present). The table and
caption boxes retain their own content, padding, margin, and border
areas, and the dimensions of the rectangular anonymous box are the
smallest required to contain both. Vertical margins collapse where
the table box and caption box touch. Any repositioning of the table
must move the entire anonymous box, not just the table box, so
that the caption follows the table.
-
'caption-side'
-
Value: | top | bottom | left | right | inherit
| Initial: | top
| Applies to: | 'table-caption' elements
| Inherited: | yes
| Percentages: | N/A
| Media: | visual
|
This property specifies the position of the caption box with
respect to the table box. Values have the following meanings:
- top
- Positions the caption box above the table box.
- bottom
- Positions the caption box below the table box.
- left
- Positions the caption box to the left of the table box.
- right
- Positions the caption box to the right of the table box.
Captions above or below a 'table' element are formatted very much as
if they were a block element before or after the table, except that
(1) they inherit inheritable properties from the table, and (2) they are
not considered to be a block box for the purposes of any
'compact' or 'run-in' element that may precede the table.
A caption that is above or below a table box also behaves like a
block box for width calculations; the width is computed with respect
to the width of the table box's containing block.
For a caption that is on the left or right side of a table box, on
the other hand, a value other than 'auto' for 'width' sets the width explicitly, but
'auto' tells the user agent to chose a "reasonable width". This may
vary between "the narrowest possible box" to "a single line", so we
recommend that users do not specify 'auto' for left and right caption
widths.
To align caption content horizontally within the caption box, use
the 'text-align'
property. For vertical alignment of a left or right caption box with
respect to the table box, use the 'vertical-align' property. The
only meaningful values in this case are 'top', 'middle', and
'bottom'. All other values are treated the same as 'top'.
Example(s):
In this example, the 'caption-side' property places
captions below tables. The caption will be as wide as the parent of
the table, and caption text will be left-justified.
CAPTION { caption-side: bottom;
width: auto;
text-align: left }
Example(s):
The following example shows how to put a caption in the left
margin. The table itself is centered, by setting its left and right
margins to 'auto', and the whole box with table and caption is shifted
into the left margin by the same amount as the width of the caption.
BODY {
margin-left: 8em
}
TABLE {
margin-left: auto;
margin-right: auto
}
CAPTION {
caption-side: left;
margin-left: -8em;
width: 8em;
text-align: right;
vertical-align: bottom
}
Assuming the width of the table is less than the available width,
the formatting will be similar to this:
Like other elements of the document language, internal table
elements generate rectangular boxes with content, padding, and
borders. They do not have margins, however.
The visual layout of these boxes is governed by a rectangular,
irregular grid of rows and columns. Each box occupies a whole number
of grid cells, determined according to the following rules.
These rules do not apply to HTML 4.0 or earlier HTML versions;
HTML imposes its own limitations on row and column spans.
- Each row box occupies one row of grid cells. Together, the row
boxes fill the table from top to bottom in the order they occur in the
source document (i.e., the table occupies exactly as
many grid rows as there are row elements).
- A row group occupies the same grid cells as the rows it contains.
- A column box occupies one or more columns of grid cells. Column
boxes are placed next to each other in the order they occur. The first
column box may be either on the left or on the right, depending on the
value of the 'direction'
property of the table.
- A column group box occupies the same grid cells as the columns it
contains.
- Cells may span several rows or columns. (Although CSS2 doesn't
define how the number of spanned rows or columns is determined, a user
agent may have special knowledge about the source document; a future
version of CSS may provide a way to express this knowledge in CSS
syntax.) Each cell is thus a rectangular box, one or more grid cells
wide and high. The top row of this rectangle is in the row specified
by the cell's parent. The rectangle must be as far to the left as
possible, but it may not overlap with any other cell box, and must be
to the right of all cells in the same row that are earlier in the
source document. (This constraint holds if the 'direction' property of
the table is 'ltr'; if the 'direction' is 'rtl', interchange
"left" and "right" in the previous sentence.)
- A cell box cannot extend beyond the last row box of a table or
row-group; the
user agents must shorten it until it fits.
Note.
Table cells may be relatively and absolutely positioned, but
this is not recommended: positioning and floating remove a box
from the flow, affecting table alignment.
Here are two examples. The first is assumed to occur in an HTML
document:
<TABLE>
<TR><TD>1 <TD rowspan="2">2 <TD>3 <TD>4
<TR><TD colspan="2">5
</TABLE>
<TABLE>
<ROW><CELL>1 <CELL rowspan="2">2 <CELL>3 <CELL>4
<ROW><CELL colspan="2">5
</TABLE>
The second table is formatted as in the figure on the
right. However, the HTML table's rendering is explicitly undefined by
HTML, and CSS doesn't try to define it. User agents are free to render
it, e.g., as in the figure on the left.
For the purposes of finding the background of each table cell, the
different table elements may be thought of as being on six
superimposed layers. The background set on an element in one of the
layers will only be visible if the layers above it have a transparent
background.
-
The lowest layer is a single plane, representing the table box
itself. Like all boxes, it may be transparent.
-
The next layer contains the column groups. The columns groups are
as tall as the table, but they need not cover the whole table
horizontally.
-
On top of the column groups are the areas representing the column
boxes. Like column groups, columns are as tall as the table, but need
not cover the whole table horizontally.
-
Next is the layer containing the row groups. Each row group is as
wide as the table. Together, the row groups completely cover the table
from top to bottom.
-
The next to last layer contains the rows. The rows also cover the
whole table.
-
The topmost layer contains the cells themselves. As the figure
shows, although all rows contain the same number of cells, not every
cell may have specified content. These "empty" cells are transparent,
letting lower layers shine through.
In the following example, the first row contains four cells, but
the second row contains no cells, and thus the table background shines
through, except where a cell from the first row spans into this
row. The following HTML code and style rules
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
<HTML>
<HEAD>
<STYLE type="text/css">
TABLE { background: #ff0; border-collapse: collapse }
TD { background: red; border: double black }
</STYLE>
</HEAD>
<BODY>
<P>
<TABLE>
<TR>
<TD> 1
<TD rowspan="2"> 2
<TD> 3
<TD> 4
</TR>
<TR><TD></TD></TR>
</TABLE>
</BODY>
</HTML>
might be formatted as follows:
CSS does not define an "optimal" layout for tables since, in many
cases, what is optimal is a matter of taste. CSS does define
constraints that user agents must respect when laying out a
table. User agents may use any algorithm they wish to do so, and are
free to prefer rendering speed over precision, except when the "fixed
layout algorithm" is selected.
-
'table-layout'
-
Value: | auto | fixed | inherit
| Initial: | auto
| Applies to: | 'table'
and 'inline-table' elements
| Inherited: | no
| Percentages: | N/A
| Media: | visual
|
The 'table-layout'
property controls the algorithm used to lay out the table cells, rows,
and columns. Values have the following meaning:
- fixed
- Use the fixed table layout algorithm
- auto
- Use any automatic table layout algorithm
The two algorithms are described below.
With this (fast) algorithm, the horizontal layout of the table does
not depend on the contents of the cells; it only depends on the
table's width, the width of the columns, and borders or cell spacing.
The table's width may be specified explicitly with the 'width' property. A value of 'auto' (for
both 'display: table' and 'display: inline-table') means use the automatic table layout algorithm.
In the fixed table layout algorithm, the width of each column is
determined as follows:
- A column element with a value other than 'auto' for the
'width' property sets the width
for that column.
- Otherwise, a cell in the first row with a value other than 'auto'
for the 'width' property sets the
width for that column. If the cell spans more than one column, the
width is divided over the columns.
- Any remaining columns equally divide the remaining horizontal
table space (minus borders or cell spacing).
The width of the table is then the greater of the
value of the 'width' property
for the table element and the sum of the column widths (plus
cell spacing or borders). If the table is wider than the columns,
the extra space should be distributed over the columns.
In this manner, the user agent can begin to lay out the table once
the entire first row has been received. Cells in subsequent rows do
not affect column widths. Any cell that has content that overflows
uses the 'overflow' property to
determine whether to clip the overflow content.
In this algorithm (which generally requires no more than two
passes), the table's width is given by the width of its columns (and
intervening borders). This algorithm reflects
the behavior of several popular HTML user agents at the writing of
this specification. UAs are not required to implement this algorithm
to determine the table layout in the case that 'table-layout' is 'auto'; they
can use any other algorithm.
This algorithm may be inefficient since it requires the user agent to
have access to all the content in the table before determining the
final layout and may demand more than one pass.
Column widths are determined as follows:
- Calculate the minimum content width (MCW) of each cell: the
formatted content may span any number of lines but may not
overflow the cell box. If the specified
'width' (W) of the cell
is greater than MCW, W is the minimum cell width. A value
of 'auto' means that MCW is the minimum cell width.
Also, calculate the "maximum" cell width of each cell: formatting
then content without breaking lines other than where explicit line
breaks occur.
- For each column, determine a maximum and minimum column width from
the cells that span only that column. The minimum is that required by
the cell with the largest minimum cell width (or the column 'width', whichever is larger). The
maximum is that required by the cell with the largest maximum cell
width (or the column 'width',
whichever is larger).
- For each cell that spans more than one column, increase the
minimum widths of the columns it spans so that together, they are at
least as wide as the cell. Do the same for the maximum widths. If
possible, widen all spanned columns by approximately the same amount.
This gives a maximum and minimum width for each column.
Column widths influence the final table width as follows:
- If the 'table' or 'inline-table' element's 'width' property has a specified value (W)
other than 'auto', the property's computed value is the greater of W
and the minimum width required by all the columns plus cell
spacing or borders (MIN). If W is greater than MIN, the extra width should be
distributed over the columns.
- If the 'table' or 'inline-table' element has 'width: auto', the
computed table width is the greater of the table's containing block
width and MIN. However, if the maximum width required by the columns
plus cell spacing or borders (MAX)
is less than that of the containing block, use MAX.
A percentage value for a column width is relative to the table
width. If the table has 'width: auto', a percentage represents a
constraint on the column's width, which a UA should try to
satisfy. (Obviously, this is not always possible: if the column's
width is '110%', the constraint cannot be satisfied.)
Note. In this algorithm, rows (and row
groups) and columns (and column groups) both constrain and are
constrained by the dimensions of the cells they contain. Setting the
width of a column may indirectly influence the height of a row, and
vice versa.
The height of a table is given by the 'height' property for the 'table' or
'inline-table' element. A value of 'auto' means that the height is the
sum of the row heights plus any cell spacing or borders. Any other
value specifies the height explicitly; the table may thus be taller or
shorter than the height of its rows. CSS2 does not specify rendering
when the specified table height differs from the content height, in
particular whether content height should override specified height; if
it doesn't, how extra space should be distributed among rows that add
up to less than the specified table height; or, if the content height
exceeds the specified table height, whether the UA should provide a
scrolling mechanism. Note. Future versions of CSS
may specify this further.
The height of a 'table-row' element's box is calculated once the
user agent has all the cells in the row available: it is the maximum
of the row's specified 'height'
and the minimum height (MIN) required by the cells. A 'height' value of 'auto' for a
'table-row' means the computed row height is MIN. MIN depends on cell
box heights and cell box alignment (much like the calculation of a line box height). CSS2 does not
define what percentage values of 'height' refer to when specified for
table rows and row groups.
In CSS2, the height of a cell box is the maximum of the table
cell's 'height' property and the
minimum height required by the content (MIN). A value of 'auto' for
'height' implies a computed value
of MIN. CSS2 does not define what percentage values of 'height' refer to when specified for
table cells.
CSS2 does not specify how cells that span more than row
affect row height calculations except that the sum of the row
heights involved must be great enough to encompass the cell
spanning the rows.
The 'vertical-align'
property of each table cell determines its alignment within the row.
Each cell's content has a baseline, a top, a middle, and a bottom, as
does the row itself. In the context of tables, values for 'vertical-align' have the
following meanings:
- baseline
- The baseline of the cell is put at the same height as the baseline
of the first of the rows it spans (see below for the definition of
baselines of cells and rows).
- top
- The top of the cell box is aligned with the top of the first row
it spans.
- bottom
- The bottom of the cell box is aligned with the bottom of the last
row it spans.
- middle
- The center of the cell is aligned with the center of the rows it
spans.
- sub, super, text-top, text-bottom
- These values do not apply to cells; the cell is aligned at the
baseline instead.
The baseline of a cell is the baseline of the first
line box in
the cell. If there is no text, the baseline is the baseline of
whatever object is displayed in the cell, or, if it has none, the
bottom of the cell box. The maximum distance between the top of the
cell box and the baseline over all cells that have
'vertical-align: baseline' is used to set the baseline of the row. Here
is an example:
Cell boxes 1 and 2 are aligned at their baselines. Cell box 2 has
the largest height above the baseline, so that determines the baseline
of the row. Note that if there is no cell box aligned at its
baseline, the row will not have (nor need) a baseline.
To avoid ambiguous situations, the alignment of cells proceeds in
the following order:
- First the cells that are aligned on their baseline are
positioned. This will establish the baseline of the row. Next the
cells with 'vertical-align: top' are positioned.
- The row now has a top, possibly a baseline, and a provisional
height, which is the distance from the top to the lowest bottom of the
cells positioned so far. (See conditions on the cell padding
below.)
- If any of the remaining cells, those aligned at the bottom or the
middle, have a height that is larger than the current height of the
row, the height of the row will be increased to the maximum of those
cells, by lowering the bottom.
- Finally the remaining cells are positioned.
Cell boxes that are smaller than the height of the row receive
extra top or bottom padding.
The horizontal alignment of a cell's content within a cell box is
specified with the 'text-align' property.
When the 'text-align'
property for more than one cell in a column is set to a <string> value, the
content of those cells is aligned along a vertical axis. The beginning
of the string touches this axis. Character directionality determines
whether the string lies to the left or right of the axis.
Aligning text in this way is only useful if the text fits on one
line. The result is undefined if the cell content spans more than one
line.
If value of 'text-align'
for a table cell is a string but the string doesn't occur in the cell
content, the end of the cell's content touches the vertical axis of
alignment.
Note that the strings do not have to be the same for each cell,
although they usually are.
CSS does not provide a way specify the offset of the vertical
alignment axis with respect to the edge of a column box.
Example(s):
The following style sheet:
TD { text-align: "." }
TD:before { content: "$" }
will cause the column of dollar figures
in the following HTML table:
<TABLE>
<COL width="40">
<TR> <TH>Long distance calls
<TR> <TD> 1.30
<TR> <TD> 2.50
<TR> <TD> 10.80
<TR> <TD> 111.01
<TR> <TD> 85.
<TR> <TD> 90
<TR> <TD> .05
<TR> <TD> .06
</TABLE>
to align along the decimal point. For fun,
we have used the :before
pseudo-element to insert a dollar sign before each figure. The table
might be rendered as follows:
Long distance calls
$1.30
$2.50
$10.80
$111.01
$85.
$90
$.05
$.06
The 'visibility' property
takes the value 'collapse' for row, row group, column, and column
group elements. This value causes the entire row or column to be
removed from the display, and the space normally taken up by the row
or column to be made available for other content. The suppression of
the row or column, however, does not otherwise affect the layout of
the table. This allows dynamic effects to remove table rows or columns
without forcing a re-layout of the table in order to account for the
potential change in column constraints.
There are two distinct models for setting borders on table cells in
CSS. One is most suitable for so-called separated borders around individual cells, the
other is suitable for borders that are continuous from one end of the
table to the other. Many border styles can be achieved with either
model, so it is often a matter of taste which one is used.
-
'border-collapse'
-
Value: | collapse | separate | inherit
| Initial: | collapse
| Applies to: | 'table' and 'inline-table' elements
| Inherited: | yes
| Percentages: | N/A
| Media: | visual
|
This property selects a table's border model. The value 'separate'
selects the separated borders border model. The value 'collapse'
selects the collapsing borders model. The models are described below.
The lengths specify the distance that separates adjacent cell
borders. If one length is specified, it gives both the horizontal and
vertical spacing. If two are specified, the first gives the horizontal
spacing and the second the vertical spacing. Lengths may not be
negative.
In this model, each cell has an individual border. The
'border-spacing' property
specifies the distance between the borders of adjacent cells. This
space is filled with the background of the table element. Rows,
columns, row groups, and column groups cannot have borders (i.e., user
agents must ignore the border properties for
those elements).
Example(s):
The table in the figure below could be the result of a style sheet
like this:
TABLE { border: outset 10pt;
border-collapse: separate;
border-spacing: 15pt }
TD { border: inset 5pt }
TD.special { border: inset 10pt } /* The top-left cell */
-
'empty-cells'
-
Value: | show | hide | inherit
| Initial: | show
| Applies to: | 'table-cell'
elements
| Inherited: | yes
| Percentages: | N/A
| Media: | visual
|
In the separated borders model, this property controls the
rendering of borders around cells that have no visible content. Empty
cells and cells with the 'visibility' property set to
'hidden' are considered to have no visible content. Visible content
includes " " and other whitespace except ASCII CR ("\0D"), LF
("\0A"), tab ("\09"), and space ("\20").
When this property has the value 'show', borders are drawn
around empty cells (like normal cells).
A value of 'hide' means that no borders are drawn around
empty cells. Furthermore, if all the cells in a row have a value of
'hide' and have no visible content, the entire row behaves as if
it had 'display: none'.
Example(s):
The following rule causes borders to be drawn around
all cells:
TABLE { empty-cells: show }
In the collapsing border model, it is possible to
specify borders that surround all or part of a cell, row, row group,
column, and column group. Borders for HTML's "rule" attribute can be
specified this way.
Borders are centered on the grid lines between the cells. User
agents must find a consistent rule for rounding off in the case of an
odd number of discrete units (screen pixels, printer dots).
The diagram below shows how the width of the table, the widths of
the borders, the padding, and the cell width interact. Their relation
is given by the following equation, which holds for every row of the
table:
row-width = (0.5 * border-width0) +
padding-left1 + width1 +
padding-right1 +
border-width1 +
padding-left2 +...+
padding-rightn +
(0.5 * border-widthn)
Here n is the number of cells in the row, and
border-widthi refers to the border
between cells i and i + 1. Note only half
of the two exterior borders are counted in the table width;
the other half of these two borders lies in the margin area.
Note that in this model, the width of the table includes half the
table border. Also, in this model, a table doesn't have padding (but
does have margins).
In the collapsing border model, borders at every edge of every cell
may be specified by border properties on a variety of elements that
meet at that edge (cells, rows, row groups, columns, column groups, and
the table itself), and these borders may vary in width, style, and
color. The rule of thumb is that at each edge the most "eye catching"
border style is chosen, except that any occurrence of the style
'hidden' unconditionally turns the border off.
The following rules determine which border style "wins" in case
of a conflict:
- Borders with the 'border-style' of 'hidden'
take precedence over all other conflicting borders. Any border
with this value suppresses all borders at this location.
- Borders with a style of 'none' have the lowest priority. Only if
the border properties of all the elements meeting at this edge are
'none' will the border be omitted (but note that 'none' is the default
value for the border style.)
- If none of the styles is 'hidden' and at least one of them is not
'none', then narrow borders are discarded in favor of wider ones. If
several have the same 'border-width' than styles are
preferred in this order: 'double', 'solid', 'dashed', 'dotted',
'ridge', 'outset', 'groove', and the lowest: 'inset'.
- If border styles differ only in color, then a style set on a cell
wins over one on a row, which wins over a row group, column, column
group and, lastly, table.
Example(s):
The following example illustrates the application
of these precedence rules. This style sheet:
TABLE { border-collapse: collapse;
border: 5px solid yellow; }
*#col1 { border: 3px solid black; }
TD { border: 1px solid red; padding: 1em; }
TD.solid-blue { border: 5px dashed blue; }
TD.solid-green { border: 5px solid green; }
with this HTML source:
<P>
<TABLE>
<COL id="col1"><COL id="col2"><COL id="col3">
<TR id="row1">
<TD> 1
<TD> 2
<TD> 3
</TR>
<TR id="row2">
<TD> 4
<TD class="solid-blue"> 5
<TD class="solid-green"> 6
</TR>
<TR id="row3">
<TD> 7
<TD> 8
<TD> 9
</TR>
<TR id="row4">
<TD> 10
<TD> 11
<TD> 12
</TR>
<TR id="row5">
<TD> 13
<TD> 14
<TD> 15
</TR>
</TABLE>
would produce something like this:
Example(s):
The next example shows a table with horizontal rules between the
rows. The top border of the table is set to 'hidden' to suppress the
top border of the first row. This implements the "rules"
attribute of HTML 4.0 (rules="rows").
TABLE[rules=rows] TR { border-top: solid }
TABLE[rules=rows] { border-collapse: collapse;
border-top: hidden }
In this case the same effect can also be achieved without setting a
'hidden' border on TABLE, by addressing the first row separately. Which
method is preferred is a matter of taste.
TR:first-child { border-top: none }
TR { border-top: solid }
Example(s):
Here is another example of hidden collapsing
borders:
HTML source:
<TABLE style="border-collapse: collapse; border: solid;">
<TR><TD style="border-right: hidden; border-bottom: hidden">foo</TD>
<TD style="border: solid">bar</TD></TR>
<TR><TD style="border: none">foo</TD>
<TD style="border: solid">bar</TD></TR>
</TABLE>
Some of the values of the 'border-style' have
different meanings in tables than for other elements. In the list
below they are marked with an asterisk.
- none
- No border.
- *hidden
- Same as 'none', but in the collapsing
border model, also inhibits any other border (see the
section on border conflicts).
- dotted
- The border is a series of dots.
- dashed
- The border is a series of short line segments.
- solid
- The border is a single line segment.
- double
- The border is two solid lines. The sum of the two lines and the
space between them equals the value of 'border-width'.
- groove
- The border looks as though it were carved into the canvas.
- ridge
- The opposite of 'grove': the border looks as though it were coming
out of the canvas.
- *inset
- In the separated borders model,
the border makes the entire box look as though
it were embedded in the canvas. In the
collapsing
border model, same as 'groove'.
- *outset
- In the separated borders model,
the border makes the entire box look as though
it were coming out of the canvas. In the
collapsing
border model, same as 'ridge'.
When a table is spoken by a speech generator, the relation between
the data cells and the header cells must be expressed in a different
way than by horizontal and vertical alignment. Some speech browsers
may allow a user to move around in the 2-dimensional space, thus
giving them the opportunity to map out the spatially represented
relations. When that is not possible, the style sheet must specify at
which points the headers are spoken.
-
'speak-header'
-
Value: | once | always | inherit
| Initial: | once
| Applies to: | elements that
have table header information
| Inherited: | yes
| Percentages: | N/A
| Media: | aural
|
This property specifies whether table headers
are spoken before every
cell, or only before a cell when that cell is associated with a
different header than the previous cell. Values have
the following meanings:
- once
- The header is spoken one time, before a series of
cells.
- always
- The header is spoken before every pertinent cell.
Each document language may have different mechanisms that allow
authors to specify headers. For example, in HTML 4.0 ([HTML40]), it
is possible to specify header information with three different
attributes ("headers", "scope", and "axis"), and the specification
gives an algorithm for determining header information when these
attributes have not been specified.
This HTML example presents the money spent on meals, hotels and
transport in two locations (San Jose and Seattle) for successive
days. Conceptually, you can think of the table in terms of a
n-dimensional space. The headers of this space are: location, day,
category and subtotal. Some cells define marks along an axis while
others give money spent at points within this space. The markup
for this table is:
<TABLE>
<CAPTION>Travel Expense Report</CAPTION>
<TR>
<TH></TH>
<TH>Meals</TH>
<TH>Hotels</TH>
<TH>Transport</TH>
<TH>subtotal</TH>
</TR>
<TR>
<TH id="san-jose" axis="san-jose">San Jose</TH>
</TR>
<TR>
<TH headers="san-jose">25-Aug-97</TH>
<TD>37.74</TD>
<TD>112.00</TD>
<TD>45.00</TD>
<TD></TD>
</TR>
<TR>
<TH headers="san-jose">26-Aug-97</TH>
<TD>27.28</TD>
<TD>112.00</TD>
<TD>45.00</TD>
<TD></TD>
</TR>
<TR>
<TH headers="san-jose">subtotal</TH>
<TD>65.02</TD>
<TD>224.00</TD>
<TD>90.00</TD>
<TD>379.02</TD>
</TR>
<TR>
<TH id="seattle" axis="seattle">Seattle</TH>
</TR>
<TR>
<TH headers="seattle">27-Aug-97</TH>
<TD>96.25</TD>
<TD>109.00</TD>
<TD>36.00</TD>
<TD></TD>
</TR>
<TR>
<TH headers="seattle">28-Aug-97</TH>
<TD>35.00</TD>
<TD>109.00</TD>
<TD>36.00</TD>
<TD></TD>
</TR>
<TR>
<TH headers="seattle">subtotal</TH>
<TD>131.25</TD>
<TD>218.00</TD>
<TD>72.00</TD>
<TD>421.25</TD>
</TR>
<TR>
<TH>Totals</TH>
<TD>196.27</TD>
<TD>442.00</TD>
<TD>162.00</TD>
<TD>800.27</TD>
</TR>
</TABLE>
By providing the data model in this way, authors make it
possible for speech enabled-browsers to explore the table in
rich ways, e.g., each cell could be spoken as a list, repeating the
applicable headers before each data cell:
San Jose, 25-Aug-97, Meals: 37.74
San Jose, 25-Aug-97, Hotels: 112.00
San Jose, 25-Aug-97, Transport: 45.00
...
The browser could also speak the headers only when they change:
San Jose, 25-Aug-97, Meals: 37.74
Hotels: 112.00
Transport: 45.00
26-Aug-97, Meals: 27.28
Hotels: 112.00
...
|