td
and th
elementsThe td
and th
elements may have a colspan
content
attribute specified, whose value must be a valid non-negative
integer greater than zero.
The td
and th
elements may also have a
rowspan
content
attribute specified, whose value must be a valid non-negative
integer.
These attributes give the number of columns and rows respectively that the cell is to span. These attributes must not be used to overlap cells, as described in the description of the table model.
The td
and th
element may have a headers
content
attribute specified. The headers
attribute, if specified,
must contain a string consisting of an unordered set of unique
space-separated tokens that are case-sensitive,
each of which must have the value of an ID of a th
element taking
part in the same table as the
td
or th
element (as
defined by the table model).
A th
element with ID id is said
to be directly targeted by all td
and
th
elements in the same table that have headers
attributes whose values
include as one of their tokens the ID id. A
th
element A is said to be
targeted by a th
or td
element
B if either A is directly
targeted by B or if there exists an element
C that is itself targeted by the element
B and A is directly
targeted by C.
A th
element must not be targeted by
itself.
The colspan
, rowspan
, and headers
attributes take part in the
table model.
The td
and th
elements implement
interfaces that inherit from the HTMLTableCellElement
interface:
interface HTMLTableCellElement : HTMLElement {
attribute unsigned long colSpan;
attribute unsigned long rowSpan;
[PutForwards=value] readonly attribute DOMSettableTokenList headers;
readonly attribute long cellIndex;
};
cellIndex
Returns the position of the cell in the row's cells
list. This does not necessarily
correspond to the x-position of the cell in
the table, since earlier cells might cover multiple rows or
columns.
Returns −1 if the element isn't in a row.
The colSpan
IDL
attribute must reflect the colspan
content attribute. The
value must be limited to only non-negative numbers greater
than zero.
The rowSpan
IDL
attribute must reflect the rowspan
content attribute. Its
default value, which must be used if parsing the attribute as a non-negative
integer returns an error, is 1.
The headers
IDL
attribute must reflect the content attribute of the
same name.
The cellIndex
IDL attribute must, if the element has a parent tr
element, return the index of the cell's element in the parent
element's cells
collection. If
there is no such parent element, then the attribute must return
−1.
The various table elements and their content attributes together define the table model.
A table consists of cells
aligned on a two-dimensional grid of slots with coordinates (x, y). The grid is finite, and is
either empty or has one or more slots. If the grid has one or more
slots, then the x coordinates are always in the
range 0 ≤ x < x_{width}, and the y
coordinates are always in the range 0 ≤ y < y_{height}. If one or both of x_{width} and y_{height} are zero, then the table is empty (has
no slots). Tables correspond to table
elements.
A cell is a set of slots anchored
at a slot (cell_{x}, cell_{y}), and with a particular
width and height such that
the cell covers all the slots with coordinates (x, y) where cell_{x} ≤ x < cell_{x}+width and
cell_{y} ≤ y < cell_{y}+height. Cells can
either be data cells or header cells. Data cells
correspond to td
elements, and header cells correspond
to th
elements. Cells of both types can have zero or
more associated header cells.
It is possible, in certain error cases, for two cells to occupy the same slot.
A row is a complete set of slots
from x=0 to x=x_{width}-1, for a particular value of y. Rows correspond to tr
elements.
A column is a complete set of
slots from y=0 to y=y_{height}-1, for a particular value of x. Columns can correspond to col
elements. In the absence of col
elements, columns are
implied.
A row group is a set of
rows anchored at a slot (0, group_{y}) with a particular height such that the row group covers all the slots
with coordinates (x, y)
where 0 ≤ x < x_{width} and group_{y} ≤ y < group_{y}+height. Row groups
correspond to tbody
, thead
, and
tfoot
elements. Not every row is necessarily in a row
group.
A column group is a set
of columns anchored at a slot
(group_{x}, 0) with a
particular width such that the column group
covers all the slots with coordinates (x, y) where group_{x} ≤ x < group_{x}+width and
0 ≤ y < y_{height}. Column groups
correspond to colgroup
elements. Not every column is
necessarily in a column group.
Row groups cannot overlap each other. Similarly, column groups cannot overlap each other.
A cell cannot cover slots that are from two or more row groups. It is, however, possible for a cell to be in multiple column groups. All the slots that form part of one cell are part of zero or one row groups and zero or more column groups.
In addition to cells, columns, rows, row
groups, and column
groups, tables can have a
caption
element associated with them. This gives the
table a heading, or legend.
A table model error is an error with the data
represented by table
elements and their
descendants. Documents must not have table model errors.
To determine which elements correspond to which slots in a table associated with a
table
element, to determine the dimensions of the table
(x_{width} and y_{height}), and to determine if
there are any table model
errors, user agents must use the following algorithm:
Let x_{width} be zero.
Let y_{height} be zero.
Let pending tfoot
elements be
a list of tfoot
elements, initially empty.
Let the table be the table represented by the
table
element. The x_{width} and y_{height} variables give the
table's dimensions. The table is
initially empty.
If the table
element has no children elements,
then return the table (which will be empty),
and abort these steps.
Associate the first caption
element child of the
table
element with the table. If
there are no such children, then it has no associated
caption
element.
Let the current element be the first
element child of the table
element.
If a step in this algorithm ever requires the current element to be advanced to the next child of the
table
when there is no such next child, then
the user agent must jump to the step labeled end, near the
end of this algorithm.
While the current element is not one of the
following elements, advance the current element to the next child of the
table
:
If the current element is a
colgroup
, follow these substeps:
Column groups: Process the current element according to the appropriate case below:
col
element childrenFollow these steps:
Let x_{start} have the value of x_{width}.
Let the current column be the first
col
element child of the colgroup
element.
Columns: If the current column
col
element has a span
attribute, then parse its
value using the rules for parsing non-negative
integers.
If the result of parsing the value is not an error or zero, then let span be that value.
Otherwise, if the col
element has no span
attribute, or if trying to
parse the attribute's value resulted in an error or zero,
then let span be 1.
Increase x_{width} by span.
Let the last span columns in the
table correspond to the current
column col
element.
If current column is not the last
col
element child of the colgroup
element, then let the current column be
the next col
element child of the
colgroup
element, and return to the step
labeled columns.
Let all the last columns in the
table from x=x_{start} to x=x_{width}-1 form a
new column group,
anchored at the slot (x_{start}, 0), with width x_{width}-x_{start},
corresponding to the colgroup
element.
col
element childrenIf the colgroup
element has a span
attribute, then parse
its value using the rules for parsing non-negative
integers.
If the result of parsing the value is not an error or zero, then let span be that value.
Otherwise, if the colgroup
element has no
span
attribute, or
if trying to parse the attribute's value resulted in an
error or zero, then let span be 1.
Increase x_{width} by span.
Let the last span columns in the
table form a new column group, anchored
at the slot (x_{width}-span,
0), with width span, corresponding to
the colgroup
element.
While the current element is not one of
the following elements, advance the current element to the next child of the
table
:
If the current element is a
colgroup
element, jump to the step labeled
column groups above.
Let y_{current} be zero.
Let the list of downward-growing cells be an empty list.
Rows: While the current element is
not one of the following elements, advance the current element to the next child of the
table
:
If the current element is a
tr
, then run the algorithm for processing
rows, advance
the current element to the next child of the
table
, and return to the step labeled
rows.
Run the algorithm for ending a row group.
If the current element is a
tfoot
, then add that element to the list of pending tfoot
elements, advance the current element to the next child of the
table
, and return to the step labeled
rows.
The current element is either a
thead
or a tbody
.
Run the algorithm for processing row groups.
Return to the step labeled rows.
End: For each tfoot
element in the list of
pending tfoot
elements, in tree
order, run the algorithm for processing row
groups.
If there exists a row or column in the table containing only slots that do not have a cell anchored to them, then this is a table model error.
Return the table.
The algorithm for processing row groups, which is
invoked by the set of steps above for processing
thead
, tbody
, and tfoot
elements, is:
Let y_{start} have the value of y_{height}.
For each tr
element that is a child of the element
being processed, in tree order, run the algorithm for
processing rows.
If y_{height} > y_{start}, then let all the last rows in the table from y=y_{start} to y=y_{height}-1 form a new row group, anchored at the slot with coordinate (0, y_{start}), with height y_{height}-y_{start}, corresponding to the element being processed.
Run the algorithm for ending a row group.
The algorithm for ending a row group, which is invoked by the set of steps above when starting and ending a block of rows, is:
While y_{current} is less than y_{height}, follow these steps:
Increase y_{current} by 1.
Empty the list of downward-growing cells.
The algorithm for processing rows, which is invoked by
the set of steps above for processing tr
elements,
is:
If y_{height} is equal to y_{current}, then increase y_{height} by 1. (y_{current} is never greater than y_{height}.)
Let x_{current} be 0.
If the tr
element being processed has no
td
or th
element children, then increase
y_{current} by 1, abort this
set of steps, and return to the algorithm above.
Let current cell be the first
td
or th
element in the tr
element being processed.
Cells: While x_{current} is less than x_{width} and the slot with coordinate (x_{current}, y_{current}) already has a cell assigned to it, increase x_{current} by 1.
If x_{current} is equal to x_{width}, increase x_{width} by 1. (x_{current} is never greater than x_{width}.)
If the current cell has a colspan
attribute, then parse that
attribute's value, and let colspan be
the result.
If parsing that value failed, or returned zero, or if the attribute is absent, then let colspan be 1, instead.
If the current cell has a rowspan
attribute, then parse that attribute's
value, and let rowspan be the
result.
If parsing that value failed or if the attribute is absent, then let rowspan be 1, instead.
If rowspan is zero, then let cell grows downward be true, and set rowspan to 1. Otherwise, let cell grows downward be false.
If x_{width} < x_{current}+colspan, then let x_{width} be x_{current}+colspan.
If y_{height} < y_{current}+rowspan, then let y_{height} be y_{current}+rowspan.
Let the slots with coordinates (x, y) such that x_{current} ≤ x < x_{current}+colspan and y_{current} ≤ y < y_{current}+rowspan be covered by a new cell c, anchored at (x_{current}, y_{current}), which has width colspan and height rowspan, corresponding to the current cell element.
If the current cell element is a
th
element, let this new cell c
be a header cell; otherwise, let it be a data cell.
To establish which header cells apply to the current cell element, use the algorithm for assigning header cells described in the next section.
If any of the slots involved already had a cell covering them, then this is a table model error. Those slots now have two cells overlapping.
If cell grows downward is true, then add the tuple {c, x_{current}, colspan} to the list of downward-growing cells.
Increase x_{current} by colspan.
If current cell is the last td
or th
element in the tr
element being
processed, then increase y_{current} by 1, abort this set of steps, and
return to the algorithm above.
Let current cell be the next
td
or th
element in the tr
element being processed.
Return to the step labelled cells.
When the algorithms above require the user agent to run the algorithm for growing downward-growing cells, the user agent must, for each {cell, cell_{x}, width} tuple in the list of downward-growing cells, if any, extend the cell cell so that it also covers the slots with coordinates (x, y_{current}), where cell_{x} ≤ x < cell_{x}+width.
Each cell can be assigned zero or more header cells. The algorithm for assigning header cells to a cell principal cell is as follows.
Let header list be an empty list of cells.
Let (principal_{x}, principal_{y}) be the coordinate of the slot to which the principal cell is anchored.
headers
attribute specifiedTake the value of the principal cell's
headers
attribute and
split it on
spaces, letting id list be the list
of tokens obtained.
For each token in the id list, if the
first element in the Document
with an ID equal to
the token is a cell in the same table, and that cell is not the
principal cell, then add that cell to header list.
headers
attribute specifiedLet principal_{width} be the width of the principal cell.
Let principal_{height} be the height of the principal cell.
For each value of y from principal_{y} to principal_{y}+principal_{height}-1, run the internal algorithm for scanning and assigning header cells, with the principal cell, the header list, the initial coordinate (principal_{x},y), and the increments Δx=−1 and Δy=0.
For each value of x from principal_{x} to principal_{x}+principal_{width}-1, run the internal algorithm for scanning and assigning header cells, with the principal cell, the header list, the initial coordinate (x,principal_{y}), and the increments Δx=0 and Δy=−1.
If the principal cell is anchored in a row group, then add all header cells that are row group headers and are anchored in the same row group with an x-coordinate less than or equal to principal_{x}+principal_{width}-1 and a y-coordinate less than or equal to principal_{y}+principal_{height}-1 to header list.
If the principal cell is anchored in a column group, then add all header cells that are column group headers and are anchored in the same column group with an x-coordinate less than or equal to principal_{x}+principal_{width}-1 and a y-coordinate less than or equal to principal_{y}+principal_{height}-1 to header list.
Remove all the empty cells from the header list.
Remove any duplicates from the header list.
Remove principal cell from the header list if it is there.
Assign the headers in the header list to the principal cell.
The internal algorithm for scanning and assigning header cells, given a principal cell, a header list, an initial coordinate (initial_{x}, initial_{y}), and Δx and Δy increments, is as follows:
Let x equal initial_{x}.
Let y equal initial_{y}.
Let opaque headers be an empty list of cells.
Let in header block be true, and let headers from current header block be a list of cells containing just the principal cell.
Let in header block be false and let headers from current header block be an empty list of cells.
Loop: Increment x by Δx; increment y by Δy.
For each invocation of this algorithm, one of Δx and Δy will be −1, and the other will be 0.
If either x or y is less than 0, then abort this internal algorithm.
If there is no cell covering slot (x, y), or if there is more than one cell covering slot (x, y), return to the substep labeled loop.
Let current cell be the cell covering slot (x, y).
Set in header block to true.
Add current cell to headers from current header block.
Let blocked be false.
If there are any cells in the opaque headers list anchored with the same x-coordinate as the current cell, and with the same width as current cell, then let blocked be true.
If the current cell is not a column header, then let blocked be true.
If there are any cells in the opaque headers list anchored with the same y-coordinate as the current cell, and with the same height as current cell, then let blocked be true.
If the current cell is not a row header, then let blocked be true.
If blocked is false, then add the current cell to the headers list.
Set in header block to false. Add all the cells in headers from current header block to the opaque headers list, and empty the headers from current header block list.
Return to the step labeled loop.
A header cell anchored at the slot with coordinate (x, y) with width width and height height is said to be a column header if any of the following conditions are true:
scope
attribute
is in the column state, orscope
attribute
is in the auto state, and
there are no data cells in any of the cells covering slots with
y-coordinates y
.. y+height-1.A header cell anchored at the slot with coordinate (x, y) with width width and height height is said to be a row header if any of the following conditions are true:
scope
attribute
is in the row state, orscope
attribute
is in the auto state, the
cell is not a column header, and there are no data
cells in any of the cells covering slots with x-coordinates x .. x+width-1.A header cell is said to be a column group header if
its scope
attribute is in the
column group state.
A header cell is said to be a row group header if
its scope
attribute is in the
row group state.
A cell is said to be an empty cell if it contains no elements and its text content, if any, consists only of White_Space characters.