Work in progress — this reference is being written in the open. Unfinished pages are excluded from search engines.
Paged · IDML Reference
Tables

The table model

The Table element and its attributes — the row and column counts that define the grid, the outer border strokes, and the alternating row and column divider rules.

Pro· reference

The <Table> element is the root of a table: it declares the grid's dimensions as counts and carries the table's own paint directly as attributes.

In short: A <Table> defines a grid with four counts — HeaderRowCount, BodyRowCount, FooterRowCount, and ColumnCount — and carries the table's own borders as attributes: the four outer-edge strokes and the alternating row and column dividers. Its <Row>, <Column>, and <Cell> children fill the grid in. A <Table> always lives inside a <CharacterStyleRange>, inside a <ParagraphStyleRange>, inside a story. This page is the attribute reference for the <Table> element itself.

The <Table> element is the root of a table. It declares the grid's dimensions as counts, and it carries the table's own paint — the four outer border strokes and the alternating row / column dividers — directly as attributes. Its <Row>, <Column>, and <Cell> children, covered on the next page, fill the grid in.

A <Table> always lives inside a <CharacterStyleRange>, which is inside a <ParagraphStyleRange>, which is inside a story — see tables in the text flow for what that nesting means.

<ParagraphStyleRange AppliedParagraphStyle="ParagraphStyle/$ID/[No paragraph style]">
  <CharacterStyleRange AppliedCharacterStyle="CharacterStyle/$ID/[No character style]">
    <Table Self="utable" HeaderRowCount="1" FooterRowCount="0" BodyRowCount="2"
           ColumnCount="2" AppliedTableStyle="TableStyle/$ID/[Basic Table]">
      <Row .../> <Column .../> <Cell ...>…</Cell>
    </Table>
  </CharacterStyleRange>
</ParagraphStyleRange>

Shape: the row and column counts

These four counts define the grid. The total number of rows is HeaderRowCount + BodyRowCount + FooterRowCount; the renderer expects exactly that many <Row> children and ColumnCount <Column> children. The counts also tell the renderer which rows belong to which region — header rows are the first HeaderRowCount, footer rows are the last FooterRowCount, and the body is everything between. Region membership drives both repetition (see tables in the text flow) and which cell-style region a cell falls into.

Attribute · TableType / valuesSupportNotes
Selfstring idSupportedThe table id, e.g. "utable". Informational at the structural level; cells address the grid by Name, not by this id.
HeaderRowCountint (0–25)SupportedHow many leading rows form the header region. 0 means no header. Defaults to 0 when absent.
FooterRowCountint (0–25)SupportedHow many trailing rows form the footer region. 0 means no footer. Defaults to 0 when absent.
BodyRowCountintSupportedHow many rows form the body region (everything that is neither header nor footer). Defaults to 0 when absent.
ColumnCountintSupportedHow many columns the table has; should match the number of <Column> children. Defaults to 0 when absent.
AppliedTableStylestring (TableStyle id)Parsed, not yet renderedThe table style the table applies. Recorded and resolved for region cell-style lookup, but the table’s own geometry comes from the cell elements directly rather than from the style. See the note below.

AppliedTableStyle resolves the table style's region cell-style references (so a cell with no AppliedCellStyle of its own can inherit the header / body / footer region default), but the table's measured layout — insets, row heights, the actual strokes drawn — is read from the row, column, and cell elements rather than synthesised from the style. The style page, table and cell styles, describes which parts of that cascade are read today.

When a table breaks across a chain of threaded frames, its header rows can repeat at the top of each continuation frame and its footer rows at the bottom of each frame but the last. Two booleans on the <Table> control whether they do.

Attribute · TableType / valuesSupportNotes
RepeatingHeaderbooleanSupportedWhether the header rows duplicate at the top of every continuation frame. Absent means true (repeat); an explicit false suppresses the repeat. Only meaningful when HeaderRowCount > 0.
RepeatingFooterbooleanSupportedWhether the footer rows duplicate at the bottom of every frame except the last. Absent means true; an explicit false suppresses it. Only meaningful when FooterRowCount > 0.

The repetition itself is described, with its current limits, in tables in the text flow.

The outer border

InDesign serialises the table's four outer-edge strokes directly on the <Table> element when the user customises the border without going through a table style. Each edge has its own colour, weight, type, and tint. These take precedence over any border the AppliedTableStyle would contribute. A colour of Swatch/None means no stroke on that edge.

Attribute · TableType / valuesSupportNotes
TopBorderStrokeColor / BottomBorderStrokeColor / LeftBorderStrokeColor / RightBorderStrokeColorstring (swatch id)SupportedPer-edge outer-border paint. A reference into Resources/Graphic.xml.
TopBorderStrokeWeight / BottomBorderStrokeWeight / LeftBorderStrokeWeight / RightBorderStrokeWeightdouble (pt)SupportedPer-edge outer-border weight in points.
TopBorderStrokeType / … / RightBorderStrokeTypestring (stroke-style id)Parsed, not yet renderedPer-edge stroke style (solid, dashed, …). Captured; the renderer draws a solid stroke today.
TopBorderStrokeTint / … / RightBorderStrokeTintdouble (0–100%)SupportedPer-edge border tint percentage.
TopBorderStrokeGapColor / GapTint (per edge)swatch id / doubleNot yet parsedGap colour for dashed / striped border styles. Read past, not acted on.

Row and column dividers

Between the outer border, the lines that separate one row from the next (and one column from the next) are described by two families of alternating attributes: a "start" set that paints the first run of dividers and an "end" set that paints the next run, cycling across the table. They live directly on the <Table>.

Attribute · TableType / valuesSupportNotes
StartRowStrokeCount / EndRowStrokeCountintSupportedHow many consecutive row dividers take the "start" paint, then the "end" paint, alternating down the table.
StartRowStrokeColor / EndRowStrokeColorstring (swatch id)SupportedRow-divider paint for each phase of the alternation.
StartRowStrokeWeight / EndRowStrokeWeightdouble (pt)SupportedRow-divider weight for each phase.
StartRowStrokeTint / EndRowStrokeTintdouble (0–100%)SupportedRow-divider tint for each phase.
StartRowStrokeType / EndRowStrokeTypestring (stroke-style id)Parsed, not yet renderedRow-divider stroke style; captured, drawn solid today.
StartColumnStrokeCount / Color / Weight / Tint / Type (and End* equivalents)mixedParsed, not yet renderedThe column-divider analogue of the row-stroke family. Parsed into the same structure; column-divider drawing is not yet emitted.

In practice, when a divider style comes from a table style, InDesign also serialises the resulting stroke on each <Cell>'s matching edge. The renderer draws those per-cell edge strokes (covered on the next page), which is what makes ordinary gridlines appear even when the table-level divider attributes are left at their defaults.

The StrokeOrder attribute — which stroke wins where a row divider crosses a column divider — and the skip-first / skip-last alternating counts are stored by IDML on the <Table> but are not read here.

Not yet parsedStrokeOrder, skip-alternating counts

Frequently asked questions

How does a <Table> define how many rows and columns it has? The total number of rows is HeaderRowCount + BodyRowCount + FooterRowCount, and the column count is ColumnCount. The renderer expects exactly that many <Row> children and ColumnCount <Column> children; each count defaults to 0 when the attribute is absent.

Does the renderer get a table's geometry from AppliedTableStyle? No. AppliedTableStyle is recorded and resolved only for region cell-style lookup — so a cell with no AppliedCellStyle can inherit a header, body, or footer default. The table's measured layout — insets, row heights, and the strokes actually drawn — is read from the row, column, and cell elements directly.

Why do gridlines still appear when the table-level divider attributes are left at their defaults? When a divider style comes from a table style, InDesign also serialises the resulting stroke on each <Cell>'s matching edge. The renderer draws those per-cell edge strokes, so ordinary gridlines appear even without any explicit table-level divider attributes.

Are dashed or striped table borders drawn as authored? Not yet. The per-edge StrokeType attributes are captured but the renderer draws a solid stroke today, and the dashed-style gap colours (StrokeGapColor / GapTint) are read past but not acted on.

On this page