The <tfoot> Element
Technical summary
tfoot is a row group for column summaries in its parent table. It can contain a total or another summary, but the element does not calculate values.
Conforming markup places it after the table body and allows at most one direct tfoot child. Its DOM interface is HTMLTableSectionElement. HTML-AAM maps native tfoot to the rowgroup role.
Definition, placement, and content model
| Item | Specification | Conditions and limits |
|---|---|---|
| Meaning | A row group for the parent table's column summaries (footers) | It does not calculate values, set visual placement, or define a webpage footer |
| Context | A child of table | After caption, colgroup, thead, and the table body or direct table rows; at most one direct tfoot child |
| Content model | Zero or more tr and script-supporting elements | An empty tfoot is allowed by the content model |
| Start and end tags | The start tag is required | The end tag may be omitted only when the parent has no more content |
| DOM interface | HTMLTableSectionElement | thead and tbody use the same interface |
| Element-specific attributes | None | Global attributes are available |
tfoot is structural markup for summary rows. Adding it does not calculate totals or automatically associate cells. Rows and cells are expressed with tr, th, and td.
Row groups and table row order
thead, tbody, and tfoot are table row groups with different purposes. The conforming table content model places an optional tfoot after the table body: zero or more tbody elements, or one or more direct tr elements.
<table>
<caption>Quarterly revenue</caption>
<thead>...heading rows...</thead>
<tbody>...data rows...</tbody>
<tfoot>...summary rows...</tfoot>
</table>
HTMLTableElement.rows is a live HTMLCollection of table rows. Its order is not simply tree order: it puts thead rows first, then tbody or direct table rows, and tfoot rows last. Inspect table.children as well when the actual DOM child order matters.
HTMLTableSectionElement and table APIs
| Member | Return value or action | Boundary |
|---|---|---|
tfoot.rows | An HTMLCollection of the section's direct tr children | Live collection; reflects row insertions and removals |
tfoot.insertRow(index) | Inserts a new tr in the tfoot | -1 means the end; an out-of-range index throws IndexSizeError |
tfoot.deleteRow(index) | Removes the selected tr from the tfoot | -1 means the last row; an invalid index or empty section throws IndexSizeError |
table.tFoot | The first direct tfoot child, or null | Singular getter on HTMLTableElement |
table.createTFoot() | Returns the existing first tfoot, or creates one and inserts it at the end of the table | Does not create a summary row |
table.deleteTFoot() | Removes the first direct tfoot child | No effect when none exists |
const table = document.querySelector("table");
const foot = table.tFoot;
foot.rows.length; // number of rows in this tfoot
foot.insertRow(-1); // append a row to this tfoot
table.createTFoot(); // return the existing one if present
table.insertRow(-1) appends to the section containing the last row in the table's rows collection. If that row belongs to tfoot, the new row is added there. The insertion target differs in other cases, such as a table whose tfoot is empty; use tfoot.insertRow() when a specific section is intended.
The DOM built by the parser
The conforming table content model puts tfoot after the table body. The HTML parser can also build a DOM from non-conforming input. In this input, the child order in the tree and the order in table.rows differ:
<table>
<tfoot><tr><td>Total</td></tr></tfoot>
<tbody><tr><td>Item</td></tr></tbody>
</table>
// Chrome 155 observed DOM child order: tfoot, tbody
// table.rows order: tbody tr, tfoot tr
This parser recovery is not a reason to write tfoot first. In ordinary HTML, put it after the table body. Check DOM child order and API collection order separately.
Accessibility mapping
HTML-AAM maps native tfoot to the WAI-ARIA rowgroup role. This exposes a group of rows; it does not make tfoot the table's name or the heading for its summary row. Use th scope="row" for the summary row's heading and td for its value.
A Chrome 155 browser role query exposed three rowgroup roles in a named table; the last group contained the summary row. This is a browser Accessibility role-query observation for the selected fixture. The normative HTML-AAM mapping, Windows UI Automation and other platform APIs, and screen-reader speech are separate evidence layers.
Facts and evidence
The table connects core normative claims to their sources. Normative mappings and observations in the selected browser are kept separate.
| Type | Fact | Conditions and scope | Status | Source |
|---|---|---|---|---|
| SPEC | tfoot represents the footer rows that summarize columns in its parent table and participates in the table model. | Meaning, context, content model, and end-tag omission conditions. | Reviewed | HTML Standard: the tfoot element |
| SPEC | The conforming table content model allows an optional tfoot after the table body, with at most one direct tfoot child. | The body is zero or more tbody elements, or one or more direct tr elements. | Reviewed | HTML Standard: the table element |
| SPEC | tfoot uses HTMLTableSectionElement; the table exposes tFoot, createTFoot(), and deleteTFoot(). | Distinguishes section row APIs from the table-level row collection. | Reviewed | HTML Standard: table section APIs |
| SPEC | HTML-AAM maps native tfoot to the rowgroup role. | Keep normative mapping separate from browser AX tree, platform APIs, and assistive-technology output. | Reviewed | HTML-AAM: tfoot |
Evidence
- HTML Standard: The
tfootelement — meaning, context, content model, tag omission, and table section interface - HTML Standard: The
tableelement — table child order and the table row collection - HTML Standard: Parsing tables — parser behavior for table tokens
- HTML Accessibility API Mappings:
tfoot— nativerowgrouprole - Web Platform Tests:
tfootrows — section row collection - Web Platform Tests:
tFoot.html— table footer getter and methods - Web Platform Tests: footer before body —
table.insertRow(-1)with this parsed child order
Implementation evidence
Specification requirements, Chrome observations from the fixture, WPT runs, and browser Accessibility role queries are recorded separately. Each result is limited to the stated conditions and scope.
| Type | Reproduced scope | Conditions recorded | Status |
|---|---|---|---|
| IMPL | HTMLTableSectionElement, table.tFoot, createTFoot() / deleteTFoot(), tfoot.rows and section row APIs, table.rows ordering, and parser child order |
2026-10-18 JST / Chrome UA 155.0.0.0 (Windows NT 10.0 UA) / viewport 1280×720 / navigator.language=ja. Served build-config/yugien/research-results/tfoot-v1/ at loopback 127.0.0.1:4199; fixture checks passed 17/17. Confirmed the interface, getter, creation/deletion methods, live row collection, row APIs, DOM and table.rows order when the parser receives tfoot before tbody, and permitted end-tag omission. One Chrome environment only; other browsers, OS builds, and platform APIs were not measured. |
Partial observation (Chrome 155 / fixture 17/17) |
| WPT | Selected WPTs for tfoot.rows, table.tFoot / createTFoot() / deleteTFoot(), and table.insertRow(-1) when tfoot precedes tbody |
2026-10-18 JST / Chrome UA 155.0.0.0 / wpt.live. rows.html: 1/1 passed; tFoot.html: 2/2 passed; insertRow-tfoot-before-tbody.html: 1/1 passed. Total: 4/4 passed. The exact upstream revision served by wpt.live could not be pinned. Unselected tests and other browsers were not run.The test version used was not recorded. The linked test may change, so this result cannot be repeated with certainty against the same version. |
4/4 selected tests passed (wpt.live revision not pinned) |
| AAM | Exposure of a named table, rowgroups, and rows through Chrome browser role queries | 2026-10-18 JST / Chrome UA 155.0.0.0 (Windows NT 10.0 UA) / viewport 1280×720 / navigator.language=ja. Queried the fixture table named Quarterly revenue by role and observed 1 table, 3 rowgroups, and 4 rows. The third rowgroup query contained the summary row Total 30000. This is a browser role-query observation; Windows UI Automation and other platform APIs, and screen-reader speech were not measured. |
Partial observation (Chrome 155 browser role query / one environment) |
A browser role query is not the same measurement as a platform Accessibility API or screen-reader speech. The tested layer and unmeasured scope remain separate.
Coverage and open issues
- Specification checkedMeaning, placement, content model, tag omission, HTMLTableSectionElement and table APIs, table row collection, and HTML-AAM mapping
- Selected observationsChrome 155 fixture 17/17; selected WPT 4/4; browser role query: 1 table, 3 rowgroups, and 4 rows
- OpenOnly three selected WPT files were run. The upstream revision served by wpt.live was not pinned.
- OpenOther browsers and operating systems, platform Accessibility APIs, screen readers, printing, all parser-recovery paths, and Expert-gap Review
This Topic has initial coverage. Passing the selected fixture and tests does not establish the same result for every HTML structure, browser, operating system, or assistive technology.
Related surfaces
See the colgroup Topic for column-group structure, CSS, and measurements.
For a beginner-friendly explanation, see How to Use the tfoot Element in Yugien. The full table content model is covered by the table Topic; heading rows by thead; main data rows by tbody; row APIs by tr; and the summary cell's heading relationship by th.