4.9 Tabular data

4.9.1 The table element

Categories:
Flow content.
Palpable content.
Contexts in which this element can be used:
Where flow content is expected.
Content model:
In this order: optionally a caption element, followed by 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), optionally intermixed with one or more script-supporting elements.
Tag omission in text/html:
Neither tag is omissible.
Content attributes:
Global attributes
sortable — Enables a sorting interface for the table
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;
  HTMLElement createTBody();
  readonly attribute HTMLCollection rows;
  HTMLElement insertRow(optional long index = -1);
  void deleteRow(long index);
           attribute boolean sortable;
  void stopSorting();
};

The table element represents data with more than one dimension, in the form of a table.

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.

Authors are encouraged to provide information describing how to interpret complex tables. Guidance on how to provide such information is given below.

Tables must not be used as layout aids. Historically, some Web authors have misused tables in HTML as a way to control their page layout. This usage is non-conforming, because tools attempting to extract tabular data from such documents would obtain very confusing results. In particular, users of accessibility tools like screen readers are likely to find it very difficult to navigate pages with tables used for layout.

There are a variety of alternatives to using HTML tables for layout, primarily using CSS positioning and the CSS table model. [CSS]

Authors are encouraged to consider using some of the table design techniques described below to make tables easier to navigate for users.


The sortable attribute is used in the table sorting model.


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.

Here is an example of a table being used to mark up a Sudoku puzzle. Observe the lack of headers, which are not necessary in such a table.

<section>
 <style scoped>
  table { border-collapse: collapse; border: solid thick; }
  colgroup, tbody { border: solid medium; }
  td { border: solid thin; height: 1.4em; width: 1.4em; text-align: center; padding: 0; }
 </style>
 <h1>Today's Sudoku</h1>
 <table>
  <colgroup><col><col><col>
  <colgroup><col><col><col>
  <colgroup><col><col><col>
  <tbody>
   <tr> <td> 1 <td>   <td> 3 <td> 6 <td>   <td> 4 <td> 7 <td>   <td> 9
   <tr> <td>   <td> 2 <td>   <td>   <td> 9 <td>   <td>   <td> 1 <td>
   <tr> <td> 7 <td>   <td>   <td>   <td>   <td>   <td>   <td>   <td> 6
  <tbody>
   <tr> <td> 2 <td>   <td> 4 <td>   <td> 3 <td>   <td> 9 <td>   <td> 8
   <tr> <td>   <td>   <td>   <td>   <td>   <td>   <td>   <td>   <td>
   <tr> <td> 5 <td>   <td>   <td> 9 <td>   <td> 7 <td>   <td>   <td> 1
  <tbody>
   <tr> <td> 6 <td>   <td>   <td>   <td> 5 <td>   <td>   <td>   <td> 2
   <tr> <td>   <td>   <td>   <td>   <td> 7 <td>   <td>   <td>   <td>
   <tr> <td> 9 <td>   <td>   <td> 8 <td>   <td> 2 <td>   <td>   <td> 5
 </table>
</section>
4.9.1.1 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 use the table.

For instance, the following table:

Characteristics with positive and negative sides
Negative Characteristic Positive
Sad Mood Happy
Failing Grade Passing

...might 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
<p>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.</p>
<table>
 <caption>Characteristics with positive and negative sides</caption>
 <thead>
  <tr>
   <th id="n"> Negative
   <th> Characteristic
   <th> Positive
 <tbody>
  <tr>
   <td headers="n r1"> Sad
   <th id="r1"> Mood
   <td> Happy
  <tr>
   <td headers="n r2"> Failing
   <th id="r2"> Grade
   <td> Passing
</table>
In the table's caption
<table>
 <caption>
  <strong>Characteristics with positive and negative sides.</strong>
  <p>Characteristics are given in the second column, with the
  negative side in the left column and the positive side in the right
  column.</p>
 </caption>
 <thead>
  <tr>
   <th id="n"> Negative
   <th> Characteristic
   <th> Positive
 <tbody>
  <tr>
   <td headers="n r1"> Sad
   <th id="r1"> Mood
   <td> Happy
  <tr>
   <td headers="n r2"> Failing
   <th id="r2"> Grade
   <td> Passing
</table>
In the table's caption, in a details element
<table>
 <caption>
  <strong>Characteristics with positive and negative sides.</strong>
  <details>
   <summary>Help</summary>
   <p>Characteristics are given in the second column, with the
   negative side in the left column and the positive side in the right
   column.</p>
  </details>
 </caption>
 <thead>
  <tr>
   <th id="n"> Negative
   <th> Characteristic
   <th> Positive
 <tbody>
  <tr>
   <td headers="n r1"> Sad
   <th id="r1"> Mood
   <td> Happy
  <tr>
   <td headers="n r2"> Failing
   <th id="r2"> Grade
   <td> Passing
</table>
Next to the table, in the same figure
<figure>
 <figcaption>Characteristics with positive and negative sides</figcaption>
 <p>Characteristics are given in the second column, with the
 negative side in the left column and the positive side in the right
 column.</p>
 <table>
  <thead>
   <tr>
    <th id="n"> Negative
    <th> Characteristic
    <th> Positive
  <tbody>
   <tr>
    <td headers="n r1"> Sad
    <th id="r1"> Mood
    <td> Happy
   <tr>
    <td headers="n r2"> Failing
    <th id="r2"> Grade
    <td> Passing
 </table>
</figure>
Next to the table, in a figure's figcaption
<figure>
 <figcaption>
  <strong>Characteristics with positive and negative sides</strong>
  <p>Characteristics are given in the second column, with the
  negative side in the left column and the positive side in the right
  column.</p>
 </figcaption>
 <table>
  <thead>
   <tr>
    <th id="n"> Negative
    <th> Characteristic
    <th> Positive
  <tbody>
   <tr>
    <td headers="n r1"> Sad
    <th id="r1"> Mood
    <td> Happy
   <tr>
    <td headers="n r2"> Failing
    <th id="r2"> Grade
    <td> Passing
 </table>
</figure>

Authors may also use other techniques, or combinations of the above techniques, as appropriate.

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:

<table>
 <caption>Characteristics with positive and negative sides</caption>
 <thead>
  <tr>
   <th> Characteristic
   <th> Negative
   <th> Positive
 <tbody>
  <tr>
   <th> Mood
   <td> Sad
   <td> Happy
  <tr>
   <th> Grade
   <td> Failing
   <td> Passing
</table>
4.9.1.2 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.)

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.

Authors are encouraged to use CSS to achieve these effects.

4.9.2 The caption element

Categories:
None.
Contexts in which this element can be used:
As the first element child of a table element.
Content model:
Flow content, but with no descendant table elements.
Tag omission in text/html:
A caption element's end tag can be omitted if the caption element is not immediately followed by a space character or a comment.
Content attributes:
Global attributes
DOM interface:
interface HTMLTableCaptionElement : 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.

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.

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:

<caption>
<p>Table 1.
<p>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.
</caption>

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.

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

4.9.3 The colgroup element

Categories:
None.
Contexts in which this element can be used:
As a child of a table element, after any caption elements and before any thead, tbody, tfoot, and tr elements.
Content model:
If the span attribute is present: Empty.
If the span attribute is absent: Zero or more col and template elements.
Tag omission in text/html:
A colgroup element's start tag can 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 can be omitted if the colgroup element is not immediately followed by a space character or a comment.
Content attributes:
Global attributes
span — Number of columns spanned by the element
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.

4.9.4 The col element

Categories:
None.
Contexts in which this element can be used:
As a child of a colgroup element that doesn't have a span attribute.
Content model:
Empty.
Tag omission in text/html:
No end tag.
Content attributes:
Global attributes
span — Number of columns spanned by the element
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.

4.9.5 The tbody element

Categories:
None.
Contexts in which this element can 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:
Zero or more tr and script-supporting elements
Tag omission in text/html:
A tbody element's start tag can 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 can 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.
Content attributes:
Global attributes
DOM interface:
interface HTMLTableSectionElement : HTMLElement {
  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.

tbody . rows

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.

4.9.6 The thead element

Categories:
None.
Contexts in which this element can 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:
Zero or more tr and script-supporting elements
Tag omission in text/html:
A thead element's end tag can be omitted if the thead element is immediately followed by a tbody or tfoot element.
Content attributes:
Global attributes
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.

This example shows a thead element being used. Notice the use of both th and td elements in the thead element: the first row is the headers, and the second row is an explanation of how to fill in the table.

<table>
 <caption> School auction sign-up sheet </caption>
 <thead>
  <tr>
   <th><label for=e1>Name</label>
   <th><label for=e2>Product</label>
   <th><label for=e3>Picture</label>
   <th><label for=e4>Price</label>
  <tr>
   <td>Your name here
   <td>What are you selling?
   <td>Link to a picture
   <td>Your reserve price
 <tbody>
  <tr>
   <td>Ms Danus
   <td>Doughnuts
   <td><img src="http://example.com/mydoughnuts.png" title="Doughnuts from Ms Danus">
   <td>$45
  <tr>
   <td><input id=e1 type=text name=who required form=f>
   <td><input id=e2 type=text name=what required form=f>
   <td><input id=e3 type=url name=pic form=f>
   <td><input id=e4 type=number step=0.01 min=0 value=0 required form=f>
</table>
<form id=f action="/auction.cgi">
 <input type=button name=add value="Submit">
</form>

4.9.7 The tfoot element

Categories:
None.
Contexts in which this element can 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:
Zero or more tr and script-supporting elements
Tag omission in text/html:
A tfoot element's end tag can be omitted if the tfoot element is immediately followed by a tbody element, or if there is no more content in the parent element.
Content attributes:
Global attributes
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.

4.9.8 The tr element

Categories:
None.
Contexts in which this element can 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:
Zero or more td, th, and script-supporting elements
Tag omission in text/html:
A tr element's end tag can be omitted if the tr element is immediately followed by another tr element, or if there is no more content in the parent element.
Content attributes:
Global attributes
DOM interface:
interface HTMLTableRowElement : HTMLElement {
  readonly attribute long rowIndex;
  readonly attribute long sectionRowIndex;
  readonly attribute HTMLCollection cells;
  HTMLElement insertCell(optional long index = -1);
  void deleteCell(long index);
};

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

tr . rowIndex

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.

4.9.9 The td element

Categories:
Sectioning root.
Contexts in which this element can be used:
As a child of a tr element.
Content model:
Flow content.
Tag omission in text/html:
A td element's end tag can be omitted if the td element is immediately followed by a td or th element, or if there is no more content in the parent element.
Content attributes:
Global attributes
colspan — Number of columns that the cell is to span
rowspan — Number of rows that the cell is to span
headers — The header cells for this cell
DOM interface:
interface HTMLTableDataCellElement : HTMLTableCellElement {};

The td element represents a data cell in a table.

4.9.10 The th element

Categories:
If the th element is a sorting interface th element: Interactive content.
Otherwise: None.
Contexts in which this element can be used:
As a child of a tr element.
Content model:
Flow content, but with no header, footer, sectioning content, or heading content descendants, and if the th element is a sorting interface th element, no interactive content descendants.
Tag omission in text/html:
A th element's end tag can 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.
Content attributes:
Global attributes
colspan — Number of columns that the cell is to span
rowspan — Number of rows that the cell is to span
headers — The header cells for this cell
scope — Specifies which cells the header cell applies to
abbr — Alternative label to use for the header cell when referencing the cell in other contexts
sortedColumn sort direction and ordinality
DOM interface:
interface HTMLTableHeaderCellElement : HTMLTableCellElement {
           attribute DOMString scope;
           attribute DOMString abbr;
           attribute DOMString sorted;
  void sort();
};

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 column 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 sorted attribute is used in the table sorting model.

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:

<table>
 <thead>
  <tr> <th> ID <th> Measurement <th> Average <th> Maximum
 <tbody>
  <tr> <td> <th scope=rowgroup> Cats <td> <td>
  <tr> <td> 93 <th scope=row> Legs <td> 3.5 <td> 4
  <tr> <td> 10 <th scope=row> Tails <td> 1 <td> 1
 <tbody>
  <tr> <td> <th scope=rowgroup> English speakers <td> <td>
  <tr> <td> 32 <th scope=row> Legs <td> 2.67 <td> 4
  <tr> <td> 35 <th scope=row> Tails <td> 0.33 <td> 1
</table>

This would result in the following table:

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 headers in the first row all apply directly down to the rows in their column.

The headers with the explicit scope attributes apply to all the cells in their row group other than the cells in the first column.

The remaining headers apply just to the cells to the right of them.

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


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.

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 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;
};
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.

4.9.12 Table sorting model

The sortable attribute on table elements is a boolean attribute. When present, it indicates that the user agent is to allow the user to sort the table.

To make a column sortable in a table with a thead, the column needs to have th element that does not span multiple columns in a thead above any rows that it is to sort.

To make a column sortable in a table without a thead, the column needs to have th element that does not span multiple columns in the first tr element of the table, where that tr element is not in a tfoot.

When the user selects a column by which to sort, the user agent sets the th element's sorted attribute. This attribute can also be set manually, to indicate that the table should be automatically sorted, even when scripts modify the page on when the page is loaded.

The sorted attribute, if specified, must have a value that is a set of space-separated tokens consisting of optionally a token whose value is an ASCII case-insensitive match for the string "reversed", and optionally a token whose value is a valid non-negative integer greater than zero, in either order.

In other words, ignoring spaces and case, the sorted attribute's value can be empty, "reversed", "1", "reversed 1", or "1 reversed", where "1" is any number equal to or greater than 1.

While one or more th elements in the table have a sorted attribute, the user agent will keep the table's data rows sorted. The value of the attribute controls how the column is used in determining the sort order. The reversed keyword means that the column sort direction is reversed, rather than normal, which is the default if the keyword is omitted. The number, if present, indicates the column key ordinality; if the number is omitted, the column is the primary key, as if the value 1 had been specified.

Thus, sorted="1" indicates the table's primary key, sorted="2" its secondary key, and so forth.


A sorting-capable th element is a th element that matches all the following conditions simultaneously:

In other words, each column can have one sorting-capable th element; this will be the highest th in a thead that spans no other columns, or, if there is no thead, the th in the first row (that is not in a tfoot), assuming it spans no columns.

The sorting-capable th elements of the table element table are the sorting-capable th elements whose cell's table is table.

A table element table is a sorting-capable table element if there are one or more sorting-capable th elements of the table element table.

A th element is a sorting-enabled th element if it is a sorting-capable th element and it has a sorted attribute.

The sorting-enabled th elements of the table element table are the sorting-enabled th elements whose cell's table is table.

A table element table is a sorting-enabled table element if there are one or more sorting-capable th elements of the table element table, and at least one of them is a sorting-enabled th element (i.e. at least one has a sorted attribute).

A table element is a table element with a user-agent exposed sorting interface if it is a sorting-capable table element and has a sortable attribute specified.

A sorting interface th element is a sorting-capable th element whose cell's table is a table element with a user-agent exposed sorting interface.


Each table element has a currently-sorting flag, which must initially be false.


The sorted attribute must not be specified on th elements that are not sorting-capable th elements. The sortable attribute must not be specified on table elements that are not sorting-capable table elements.

A table must not have two th elements whose sorted attribute have the same column key ordinality.

th . sort()

Act as if the user had indicated that this was to be the new primary sort column.

The table won't actually be sorted until the script terminates.

table . stopSorting()

Removes all the sorted attributes that are causing the table to automatically sort its contents, if any.

4.9.13 Examples

The following shows how might one mark up the bottom part of table 45 of the Smithsonian physical tables, Volume 71:

<table>
 <caption>Specification values: <b>Steel</b>, <b>Castings</b>,
 Ann. A.S.T.M. A27-16, Class B;* P max. 0.06; S max. 0.05.</caption>
 <thead>
  <tr>
   <th rowspan=2>Grade.</th>
   <th rowspan=2>Yield Point.</th>
   <th colspan=2>Ultimate tensile strength</th>
   <th rowspan=2>Per cent elong. 50.8mm or 2 in.</th>
   <th rowspan=2>Per cent reduct. area.</th>
  </tr>
  <tr>
   <th>kg/mm<sup>2</sup></th>
   <th>lb/in<sup>2</sup></th>
  </tr>
 </thead>
 <tbody>
  <tr>
   <td>Hard</td>
   <td>0.45 ultimate</td>
   <td>56.2</td>
   <td>80,000</td>
   <td>15</td>
   <td>20</td>
  </tr>
  <tr>
   <td>Medium</td>
   <td>0.45 ultimate</td>
   <td>49.2</td>
   <td>70,000</td>
   <td>18</td>
   <td>25</td>
  </tr>
  <tr>
   <td>Soft</td>
   <td>0.45 ultimate</td>
   <td>42.2</td>
   <td>60,000</td>
   <td>22</td>
   <td>30</td>
  </tr>
 </tbody>
</table>

This table could look like this:

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

<table>
 <thead>
  <tr>
   <th>
   <th>2008
   <th>2007
   <th>2006
 <tbody>
  <tr>
   <th>Net sales
   <td>$ 32,479
   <td>$ 24,006
   <td>$ 19,315
  <tr>
   <th>Cost of sales
   <td>  21,334
   <td>  15,852
   <td>  13,717
 <tbody>
  <tr>
   <th>Gross margin
   <td>$ 11,145
   <td>$  8,154
   <td>$  5,598
 <tfoot>
  <tr>
   <th>Gross margin percentage
   <td>34.3%
   <td>34.0%
   <td>29.0%
</table>

This table could look like this:

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:

<table>
 <colgroup> <col>
 <colgroup> <col> <col> <col>
 <thead>
  <tr> <th> <th>2008 <th>2007 <th>2006
 <tbody>
  <tr> <th scope=rowgroup> Research and development
       <td> $ 1,109 <td> $ 782 <td> $ 712
  <tr> <th scope=row> Percentage of net sales
       <td> 3.4% <td> 3.3% <td> 3.7%
 <tbody>
  <tr> <th scope=rowgroup> Selling, general, and administrative
       <td> $ 3,761 <td> $ 2,963 <td> $ 2,433
  <tr> <th scope=row> Percentage of net sales
       <td> 11.6% <td> 12.3% <td> 12.6%
</table>

This table could look like this:

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%

Sometimes, tables are used for dense data. For examples, here a table is used to show entries in an access log:

<table sortable>
 <thead>
  <tr>
   <th sorted> Timestamp
   <th> IP
   <th> Message
 <tbody>
  <tr>
   <td> <time>21:01</time>
   <td> 128.30.52.199
   <td> Exceeded ingress limit
  <tr>
   <td> <time>21:04</time>
   <td> 128.30.52.3
   <td> Authentication failure
  <tr>
   <td> <time>22:35</time>
   <td> 128.30.52.29
   <td> Malware command request blocked
  <tr>
   <td> <time>22:36</time>
   <td> 128.30.52.3
   <td> Authentication failure
</table>

Because the table element has a sortable attribute, the column headers can be selected to change the table's sort order.

This might render as follows:

The table as marked above, but with the column headers having interactive affordances to select which column to sort by, the first being already selected.

If the user activates the second column, the table might change as follows:

The same table, but with the second column header's interactive affordance marked as selected, with the IP addresses sorted in numeric order (first the rows with the address ending in '3', then the row with the address ending in '29', and finally the row with the address ending in '199'.

If the user activates the second column again, reversing the sort order, it might change as follows:

The same table, but with the second column header's interactive affordance marked as selected and reversed, with the IP addresses sorted in reverse numeric order (first the row with the address ending in '199', then the row with the address ending in '29', and finally the rows with the address ending in '3'.