This is a snapshot of an early working draft and has therefore been superseded by the HTML standard.

This document will not be further updated.

HTML 5

Call For Comments — 27 October 2007

3.15. Tabular data

3.15.1. The table element

Block-level element, and structured inline-level element.

Contexts in which this element may be used:
Where block-level elements are expected.
Where structured inline-level elements are allowed.
Content model:
In this order: optionally a caption element, followed by either zero or more colgroup elements, followed optionally by a thead element, followed optionally by a tfoot element, followed by either zero or more tbody elements or one or more tr elements, followed optionally by a tfoot element (but there can only be one tfoot element child in total).
Element-specific attributes:
None.
DOM interface:
interface HTMLTableElement : HTMLElement {
           attribute HTMLTableCaptionElement caption;
  HTMLElement createCaption();
  void deleteCaption();
           attribute HTMLTableSectionElement tHead;
  HTMLElement createTHead();
  void deleteTHead();
           attribute HTMLTableSectionElement tFoot;
  HTMLElement createTFoot();
  void deleteTFoot();
  readonly attribute HTMLCollection tBodies;
  readonly attribute HTMLCollection rows;
  HTMLElement insertRow(in long index);
  void deleteRow(in long index);
};

The table element represents data with more than one dimension (a table).

we need some editorial text on how layout tables are bad practice and non-conforming

The children of a table element must be, in order:

  1. Zero or one caption elements.

  2. Zero or more colgroup elements.

  3. Zero or one thead elements.

  4. Zero or one tfoot elements, if the last element in the table is not a tfoot element.

  5. Either:

  6. Zero or one tfoot element, if there are no other tfoot elements in the table.

The table element takes part in the table model.

The caption DOM attribute must return, on getting, the first caption element child of the table element. On setting, if the new value is a caption element, the first caption element child of the table element, if any, must be removed, and the new value must be inserted as the first node of the table element. If the new value is not a caption element, then a HIERARCHY_REQUEST_ERR DOM exception must be raised instead.

The createCaption() method must return the first caption element child of the table element, if any; otherwise a new caption element must be created, inserted as the first node of the table element, and then returned.

The deleteCaption() method must remove the first caption element child of the table element, if any.

The tHead DOM attribute must return, on getting, the first thead element child of the table element. On setting, if the new value is a thead element, the first thead element child of the table element, if any, must be removed, and the new value must be inserted immediately before the first element in the table element that is neither a caption element nor a colgroup element, if any, or at the end of the table otherwise. If the new value is not a thead element, then a HIERARCHY_REQUEST_ERR DOM exception must be raised instead.

The createTHead() method must return the first thead element child of the table element, if any; otherwise a new thead element must be created and inserted immediately before the first element in the table element that is neither a caption element nor a colgroup element, if any, or at the end of the table otherwise, and then that new element must be returned.

The deleteTHead() method must remove the first thead element child of the table element, if any.

The tFoot DOM attribute must return, on getting, the first tfoot element child of the table element. On setting, if the new value is a tfoot element, the first tfoot element child of the table element, if any, must be removed, and the new value must be inserted immediately before the first element in the table element that is neither a caption element, a colgroup element, nor a thead element, if any, or at the end of the table if there are no such elements. If the new value is not a tfoot element, then a HIERARCHY_REQUEST_ERR DOM exception must be raised instead.

The createTFoot() method must return the first tfoot element child of the table element, if any; otherwise a new tfoot element must be created and inserted immediately before the first element in the table element that is neither a caption element, a colgroup element, nor a thead element, if any, or at the end of the table if there are no such elements, and then that new element must be returned.

The deleteTFoot() method must remove the first tfoot element child of the table element, if any.

The tBodies attribute must return an HTMLCollection rooted at the table node, whose filter matches only tbody elements that are children of the table element.

The rows attribute must return an HTMLCollection rooted at the table node, whose filter matches only tr elements that are either children of the table element, or children of thead, tbody, or tfoot elements that are themselves children of the table element. The elements in the collection must be ordered such that those elements whose parent is a thead are included first, in tree order, followed by those elements whose parent is either a table or tbody element, again in tree order, followed finally by those elements whose parent is a tfoot element, still in tree order.

The behaviour of the insertRow(index) method depends on the state of the table. When it is called, the method must act as required by the first item in the following list of conditions that describes the state of the table and the index argument:

If index is less than -1 or greater than the number of elements in rows collection:
The method must raise an INDEX_SIZE_ERR exception.
If the rows collection has zero elements in it, and the table has no tbody elements in it:
The method must create a tbody element, then create a tr element, then append the tr element to the tbody element, then append the tbody element to the table element, and finally return the tr element.
If the rows collection has zero elements in it:
The method must create a tr element, append it to the last tbody element in the table, and return the tr element.
If index is equal to -1 or equal to the number of items in rows collection:
The method must create a tr element, and append it to the parent of the last tr element in the rows collection. Then, the newly created tr element must be returned.
Otherwise:
The method must create a tr element, insert it immediately before the indexth tr element in the rows collection, in the same parent, and finally must return the newly created tr element.

The deleteRow(index) method must remove the indexth element in the rows collection from its parent. If index is less than zero or greater than or equal to the number of elements in the rows collection, the method must instead raise an INDEX_SIZE_ERR exception.

3.15.2. The caption element

Contexts in which this element may be used:
As the first element child of a table element.
Content model:
Significant strictly inline-level content.
Element-specific attributes:
None.
DOM interface:
No difference from HTMLElement.

The caption element represents the title of the table that is its parent, if it has a parent and that is a table element.

The caption element takes part in the table model.

3.15.3. The colgroup element

Contexts in which this element may be used:
As a child of a table element, after any caption elements and before any thead, tbody, tfoot, and tr elements.
Content model:
Zero or more col elements.
Element-specific attributes:
span, but only if the element contains no col elements
DOM interface:
interface HTMLTableColElement : HTMLElement {
           attribute unsigned long span;
};

The colgroup element represents a group of one or more columns in the table that is its parent, if it has a parent and that is a table element.

If the colgroup element contains no col elements, then the element may have a span content attribute specified, whose value must be a valid non-negative integer greater than zero. Its default value, which must be used if parsing the attribute as a non-negative integer returns either an error or zero, is 1.

The colgroup element and its span attribute take part in the table model.

The span DOM attribute must reflect the content attribute of the same name, with the exception that on setting, if the new value is 0, then an INDEX_SIZE_ERR exception must be raised.

3.15.4. The col element

Contexts in which this element may be used:
As a child of a colgroup element that doesn't have a span attribute.
Content model:
Empty.
Element-specific attributes:
span
DOM interface:

HTMLTableColElement, same as for colgroup elements. This interface defines one member, span.

If a col element has a parent and that is a colgroup element that itself has a parent that is a table element, then the col element represents one or more columns in the column group represented by that colgroup.

The element may have a span content attribute specified, whose value must be a valid non-negative integer greater than zero. Its default value, which must be used if parsing the attribute as a non-negative integer returns either an error or zero, is 1.

The col element and its span attribute take part in the table model.

The span DOM attribute must reflect the content attribute of the same name, with the exception that on setting, if the new value is 0, then an INDEX_SIZE_ERR exception must be raised.

3.15.5. The tbody element

Contexts in which this element may be used:
As a child of a table element, after any caption, colgroup, and thead elements, but only if there are no tr elements that are children of the table element.
Content model:
One or more tr elements
Element-specific attributes:
None.
DOM interface:
interface HTMLTableSectionElement : HTMLElement {
  readonly attribute HTMLCollection rows;
  HTMLElement insertRow(in long index);
  void deleteRow(in long index);
};

The HTMLTableSectionElement interface is also used for thead and tfoot elements.

The tbody element represents a block of rows that consist of a body of data for the parent table element, if the tbody element has a parent and it is a table.

The tbody element takes part in the table model.

The rows attribute must return an HTMLCollection rooted at the element, whose filter matches only tr elements that are children of the element.

The insertRow(index) method must, when invoked on an element table section, act as follows:

If index is less than -1 or greater than the number of elements in the rows collection, the method must raise an INDEX_SIZE_ERR exception.

If index is equal to -1 or equal to the number of items in the rows collection, the method must create a tr element, append it to the element table section, and return the newly created tr element.

Otherwise, the method must create a tr element, insert it as a child of the table section element, immediately before the indexth tr element in the rows collection, and finally must return the newly created tr element.

The deleteRow(index) method must remove the indexth element in the rows collection from its parent. If index is less than zero or greater than or equal to the number of elements in the rows collection, the method must instead raise an INDEX_SIZE_ERR exception.

3.15.6. The thead element

Contexts in which this element may be used:
As a child of a table element, after any caption, and colgroup elements and before any tbody, tfoot, and tr elements, but only if there are no other thead elements that are children of the table element.
Content model:
One or more tr elements
Element-specific attributes:
None.
DOM interface:
HTMLTableSectionElement, as defined for tbody elements.

The thead element represents the block of rows that consist of the column labels (headers) for the parent table element, if the thead element has a parent and it is a table.

The thead element takes part in the table model.

3.15.7. The tfoot element

Contexts in which this element may be used:
As a child of a table element, after any caption, colgroup, and thead elements and before any tbody and tr elements, but only if there are no other tfoot elements that are children of the table element.
As a child of a table element, after any caption, colgroup, thead, tbody, and tr elements, but only if there are no other tfoot elements that are children of the table element.
Content model:
One or more tr elements
Element-specific attributes:
None.
DOM interface:
HTMLTableSectionElement, as defined for tbody elements.

The tfoot element represents the block of rows that consist of the column summaries (footers) for the parent table element, if the tfoot element has a parent and it is a table.

The tfoot element takes part in the table model.

3.15.8. The tr element

Contexts in which this element may be used:
As a child of a thead element.
As a child of a tbody element.
As a child of a tfoot element.
As a child of a table element, after any caption, colgroup, and thead elements, but only if there are no tbody elements that are children of the table element.
Content model:
One or more td or th elements
Element-specific attributes:
None.
DOM interface:
interface HTMLTableRowElement : HTMLElement {
  readonly attribute long rowIndex;
  readonly attribute long sectionRowIndex;
  readonly attribute HTMLCollection cells;
  HTMLElement insertCell(in long index);
  void deleteCell(in long index);
};

The tr element represents a row of cells in a table.

The tr element takes part in the table model.

The rowIndex element must, if the element has a parent table element, or a parent tbody, thead, or tfoot element and a grandparent table element, return the index of the tr element in that table element's rows collection. If there is no such table element, then the attribute must return 0.

The rowIndex DOM attribute must, if the element has a parent table, tbody, thead, or tfoot element, return the index of the tr element in the parent element's rows collection (for tables, that's the rows collection; for table sections, that's the rows collection). If there is no such parent element, then the attribute must return 0.

The cells attribute must return an HTMLCollection rooted at the tr element, whose filter matches only td and th elements that are children of the tr element.

The insertCell(index) method must act as follows:

If index is less than -1 or greater than the number of elements in the cells collection, the method must raise an INDEX_SIZE_ERR exception.

If index is equal to -1 or equal to the number of items in cells collection, the method must create a td element, append it to the tr element, and return the newly created td element.

Otherwise, the method must create a td element, insert it as a child of the tr element, immediately before the indexth td or th element in the cells collection, and finally must return the newly created td element.

The deleteCell(index) method must remove the indexth element in the cells collection from its parent. If index is less than zero or greater than or equal to the number of elements in the cells collection, the method must instead raise an INDEX_SIZE_ERR exception.

3.15.9. The td element

Contexts in which this element may be used:
As a child of a tr element.
Content model:
Zero or more block-level elements, or inline-level content (but not both).
Element-specific attributes:
colspan
rowspan
DOM interface:
interface HTMLTableCellElement : HTMLElement {
           attribute long colSpan;
           attribute long rowSpan;
  readonly attribute long cellIndex;
};

The td element represents a data cell in a table.

The td element may have a colspan content attribute specified, whose value must be a valid non-negative integer greater than zero. Its default value, which must be used if parsing the attribute as a non-negative integer returns either an error or zero, is 1.

The td element may also have a rowspan content attribute specified, whose value must be a valid non-negative integer. Its default value, which must be used if parsing the attribute as a non-negative integer returns an error, is also 1.

The td element and its colspan and rowspan attributes take part in the table model.

The colspan DOM attribute must reflect the content attribute of the same name, with the exception that on setting, if the new value is 0, then an INDEX_SIZE_ERR exception must be raised.

The rowspan DOM attribute must reflect the content attribute of the same name.

The cellIndex DOM 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 0.

There has been some suggestion that the headers attribute from HTML4, or some other mechanism that is more powerful than scope="", should be included. This has not yet been considered.

3.15.10. The th element

Contexts in which this element may be used:
As a child of a tr element.
Content model:
Zero or more block-level elements, or inline-level content (but not both).
Element-specific attributes:
colspan
rowspan
scope
DOM interface:
interface HTMLTableHeaderCellElement : HTMLTableCellElement {
           attribute DOMString scope;
};

The th element represents a header cell in a table.

The th element may have a colspan content attribute specified, whose value must be a valid non-negative integer greater than zero. Its default value, which must be used if parsing the attribute as a non-negative integer returns either an error or zero, is 1.

The th element may also have a rowspan content attribute specified, whose value must be a valid non-negative integer. Its default value, which must be used if parsing the attribute as a non-negative integer returns an error, is also 1.

The th element may have a scope content attribute specified. The scope attribute is an enumerated attribute with five states, four of which have explicit keywords:

The row keyword, which maps to the row state
The row state means the header cell applies to all the remaining cells in the row.
The col keyword, which maps to the column state
The column state means the header cell applies to all the remaining cells in the column.
The rowgroup keyword, which maps to the row group state
The row group state means the header cell applies to all the remaining cells in the row group.
The colgroup keyword, which maps to the column group state
The column group state means the header cell applies to all the remaining cells in the column group.
The auto state
The auto state makes the header cell apply to a set of cells selected based on context.

The scope attribute's missing value default is the auto state.

The exact effect of these values is described in detail in the algorithm for assigning header cells to data cells, which user agents must apply to determine the relationships between data cells and header cells.

The th element and its colspan, rowspan, and scope attributes take part in the table model.

The scope DOM attribute must reflect the content attribute of the same name.

The HTMLTableHeaderCellElement interface inherits from the HTMLTableCellElement interface and therefore also has the DOM attributes defined above in the td section.

3.15.11. Processing model

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 1 ≤ x ≤ xmax, and the y coordinates are always in the range 1 ≤ y ≤ ymax. If one or both of xmax and ymax 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 (cellx, celly), and with a particular width and height such that the cell covers all the slots with coordinates (x, y) where cellx ≤ x < cellx+width and celly ≤ y < celly+height. Cell can either be data cells or header cells. Data cells correspond to td elements, and have zero or more associated header cells. Header cells correspond to th elements.

A row is a complete set of slots from x=1 to x=xmax, for a particular value of y. Rows correspond to tr elements.

A column is a complete set of slots from y=1 to y=ymax, for a particular value of x. Columns can correspond to col elements, but in the absense of col elements are implied.

A row group is a set of rows anchored at a slot (1, groupy) with a particular height such that the row group covers all the slots with coordinates (x, y) where 1 ≤ x < xmax and groupy ≤ y < groupy+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 (groupx, 1) with a particular width such that the column group covers all the slots with coordinates (x, y) where groupx ≤ x < groupx+width and 1 ≤ y < ymax. 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.

3.15.11.1. Forming a table

To determine which elements correspond to which slots in a table associated with a table element, to determine the dimensions of the table (xmax and ymax), and to determine if there are any table model errors, user agents must use the following algorithm:

  1. Let xmax be zero.

  2. Let ymax be zero.

  3. Let the table be the table represented by the table element. The xmax and ymax variables give the table's extent. The table is initially empty.

  4. If the table element has no table children, then return the table (which will be empty), and abort these steps.

  5. 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 algorithm must be aborted at that point and the algorithm must return the table.

  6. While the current element is not one of the following elements, advance the current element to the next child of the table:

  7. If the current element is a caption, then that is the caption element associated with the table. Otherwise, it has no associated caption element.

  8. If the current element is a caption, then while the current element is not one of the following elements, advance the current element to the next child of the table:

    (Otherwise, the current element will already be one of those elements.)

  9. If the current element is a colgroup, follow these substeps:

    1. Column groups. Process the current element according to the appropriate one of the following two cases:

      If the current element has any col element children

      Follow these steps:

      1. Let xstart have the value xmax+1.

      2. Let the current column be the first col element child of the colgroup element.

      3. 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, then let span be 1.

      4. Increase xmax by span.

      5. Let the last span columns in the table correspond to the current column col element.

      6. 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 third step of this innermost group of steps (columns).

      7. Let all the last columns in the table from x=xstart to x=xmax form a new column group, anchored at the slot (xstart, 1), with width xmax-xstart-1, corresponding to the colgroup element.

      If the current element has no col element children
      1. If 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, then let span be 1.

      2. Increase xmax by span.

      3. Let the last span columns in the table form a new column group, anchored at the slot (xmax-span+1, 1), with width span, corresponding to the colgroup element.

    2. Advance the current element to the next child of the table.

    3. While the current element is not one of the following elements, advance the current element to the next child of the table:

    4. If the current element is a colgroup element, jump to step 1 in these substeps (column groups).

  10. Let ycurrent be zero. When the algorithm is aborted, if ycurrent does not equal ymax, then that is a table model error.

  11. Let the list of downward-growing cells be an empty list.

  12. Rows. While the current element is not one of the following elements, advance the current element to the next child of the table:

  13. If the current element is a tr, then run the algorithm for processing rows (defined below), then return to the previous step (rows).

  14. Otherwise, run the algorithm for ending a row group.

  15. Let ystart have the value ymax+1.

  16. For each tr element that is a child of the current element, in tree order, run the algorithm for processing rows (defined below).

  17. If ymax ≥ ystart, then let all the last rows in the table from y=ystart to y=ymax form a new row group, anchored at the slot with coordinate (1, ystart), with height ymax-ystart+1, corresponding to the current element.

  18. Run the algorithm for ending a row group again.

  19. Return to step 12 (rows).

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:

  1. If ycurrent is less than ymax, then this is a table model error.

  2. While ycurrent is less than ymax, follow these steps:

    1. Increase ycurrent by 1.

    2. Run the algorithm for growing downward-growing cells.

  3. 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:

  1. Increase ycurrent by 1.

  2. Run the algorithm for growing downward-growing cells.

  3. Let xcurrent be 1.

  4. If the tr element being processed contains no td or th elements, then abort this set of steps and return to the algorithm above.

  5. Let current cell be the first td or th element in the tr element being processed.

  6. Cells. While xcurrent is less than or equal to xmax and the slot with coordinate (xcurrent, ycurrent) already has a cell assigned to it, increase xcurrent by 1.

  7. If xcurrent is greater than xmax, increase xmax by 1 (which will make them equal).

  8. 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.

  9. 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.

  10. If rowspan is zero, then let cell grows downward be true, and set rowspan to 1. Otherwise, let cell grows downward be false.

  11. If xmax < xcurrent+colspan-1, then let xmax be xcurrent+colspan-1.

  12. If ymax < ycurrent+rowspan-1, then let ymax be ycurrent+rowspan-1.

  13. Let the slots with coordinates (x, y) such that xcurrent ≤ x < xcurrent+colspan and ycurrent ≤ y < ycurrent+rowspan be covered by a new cell c, anchored at (xcurrent, ycurrent), 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 what header cells apply to a data cell, use the algorithm for assigning header cells to data 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.

  14. If cell grows downward is true, then add the tuple {c, xcurrent, colspan} to the list of downward-growing cells.

  15. Increase xcurrent by colspan.

  16. If current cell is the last td or th element in the tr element being processed, then abort this set of steps and return to the algorithm above.

  17. Let current cell be the next td or th element in the tr element being processed.

  18. Return to step 5 (cells).

The algorithm for growing downward-growing cells, used when adding a new row, is as follows:

  1. If the list of downward-growing cells is empty, do nothing. Abort these steps; return to the step that invoked this algorithm.

  2. Otherwise, if ymax is less than ycurrent, then increase ymax by 1 (this will make it equal to ycurrent).

  3. For each {cell, cellx, width} tuple in the list of downward-growing cells, extend the cell cell so that it also covers the slots with coordinates (x, ycurrent), where cellx ≤ x < cellx+width-1.

If, after establishing which elements correspond to which slots, there exists a column in the table containing only slots that do not have a cell anchored to them, then this is a table model error.

3.15.11.2. Forming relationships between data cells and header cells

Each data cell can be assigned zero or more header cells. The algorithm for assigning header cells to data cells is as follows.

For each header cell in the table, in tree order:

  1. Let (headerx, headery) be the coordinate of the slot to which the header cell is anchored.

  2. Examine the scope attribute of the th element corresponding to the header cell, and, based on its state, apply the appropriate substep:

    If it is in the row state

    Assign the header cell to any data cells anchored at slots with coordinates (datax, datay) where headerx < datax ≤ xmax and datay = headery.

    If it is in the column state

    Assign the header cell to any data cells anchored at slots with coordinates (datax, datay) where datax = headerx and headery < datay ≤ ymax.

    If it is in the row group state

    If the header cell is not in a row group, then don't assign the header cell to any data cells.

    Otherwise, let (1, groupy) be the slot at which the row group is anchored, let height be the number of rows in the row group, and assign the header cell to any data cells anchored at slots with coordinates (datax, datay) where headerx ≤ datax ≤ xmax and headery ≤ datay < groupy+height.

    If it is in the column group state

    If the header cell is not in a column group, then don't assign the header cell to any data cells.

    Otherwise, let (groupx, 1) be the slot at which the column group is anchored, let width be the number of columns in the column group, and assign the header cell to any data cells anchored at slots with coordinates (datax, datay) where headerx ≤ datax < groupx+width and headery ≤ datay ≤ ymax.

    Otherwise, it is in the auto state

    If the header cell is not in the first row of the table, or not in the first cell of a row, then don't assign the header cell to any data cells.

    Otherwise, if the header cell is in the first row of the table, assign the header cell to any data cells anchored at slots with coordinates (datax, datay) where datax = headerx and headery < datay ≤ ymax.

    Otherwise, the header cell is in the first column of the table; assign the header cell to any data cells anchored at slots with coordinates (datax, datay) where headerx < datax ≤ xmax and datay = headery.