The <caption> Element
Technical Summary
When its parent is a table, caption represents that table's title. Conforming HTML places it as the table's first child element and uses it to give concise context about the table's purpose or data.
HTML-AAM maps caption to the caption role and defines its labeling relation to the parent table. Caption text does not always become the table name: aria-label / aria-labelledby take precedence, and a caption hidden from the accessibility tree does not name its parent.
Definition / Content model
| Item | Specification | Condition / scope |
|---|---|---|
| Meaning | Represents the title of its parent when that parent is a table | Participates in the table model |
| Placement | First child element of table | Conforming markup has at most one caption per table; caption is optional in the table content model |
| Content model | Flow content | No descendant table elements |
| Content attributes | Global attributes | The obsolete align attribute is non-conforming; use CSS for position and alignment |
| DOM interface | HTMLTableCaptionElement | Inherits from HTMLElement; the obsolete align IDL attribute also remains defined |
A title helps readers understand what the table covers. When a table is the only content in a figure other than its figcaption, the HTML Standard advises omitting caption in favor of figcaption. This recommendation is scoped to that stated figure structure; it should not be generalized to figures containing other content.
Legacy HTML includes the caption align attribute and HTMLTableCaptionElement.align IDL attribute, but both are obsolete. New markup should use CSS caption-side and text-align.
Table association and DOM interface
caption is a child of its table, rather than text that is merely nearby. The table.caption getter returns the first caption child, or null when there is none. The setter sets a caption on the table. createCaption() creates one if needed, and deleteCaption() removes it.
const table = document.querySelector("table");
const caption = table.caption; // first caption, or null
const ensuredCaption = table.createCaption();
ensuredCaption.textContent = "Visitors by month";
table.deleteCaption();
A caption placed elsewhere, such as inside a tr, is not returned by that table's caption getter. DOM-setter repair and non-conforming markup with multiple captions are separate from ordinary conforming markup.
Rendered position and table model
HTML placement and visual placement are separate. CSS Tables defines caption-side to position the caption box above or below the table grid. Setting caption-side: bottom does not change the caption's position as the first child in the HTML or its DOM relationship with that table.
caption {
caption-side: bottom;
text-align: start;
}
Do not assume that visual order, DOM order, and assistive-technology speech order are always identical. Measure each surface separately.
Accessible role, relation, and table name
| Surface | Mapping | Condition / scope |
|---|---|---|
| Caption role | Maps to the WAI-ARIA caption role | Platform role values are then resolved through each API's WAI-ARIA mapping |
| Parent relation | Defines a label relation from caption to its parent table for platform APIs | IAccessible2, ATK, and AX use a label-for relation; UIA exposes the caption through the parent table's LabeledBy property |
| Table accessible name | After computing aria-label / aria-labelledby, uses the text subtree of the first caption child | If the name is still empty, falls back to the title attribute. A caption hidden from the accessibility tree does not provide the name |
An accessible name identifies the table to assistive technology. The visible caption is often the source, but an author-provided ARIA name has priority. HTML-AAM's mapping does not by itself specify exactly when or how a screen reader announces that name on table entry.
Fact / Evidence
Track the HTML definition, accessibility mapping, and CSS position as separate claims. Browser observations, WPT, and assistive-technology results are recorded under Implementation Evidence.
| Type | Fact | Condition / scope | Status | Evidence |
|---|---|---|---|---|
| SPEC | caption represents the title of its parent when the parent is a table | Parent relationship and participation in the table model | Reviewed | HTML Standard: the caption element |
| SPEC | Caption is the first table child element, has flow content, and cannot contain descendant tables | HTML conformance and content model; a table has an optional single caption | Reviewed | HTML Standard: the caption element |
| SPEC | Caption role and the label relation to the parent table are defined by platform mappings | WAI-ARIA role mapping and per-platform API mapping | Reviewed | HTML-AAM: caption |
| SPEC | Table accessible-name computation checks author-provided ARIA naming, then the first caption, then the title attribute | Accessible-name computation steps and the condition that caption remains in the accessibility tree | Reviewed | HTML-AAM: table accessible name |
| SPEC | caption-side positions the caption box above or below the table grid | CSS Table Module Level 3 top / bottom values; visual positioning | Reviewed | CSS Tables: caption-side |
| SPEC | The caption align content attribute and HTMLTableCaptionElement.align are obsolete | Use CSS for new markup | Reviewed | HTML Standard: obsolete features |
Evidence
- HTML Standard: The
captionelement — meaning, context, content model, HTMLTableCaptionElement - HTML Standard: The
tableelement — table content model and DOM API including caption - HTML Accessibility API Mappings:
caption— caption role and platform relations to the table - HTML-AAM:
tableaccessible name — ARIA, caption, and title order; hidden-caption condition - CSS Table Module Level 3:
caption-side— visual caption placement - HTML Standard: Obsolete features — obsolete
caption aligncontent and IDL attributes - WPT:
caption_001.html— caption getter / setter, null, and child relationship - W3C WAI: H39 — associating a table caption using the caption element
Implementation Evidence
These are observations from the selected fixture, WPTs, Chrome, and NVDA. They do not establish conformance or identical output in other environments. AAM platform mappings, the browser accessibility tree, Windows UI Automation, and NVDA speech output are recorded as separate surfaces.
| Type | Scope observed | Conditions recorded | Status |
|---|---|---|---|
| IMPL | HTMLTableCaptionElement, DOM order, table.caption, createCaption() / deleteCaption(), and rendered caption-side position |
2026-10-05 / Windows / Codex In-app Browser, Chrome UA 154.0.0.0, viewport 1536×695, navigator.language=en-US. Seven of seven checks passed in build-config/atlas/research-results/caption-v1/ at loopback 127.0.0.1:4210: IDL type, first-child order, getter, create/delete, getter exclusion for a caption inside a row, and computed caption-side: bottom rendered below the table. Windows build and DPR were not recorded. |
Partial observation (Chrome 154 / fixture 7/7) |
| WPT | Selected WPTs for the caption element DOM API and CSS caption-side |
2026-10-05 / Codex In-app Browser, Chrome UA 154.0.0.0 / wpt.live. caption_001.html: Harness OK, 5/5 passed. caption-side-1.html: Harness OK, 2/2 passed. Total for selected cases: 7/7 passed. The upstream revision served by wpt.live was not pinned. Duplicate captions in the CSS layout test are invalid markup used by that test and do not count as an HTML conformance check.The test version used was not recorded. The linked test may change, so this result cannot be repeated with certainty against the same version. |
Partial run (selected WPTs: 7/7 passed) |
| AAM | Table role and caption-derived table name in Chrome Browser Accessibility Tree; headings and key links in the four new pages | 2026-10-05 / Codex In-app Browser, Chrome UA 154.0.0.0. In the caption fixture's Browser AX snapshot, the caption text was exposed as the table name; explicit aria-label precedence, an unnamed table with a hidden caption, and the title fallback were observed. Headings, the captioned example table, language switch, and related links were checked on all four JA/EN pages. This snapshot did not establish a separate caption platform role or relation. Windows UIA and NVDA speech remain unmeasured. NVDA launch did not produce a targetable window; subsequent UI inspection stopped because Computer Use could not determine the current browser URL with sufficient confidence, so no screen-reader output was captured. |
Partial observation (Chrome Browser AX / UIA and NVDA unmeasured) |
Only selected WPT cases are run. Browser accessibility-tree and Windows UI Automation values are not a cross-platform AAM conformance verdict. NVDA speech is recorded only for combinations where its actual output was captured.
Coverage / Open Issues
- ReviewedHTML meaning, first-child condition, content model, DOM API, CSS caption-side, HTML-AAM role and table-name computation
- OpenHTML parsing and DOM-setter behavior in all browsers, invalid markup with multiple captions, and caption descendants in the table model
- OpenWPTs beyond the selected cases, other browsers, macOS AX / Linux ATK, and all Windows UIA properties
- OpenNVDA reading order, table navigation, JA / EN voice variation, other assistive technologies, and Expert-gap Review
This is initial coverage. The observations recorded here do not generalize to every table structure, browser, platform API, or assistive technology.
Related surfaces
For a beginner-friendly example and placement guidance, see the caption element page in Yugien. The table grid and parser recovery are covered by the table Topic; header and data-cell relationships are covered by the th Topic and td Topic.