In this order: optionally a <{caption}> element, followed by zero or more
<{colgroup}> elements, followed optionally by a <{thead}> element, followed by
either zero or more <{tbody}> elements or one or more <{tr}> elements, followed
optionally by a <{tfoot}> element, optionally intermixed with one or more
script-supporting elements.
The <{table}> element represents data with more than one dimension, in
the form of a table.
The <{table}> element takes part in the table model.
Tables have rows, columns, and cells given by their descendants. The rows and
columns form a grid; a table's cells must completely cover that grid without overlap.
Precise rules for determining whether this conformance requirement is met are
described in the description of the table model.
Authors are encouraged to provide information describing how to interpret complex tables.
Guidance on how to provide such information is given below.
Tables should not be used as layout aids.
Historically, many Web authors have tables in HTML as a way to control their page layout making
it difficult to extract tabular data from such documents.
In particular, users of accessibility tools, like screen readers, are likely to find it very
difficult to navigate pages with tables used for layout.
If a table is used for layout purposes, it must be marked with the attribute
role="presentation" for a user agent to properly represent the table to an
assistive technology, and to properly convey the intent of the author to tools that wish to
extract tabular data from the document.
There are a variety of alternatives to using HTML tables for layout, primarily using CSS
positioning and the CSS table model. [[!CSS-2015]]
The border content attribute may be
specified on a <{table}> element to explicitly indicate that the <{table}> element represents
tabular data and is not being used for layout purposes. If specified, the attribute's value
must either be the empty string or the value "1". If a value other than the empty
string, or "1" is set, such as a text string, user agents should interpret the
value as the empty string.
The border content attribute is used by certain user agents as an indication that
borders should be drawn around cells of the table. These user agents may treat values greater
than 1 as indicators to render wider borders for the table. Authors should instead
use CSS to provide styling for tables.
Tables can be complicated to understand and navigate. To help users with this, user agents
should clearly delineate cells in a table from each other, unless the user agent has classified
the table as a layout table.
Authors and implementors are encouraged to consider using some of the
table design techniques described below to make tables easier to navigate for users.
User agents, especially those that do table analysis on arbitrary content, are encouraged to
find heuristics to determine which tables actually contain data and which are merely being used
for layout. This specification does not define a precise heuristic, but the following are
suggested as possible indicators:
Feature
Indication
The use of the role attribute with the value presentation
Probably a layout table
The use of the border attribute with the non-conforming value 0
Probably a layout table
The use of the non-conforming cellspacing and cellpadding
attributes with the value 0
Probably a layout table
The use of <{caption}>, <{thead}>, or <{th}> elements
Probably a non-layout table
The use of the headers and scope attributes
Probably a non-layout table
The use of the border attribute with a value other than 0
Probably a non-layout table
Explicit visible borders set using CSS
Probably a non-layout table
The use of the non-conforming summary attribute
Not a good indicator (both layout and non-layout tables have historically been
given this attribute)
It is quite possible that the above suggestions are wrong. Implementors are urged
to provide feedback elaborating on their experiences with trying to create a layout table
detection heuristic.
If a <{table}> element has a (non-conforming) summary attribute, and the user agent
has not classified the table as a layout table, the user agent may report the contents of that
attribute to the user.
table . caption [ = value ]
Returns the table's <{caption}> element.
Can be set, to replace the <{caption}> element.
caption = table . createCaption()
Ensures the table has a <{caption}> element, and returns it.
table . deleteCaption()
Ensures the table does not have a <{caption}> element.
table . tHead [ = value ]
Returns the table's <{thead}> element.
Can be set, to replace the <{thead}> element. If the new value is not a
<{thead}> element, throws a {{HierarchyRequestError}} exception.
thead = table . createTHead()
Ensures the table has a <{thead}> element, and returns it.
table . deleteTHead()
Ensures the table does not have a <{thead}> element.
table . tFoot [ = value ]
Returns the table's <{tfoot}> element.
Can be set, to replace the <{tfoot}> element. If the new value is not a
<{tfoot}> element, throws a {{HierarchyRequestError}} exception.
tfoot = table . createTFoot()
Ensures the table has a <{tfoot}> element, and returns it.
table . deleteTFoot()
Ensures the table does not have a <{tfoot}> element.
table . tBodies
Returns an HTMLCollection of the <{tbody}> elements of the table.
tbody = table . createTBody()
Creates a <{tbody}> element, inserts it into the table, and returns it.
table . rows
Returns an HTMLCollection of the <{tr}> elements of the table.
tr = table . insertRow( [ index ] )
Creates a <{tr}> element, along with a tbody if required, inserts them
into the table at the position given by the argument, and returns the <{tr}>.
The position is relative to the rows in the table. The index -1, which is the default
if the argument is omitted, is equivalent to inserting at the end of the table.
If the given position is less than -1 or greater than the number of rows, throws an
{{IndexSizeError}} exception.
table . deleteRow(index)
Removes the <{tr}> element with the given position in the table.
The position is relative to the rows in the table. The index -1 is equivalent to
deleting the last row of the table.
If the given position is less than -1 or greater than the index of the last row, or if
there are no rows, throws an {{IndexSizeError}} exception.
The caption IDL attribute must return,
on getting, the first <{caption}> element child of the <{table}> element, if any, or null
otherwise. On setting, the first <{caption}> element child of the <{table}> element, if any,
must be removed, and the new value, if not null, must be inserted as the first node of the
<{table}> element.
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 IDL attribute must return, on
getting, the first <{thead}> element child of the <{table}> element, if any, or null otherwise.
On setting, if the new value is null or a <{thead}> element, the first <{thead}> element child
of the <{table}> element, if any, must be removed, and the new value, if not null, 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 if there
are no such elements. If the new value is neither null nor a <{thead}> element, then a
{{HierarchyRequestError}} DOM exception must be thrown 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 if there are no such elements, 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 IDL attribute must return, on
getting, the first <{tfoot}> element child of the <{table}> element, if any, or
null otherwise. On setting, if the new value is null or a <{tfoot}> element, the first
<{tfoot}> element child of the <{table}> element, if any, must be removed, and
the new value, if not null, must be inserted at the end of the table. If the new value is neither
null nor a <{tfoot}> element, then a {{HierarchyRequestError}} DOM exception
must be thrown 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 at the end of the table, 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 createTBody() method must create a
new <{tbody}> element, insert it immediately after the last <{tbody}> element child in the
<{table}> element, if any, or at the end of the <{table}> element if the <{table}> element
has no <{tbody}> element children, and then must return the new <{tbody}> 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 behavior 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 throw an {{IndexSizeError}} 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 -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.
When the deleteRow(index)
method is called, the user agent must run the following steps:
If index is equal to -1, then index must be
set to the number of items in the rows collection, minus one.
Now, if index is less than zero, or greater than or equal to the
number of elements in the rows collection, the method must
instead throw an {{IndexSizeError}} exception, and these steps must be aborted.
Otherwise, the method must remove the indexth element in the
rows collection from its parent.
Here is an example of a table being used to mark up a game of Tic-tac-toe.
Note the lack of headers, which are not necessary in such a table.
X
X
0
0
X
0
X
0
Techniques for describing tables
For tables that consist of more than just a grid of cells with headers in the first row and
headers in the first column, and for any table in general where the reader might have difficulty
understanding the content, authors should include explanatory information introducing the table.
This information is useful for all users, but is especially useful for users who cannot see the
table, e.g., users of screen readers.
Such explanatory information should introduce the purpose of the table, outline its basic cell
structure, highlight any trends or patterns, and generally teach the user how to understand the
contents of the table.
For instance, the following table:
Characteristics with positive and negative sides
Negative
Characteristic
Positive
Sad
Mood
Happy
Failing
Grade
Passing
...could benefit from a description explaining the way the table is laid out, something like
"Characteristics are given in the second column, with the negative side in the left column and
the positive side in the right column".
There are a variety of ways to include this information, such as:
In prose, surrounding the table
In the following table, characteristics are given in the second column, with the negative side in the left column and the positive side in the right column.
Characteristics with positive and negative sides
Negative
Characteristic
Positive
Sad
Mood
Happy
Failing
Grade
Passing
In the example above the <{aria/aria-describedby}> attribute is used to explicitly
associate the information with the table for assistive technology users.
Next to the table, in the same figure
Characteristics are given in the second column, with the negative side in the left column and the positive side in the right column.
Characteristics with positive and negative sides
Negative
Characteristic
Positive
Sad
Mood
Happy
Failing
Grade
Passing
The <{figure}> in this example has been labeled by the table <{caption}> using <{aria/aria-labelledby}>.
Authors may also use other techniques, or combinations of the above techniques, as appropriate.
Regardless of the method used to provide additional descriptive information for a
table, if a <{table}> needs a caption, authors should use a <{caption}> element
as it is the most robust method for providing an accessible caption for a table.
The best option, of course, rather than writing a description explaining the way the table is
laid out, is to adjust the table such that no explanation is needed.
In the case of the table used in the examples above, a simple rearrangement of the table so
that the headers are on the top and left sides removes the need for an explanation as well as
removing the need for the use of headers attributes:
Characteristics with positive and negative sides
Characteristic
Negative
Positive
Mood
Sad
Happy
Grade
Failing
Passing
Techniques for table design
Good table design is key to making tables more readable and usable.
In visual media, providing column and row borders and alternating row backgrounds can be very
effective to make complicated tables more readable.
For tables with large volumes of numeric content, using monospaced fonts can help users see
patterns, especially in situations where a user agent does not render the borders.
(Unfortunately, for historical reasons, not rendering borders on tables is a common default.)
Authors are encouraged to use CSS to achieve these visual effects.
In speech media, table cells can be distinguished by reporting the corresponding headers before
reading the cell's contents, and by allowing users to navigate the table in a grid fashion,
rather than serializing the entire contents of the table in source order.
User agents are encouraged to render tables using these techniques whenever the page does not
use CSS and the table is not classified as a layout table.
If the closing tag is omitted, the element will be closed by the next element that takes part
in the table model. Content up to that element will be part of the caption.
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.
When a <{table}> element is the only content in a <{figure}> element other than the
<{figcaption}>, the <{caption}> element should be omitted in favor of the <{figcaption}>.
As noted in [[#sec-techniques-for-describing-tables|techniques for describing tables]], a
caption is the most robust method for providing an accessible caption to
a table.
A caption can introduce context for a table, making it significantly easier to understand.
Consider, for instance, the following table:
1
2
3
4
5
6
1
2
3
4
5
6
7
2
3
4
5
6
7
8
3
4
5
6
7
8
9
4
5
6
7
8
9
10
5
6
7
8
9
10
11
6
7
8
9
10
11
12
In the abstract, this table is not clear. However, with a caption giving the table's number
(for reference in the main prose) and explaining its use, it makes more sense:
Table 1.
This table shows the total score obtained from rolling two six-sided dice. The first row represents the value of the first die, the first column the value of the second die. The total is given in the cell that corresponds to the values of the two dice.
This provides the user with more context:
Table 1.
This table shows the total score obtained from rolling two
six-sided dice. The first row represents the value of the first
die, the first column the value of the second die. The total is
given in the cell that corresponds to the values of the two dice.
A <{colgroup}> element's [=start tag=] may be omitted if the first thing inside the
<{colgroup}> element is a <{col}> element, and if the element is not immediately preceded by
another <{colgroup}> element whose [=end tag=] has been omitted. (It can't be omitted if the
element is empty). A <{colgroup}> element's end tag may be omitted if the
<{colgroup}> element is not immediately followed by a space character or a
comment
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.
The <{colgroup}> element and its span attribute take part in the table model.
The span IDL attribute must
reflect the content attribute of the same name. The value must be
limited to only non-negative numbers greater than zero.
The following example shows how a <{colgroup}> consisting of three <{col}> elements can
utilize CSS to help visually format the columns of a <{table}>.
...
...
...
The next example shows how a <{colgroup}> with no child <{col}> elements can use
the <{colgroup/span}> attribute. The applied CSS will render the first two columns with
a background color, and set their width to 25%, leaving the last column with no background
color, and taking up the remaining width of the <{table}>.
{{HTMLTableColElement}}, same as for <{colgroup}> elements.
This interface defines one member, {{HTMLTableColElement/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.
The <{col}> element and its span attribute take part in the table model.
The {{HTMLTableColElement/span}} IDL attribute must reflect the content attribute of the
same name. The value must be limited to only non-negative numbers greater than zero.
For examples of the <{col}> element, refer to the examples within the <{colgroup}> section,
and the section for table examples.
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.
A <{tbody}> element's start tag may be omitted if the first thing inside the
<{tbody}> element is a <{tr}> element, and if the element is not immediately preceded by
a <{tbody}>, <{thead}>, or <{tfoot}> element whose end tag has been omitted.
(It can't be omitted if the element is empty.). A <{tbody}> element's end tag may
be omitted if the <{tbody}> element is immediately followed by a tbody or
<{tfoot}> element, or if there is no more content in the parent element.
interface HTMLTableSectionElement : HTMLElement {
[SameObject] readonly attribute HTMLCollection rows;
HTMLElement insertRow(optional long index = -1);
void deleteRow(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.
Returns an HTMLCollection of the <{tr}> elements of the table section.
tr = tbody . insertRow( [ index ] )
Creates a <{tr}> element, inserts it into the table section at the position given by
the argument, and returns the <{tr}>.
The position is relative to the rows in the table section. The index -1, which is the
default if the argument is omitted, is equivalent to inserting at the end of the table section.
If the given position is less than -1 or greater than the number of rows, throws an
{{IndexSizeError}} exception.
tbody . deleteRow(index)
Removes the <{tr}> element with the given position in the table section.
The position is relative to the rows in the table section. The index -1 is equivalent
to deleting the last row of the table section.
If the given position is less than -1 or greater than the index of the last row, or if
there are no rows, throws an {{IndexSizeError}} exception.
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 throw an {{IndexSizeError}} exception.
If index is -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, when invoked, act as follows:
If index is less than -1 or greater than the number of elements in
the rows collection, the method must throw an {{IndexSizeError}} exception.
If index is -1, remove the last element in the rows collection from
its parent.
Otherwise, remove the indexth element in the rows collection from
its parent.
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.
{{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.
This example shows a <{thead}> element being used. Notice the use of the
<{th}> element to provide headers in the thead 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.
{{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.
The following example uses a <{tfoot}> to indicate a summary of the total monthly spending,
earnings, and holdings.
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.
A <{tr}> element's end tag may be omitted if the <{tr}> element is immediately
followed by another <{tr}> element, or if there is no more content in the parent element.
Returns the position of the row in the table's rows list.
Returns -1 if the element isn't in a table.
tr . sectionRowIndex
Returns the position of the row in the table section's rows list.
Returns -1 if the element isn't in a table section.
tr . cells
Returns an HTMLCollection of the td and <{th}> elements of the row.
cell = tr . insertCell( [ index ] )
Creates a <{td}> element, inserts it into the table row at the position given by the
argument, and returns the <{td}>.
The position is relative to the cells in the row. The index -1, which is the default
if the argument is omitted, is equivalent to inserting at the end of the row.
If the given position is less than -1 or greater than the number of cells, throws an
{{IndexSizeError}} exception.
tr . deleteCell(index)
Removes the td or <{th}> element with the given position in the
row.
The position is relative to the cells in the row. The index -1 is equivalent to
deleting the last cell of the row.
If the given position is less than -1 or greater than the index of the last cell, or
if there are no cells, throws an {{IndexSizeError}} exception.
The rowIndex attribute 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 -1.
The sectionRowIndex 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 HTMLTableElement.rows collection; for table sections, that's the
HTMLTableRowElement.rows collection). If there is no such parent element, then
the attribute must return -1.
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 throw an {{IndexSizeError}} 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 act as follows:
If index is less than -1 or greater than the number of elements in
the cells collection, the method must throw an {{IndexSizeError}} exception.
If index is -1, remove the last element in the cells collection
from its parent.
Otherwise, remove the indexth element in the cells collection
from its parent.
For examples of the <{tr}> element, refer to the <{table}> examples within
[[#sec-techniques-for-describing-tables|techniques for describing tables]], and
the section for table examples.
A <{td}> element's end tag may be omitted if the element is immediately followed by
another td element or <{th}> element, or if there is no more content in the
parent element.
The <{td}> element represents a data cell in a table.
The <{td}> element and its colspan, rowspan, and headers
attributes take part in the table model.
User agents, especially in environments where displaying the table as a 2D grid is impractical,
(e.g. in speech output), sometimes add information about a cell when rendering its contents;
for instance, giving its position in the table model, or listing its header cells
as determined by the algorithm for assigning header cells.
When referring to a cell's header cells are being listed, user agents may use the value of
<{th/abbr}> to present to the user through a voice interface, instead of the full contents of the header cells themselves.
A cell's header cells are determined by the algorithm for
Forming relationships between data cells and header cells
or can be explicitly defined using the <{td/headers}> attribute.
For examples of the <{td}> element and its content attributes, refer to the
<{table}> examples within
[[#sec-techniques-for-describing-tables|techniques for describing tables]], and
the section for table examples.
A <{th}> element's end tag may be omitted if the <{th}> element is immediately
followed by a <{td}> or <{th}> element, or if there is no more content in the parent element.
The <{th}> element represents a header cell in a table.
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 some of
the subsequent cells in the same row(s).
The col keyword, which maps to the
column state
The column state means the header cell applies to some of
the subsequent cells in the same column(s).
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. A <{th}> element's scope attribute must
not be in the row group state if the element is not anchored in a row group.
The colgroup keyword, which maps to
the column group state
The colgroup group state means the header cell applies to
all the remaining cells in the column group. A <{th}> element's scope attribute
must not be in the column group state if the element is not anchored in a
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 <{th}> element may have an abbr
content attribute specified. Its value must be an alternative label for the header cell, to be
used when referencing the cell in other contexts (e.g., when describing the header cells that
apply to a data cell). It is typically an abbreviated form of the full header cell, but can
also be an expansion, or merely a different phrasing.
The following snippet shows how an author could use the <{th/abbr}> attribute to provide abbreviated or expanded forms of different header cells.
Fruits of the world
Common Fruit Name
Scientific Fruit Name
CA
LATAM
SEA
The <{th}> element and its colspan, rowspan, headers, and
scope attributes take part in the table model.
The scope IDL attribute must
reflect the content attribute of the same name, limited to only known values.
The abbr IDL attribute must
reflect the content attribute of the same name.
The following example shows how the scope attribute's rowgroup
value affects which data cells a header cell applies to.
Here is a markup fragment showing a table:
The <{tbody}> elements in this example identify the range of the row groups.
Measurement of legs and tails in Cats and English speakers
ID
Measurement
Average
Maximum
Cats
93
Legs
3.5
4
10
Tails
1
1
English speakers
32
Legs
2.67
4
35
Tails
0.33
1
This would result in the following table:
Measurement of legs and tails in Cats and English speakers
ID
Measurement
Average
Maximum
Cats
93
Legs
3.5
4
10
Tails
1
1
English speakers
32
Legs
2.67
4
35
Tails
0.33
1
The header cells in row 1 ("ID", "Measurement", "Average" and "Maximum") each apply only
to the cells in their column.
The header cells with a scope="rowgroup" ("Cats" and 'English speakers') apply to
all the cells in their row group other than the cells (to their left) in column 1:
The header "Cats" (row 2, column 2) applies to the headers "Legs" (row 3, column 2)
and "Tails" (row 4, column 2) and to the data cells in rows 2, 3 and 4 of the "Average"
and "Maximum" columns.
The header 'English speakers' (row 5, column 2) applies to the headers "Legs"
(row 6, column 2) and "Tails" (row 7, column 2) and to the data cells in rows 5, 6
and 7 of the "Average" and "Maximum" columns.
Each of the "Legs" and "Tails" header cells has a scope="row" and therefore
apply to the data cells (to the right) in their row, from the "Average" and "Maximum" columns.
Attributes common to td and <{th}> elements
The <{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. For this attribute, the value zero
means that the cell is to span all the remaining rows in the row group.
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 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 <{global/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 <{global/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 IDid. 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;
[SameObject, PutForwards=value] readonly attribute DOMTokenList headers;
readonly attribute long cellIndex;
};
cell . 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. Its default value is 1.
The rowSpan IDL attribute must
reflect the rowspan content attribute. Its default value 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.
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
0 ≤ x < xwidth,
and the y coordinates are always in the range
0 ≤ y < yheight.
If one or both of xwidth and yheight 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.
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=xwidth-1, for a particular value of
y. Rows usually correspond to <{tr}> elements, though a row group can have
some implied rows at the end in some cases involving cells spanning multiple rows.
A column is a complete set of slots from
y=0 to y=yheight-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, groupy) with a particular height such that the row group
covers all the slots with coordinates (x, y) where 0 ≤ x < xwidth 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, 0) with a particular width such
that the column group covers all the slots with coordinates (x, y)
where groupx ≤ x < groupx+width and 0 ≤ y < yheight.
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.
However, it is 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.
Forming a table
User agents must use the following algorithm to determine
which elements correspond to which slots in a table associated with a <{table}> element,
the dimensions of the table (xwidth and yheight), and
The algorithm selects the first <{caption}> encountered and assigns it as the
caption for the table, and selects the first <{thead}> and processes it.
Until there is a <{thead}>, <{tfoot}>, <{tbody}> or <{tr}> element, it processes any
<{colgroup}> elements encountered, and any <{col}> children, to create column groups.
Finally, from the first <{thead}>, <{tfoot}>, <{tbody}> or <{tr}> element encountered
as a child of the <{table}> it processes those elements, moving the first <{tfoot}>
encountered to the end of the table respectively.
Let xwidth be zero.
Let yheight be zero.
Let table footer be null.
Let table header be null.
Let the table be the table represented by the <{table}> element.
The xwidth and yheight 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:
<{colgroup}>
<{thead}>
<{tbody}>
<{tfoot}>
<{tr}>
If the current element is a <{colgroup}>, follow these substeps:
Column groups: Process the current element according to the
appropriate case below:
If the current element has any <{col}> element children
Follow these steps:
Let xstart have the value of xwidth.
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 xwidth by span.
Let the last spancolumns 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=xstart to
x=xwidth-1 form a new column group, anchored at the slot (xstart, 0), with width xwidth-xstart, corresponding to the <{colgroup}> element.
If the current element has no <{col}> element children
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 or zero, then let span
be 1.
Increase xwidth by span.
Let the last spancolumns in the table form a new
column group, anchored at the slot
(xwidth-span, 0), with width span,
corresponding to the <{colgroup}> element.
Advance the current element to the next child of the <{table}>.
While the current element is not one of the following elements, advance
the current element to the next child of the table:
<{colgroup}>
<{thead}>
<{tbody}>
<{tfoot}>
<{tr}>
If the current element is a <{colgroup}> element, jump to the step labeled
column groups above.
Let ycurrent 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 <{tfoot}> and the value of
table footer is null, then run the following substeps:
let table footer be the current element;
advance the current element to the next child of the <{table}>, and
return to the step labeled rows.
If the current element is a <{thead}> and the value of
table header is null, then run the following substeps:
let table header be the current element;
advance the current element to the next child of the <{table}>, and
return to the step labeled rows.
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.
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 ystart have the value of yheight.
For each <{tr}> element that is a child of the element being processed, in tree
order, run the algorithm for processing rows.
If yheight > ystart, then let all the last rows in the table from y=ystart to y=yheight-1 form a new row
group, anchored at the slot with coordinate (0, ystart), with height yheight-ystart, corresponding
to the element being processed.
If the <{tr}> element being processed has no td or th
element children, then increase ycurrent by 1, abort
this set of steps, and return to the algorithm above.
Let current cell be the first td or <{th}> element child
in the <{tr}> element being processed.
Cells: While xcurrent is less than xwidth and the slot with coordinate (xcurrent, ycurrent) already has a
cell assigned to it, increase xcurrent by 1.
If xcurrent is equal to xwidth, increase xwidth by 1. (xcurrent is never greater than xwidth.)
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 and the <{table}> element's
node document is not set to quirks mode, then let cell grows
downward be true, and set rowspan to 1. Otherwise, let cell grows downward be false.
If xwidth < xcurrent+colspan, then let xwidth be xcurrent+colspan.
If yheight < ycurrent+rowspan, then let yheight be ycurrent+rowspan.
Let the slots with coordinates (x, y) such that xcurrent ≤ x < xcurrent+colspan and ycurrent ≤ y < ycurrent+rowspan be covered by a
new cellc, 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 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, xcurrent, colspan}
to the list of downward-growing cells.
Increase xcurrent by colspan.
If current cell is the last td or <{th}> element child in
the <{tr}> element being processed, then increase ycurrent by 1, abort this set of steps, and return to the algorithm
above.
Let current cell be the next td or <{th}> element child
in the <{tr}> element being processed.
Return to the step labeled 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, cellx, width} tuple in the list of downward-growing cells, if any, extend the cellcell so that it also covers the slots with
coordinates (x, ycurrent), where cellx ≤ x < cellx+width.
Forming relationships between data cells and header cells
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 (principalx, principaly) be the coordinate of the slot to which the principal
cell is anchored.
If the principal cell has a headers attribute specified
Take 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.
If principal cell does not have a headers attribute specified
Let principalwidth be the width of the principal cell.
Let principalheight be the height of the principal cell.
For each value of y from principaly to principaly+principalheight-1, run
the internal algorithm for scanning and assigning header cells, with the principal cell, the header list, the initial coordinate
(principalx,y), and the
increments Δx=-1 and Δy=0.
For each value of x from principalx to principalx+principalwidth-1, run
the internal algorithm for scanning and assigning header cells, with the principal cell, the header list, the initial coordinate
(x,principaly), 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 principalx+principalwidth-1 and a y-coordinate less than or
equal to principaly+principalheight-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 principalx+principalwidth-1 and a y-coordinate less than or
equal to principaly+principalheight-1 to 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
(initialx, initialy),
and Δx and Δy increments, is as follows:
Let x equal initialx.
Let y equal initialy.
Let opaque headers be an empty list of cells.
If principal cell is a header cell
Let in header block be true, and let
headers from current header block be a list of cells containing just the
principal cell.
Otherwise
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).
If current cell is a header cell
Set in header block to true.
Add current cell to headers from current header block.
Let blocked be false.
If Δx is 0
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 Δy is 0
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.
If current cell is a data cell and in header block is true
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:
The cell's <{td/scope}> attribute is in the column state, or
The cell's <{td/scope}> attribute is in the auto state,
and there are no data cells in any of the cells covering slots with x-coordinates
x .. x+width-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:
The cell's <{td/scope}> attribute is in the row state, or
The cell's <{td/scope}> 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 y-coordinates y ..
y+height-1.
A header cell is said to be a column group header if its <{td/scope}> attribute is
in the column group state.
A header cell is said to be a row group header if its <{td/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.
Examples
This section is non-normative.
The following examples showcase different <{table}> markup patterns, and how they could appear in
browsers with some styling provided by CSS.
This first example shows how an one might mark up the bottom part of table 45 of the
Smithsonian physical tables, Volume 71:
Specification values: Steel, Castings, Ann. A.S.T.M. A27-16, Class B;* P max. 0.06; S max. 0.05.
Grade.
Yield Point.
Ultimate tensile strength
Per cent elong. 50.8mm or 2 in.
Per cent reduct. area.
kg/mm2
lb/in2
Hard
0.45 ultimate
56.2
80,000
15
20
Medium
0.45 ultimate
49.2
70,000
18
25
Soft
0.45 ultimate
42.2
60,000
22
30
This example produces the following table in a browser:
Specification values: Steel, Castings, Ann. A.S.T.M. A27-16, Class B;* P max. 0.06; S max. 0.05.
Grade.
Yield Point.
Ultimate tensile strength
Per cent elong. 50.8mm or 2 in.
Per cent reduct. area.
kg/mm2
lb/in2
Hard
0.45 ultimate
56.2
80,000
15
20
Medium
0.45 ultimate
49.2
70,000
18
25
Soft
0.45 ultimate
42.2
60,000
22
30
The following shows how one might mark up the gross margin table on page 46 of Apple, Inc's
10-K filing for fiscal year 2008:
2008
2007
2006
Net sales
$ 32,479
$ 24,006
$ 19,315
Cost of sales
21,334
15,852
13,717
Gross margin
$ 11,145
$ 8,154
$ 5,598
Gross margin percentage
34.3%
34.0%
29.0%
This example produces the following table in a browser:
2008
2007
2006
Net sales
$ 32,479
$ 24,006
$ 19,315
Cost of sales
21,334
15,852
13,717
Gross margin
$ 11,145
$ 8,154
$ 5,598
Gross margin percentage
34.3%
34.0%
29.0%
The following shows how one might mark up the operating expenses table from lower on the same
page of that document:
2008
2007
2006
Research and development
$ 1,109
$ 782
$ 712
Percentage of net sales
3.4%
3.3%
3.7%
Selling, general, and administrative
$ 3,761
$ 2,963
$ 2,433
Percentage of net sales
11.6%
12.3%
12.6%
This example produces the following table in a browser:
2008
2007
2006
Research and development
$ 1,109
$ 782
$ 712
Percentage of net sales
3.4%
3.3%
3.7%
Selling, general, and administrative
$ 3,761
$ 2,963
$ 2,433
Percentage of net sales
11.6%
12.3%
12.6%
The following shows how one might mark up a coffee order that includes the team,
types of coffee, how many cups, and if sugar is needed to fulfill the order:
Daily coffee order for team meetings
Team
Types of Coffee
Cups
Sugar Packets?
Design
House Blend
French Roast
8
3
Yes
Development
Cold Brew
Espresso
6
5
No
This example produces the following table in a browser: