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

Rows, columns, and cells

The Row, Column, and Cell children of a table — track sizes, the col:row cell address, merged cells via RowSpan and ColumnSpan, per-cell insets and strokes, and the text inside a cell.

Pro· reference

A <Table> carries three kinds of children — <Row>, <Column>, and <Cell> — that fill in the grid its counts declared.

In short: The <Row> and <Column> children size a table's tracks: a <Column> carries a width, a <Row> carries height constraints, and each is named by its zero-based index. The <Cell> children hold the content and most of the formatting — each cell names its grid position with Name="col:row", can span rows or columns to merge, and holds its own paragraphs of text padded in by its insets. This page is the attribute reference for those three children.

A <Table> carries three kinds of children that fill in the grid its counts declared: one <Row> per row, one <Column> per column, and one <Cell> per occupied grid position. The rows and columns size the tracks; the cells hold the content and most of the formatting.

The example below is a three-row, two-column table — a one-row header over two body rows — with each cell holding a one-word paragraph. It is the structure the rest of this page references.

A table inside a story: HeaderRowCount and BodyRowCount set the grid, Row and Column give the tracks, and each Cell holds its own paragraph.

Stories/Story_ustory.xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<idPkg:Story xmlns:idPkg="http://ns.adobe.com/AdobeInDesign/idml/1.0/packaging" DOMVersion="20.0">
  <Story Self="ustory">
    <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]"
               TopBorderStrokeColor="Color/Black" TopBorderStrokeWeight="1"
               BottomBorderStrokeColor="Color/Black" BottomBorderStrokeWeight="1"
               LeftBorderStrokeColor="Color/Black" LeftBorderStrokeWeight="1"
               RightBorderStrokeColor="Color/Black" RightBorderStrokeWeight="1">
          <Row Self="urow0" Name="0" SingleRowHeight="24"/>
          <Row Self="urow1" Name="1" SingleRowHeight="24"/>
          <Row Self="urow2" Name="2" SingleRowHeight="24"/>
          <Column Self="ucol0" Name="0" SingleColumnWidth="120"/>
          <Column Self="ucol1" Name="1" SingleColumnWidth="120"/>
          <Cell Self="ucell00" Name="0:0" RowSpan="1" ColumnSpan="1"
                TextTopInset="2" TextLeftInset="3" TextBottomInset="2" TextRightInset="3"
                AppliedCellStyle="CellStyle/$ID/[None]" FillColor="Color/Black"
                BottomEdgeStrokeColor="Color/Black" BottomEdgeStrokeWeight="1"
                RightEdgeStrokeColor="Color/Black" RightEdgeStrokeWeight="1">
            <ParagraphStyleRange AppliedParagraphStyle="ParagraphStyle/$ID/[No paragraph style]">
              <CharacterStyleRange AppliedCharacterStyle="CharacterStyle/$ID/[No character style]">
                <Content>Item</Content>
              </CharacterStyleRange>
            </ParagraphStyleRange>
          </Cell>
          <Cell Self="ucell10" Name="1:0" RowSpan="1" ColumnSpan="1"
                TextTopInset="2" TextLeftInset="3" TextBottomInset="2" TextRightInset="3"
                AppliedCellStyle="CellStyle/$ID/[None]" FillColor="Color/Black"
                BottomEdgeStrokeColor="Color/Black" BottomEdgeStrokeWeight="1">
            <ParagraphStyleRange AppliedParagraphStyle="ParagraphStyle/$ID/[No paragraph style]">
              <CharacterStyleRange AppliedCharacterStyle="CharacterStyle/$ID/[No character style]">
                <Content>Qty</Content>
              </CharacterStyleRange>
            </ParagraphStyleRange>
          </Cell>
          <Cell Self="ucell01" Name="0:1" RowSpan="1" ColumnSpan="1"
                TextTopInset="2" TextLeftInset="3" TextBottomInset="2" TextRightInset="3"
                AppliedCellStyle="CellStyle/$ID/[None]"
                BottomEdgeStrokeColor="Color/Black" BottomEdgeStrokeWeight="1"
                RightEdgeStrokeColor="Color/Black" RightEdgeStrokeWeight="1">
            <ParagraphStyleRange AppliedParagraphStyle="ParagraphStyle/$ID/[No paragraph style]">
              <CharacterStyleRange AppliedCharacterStyle="CharacterStyle/$ID/[No character style]">
                <Content>Paper</Content>
              </CharacterStyleRange>
            </ParagraphStyleRange>
          </Cell>
          <Cell Self="ucell11" Name="1:1" RowSpan="1" ColumnSpan="1"
                TextTopInset="2" TextLeftInset="3" TextBottomInset="2" TextRightInset="3"
                AppliedCellStyle="CellStyle/$ID/[None]"
                BottomEdgeStrokeColor="Color/Black" BottomEdgeStrokeWeight="1">
            <ParagraphStyleRange AppliedParagraphStyle="ParagraphStyle/$ID/[No paragraph style]">
              <CharacterStyleRange AppliedCharacterStyle="CharacterStyle/$ID/[No character style]">
                <Content>12</Content>
              </CharacterStyleRange>
            </ParagraphStyleRange>
          </Cell>
          <Cell Self="ucell02" Name="0:2" RowSpan="1" ColumnSpan="1"
                TextTopInset="2" TextLeftInset="3" TextBottomInset="2" TextRightInset="3"
                AppliedCellStyle="CellStyle/$ID/[None]"
                RightEdgeStrokeColor="Color/Black" RightEdgeStrokeWeight="1">
            <ParagraphStyleRange AppliedParagraphStyle="ParagraphStyle/$ID/[No paragraph style]">
              <CharacterStyleRange AppliedCharacterStyle="CharacterStyle/$ID/[No character style]">
                <Content>Toner</Content>
              </CharacterStyleRange>
            </ParagraphStyleRange>
          </Cell>
          <Cell Self="ucell12" Name="1:2" RowSpan="1" ColumnSpan="1"
                TextTopInset="2" TextLeftInset="3" TextBottomInset="2" TextRightInset="3"
                AppliedCellStyle="CellStyle/$ID/[None]">
            <ParagraphStyleRange AppliedParagraphStyle="ParagraphStyle/$ID/[No paragraph style]">
              <CharacterStyleRange AppliedCharacterStyle="CharacterStyle/$ID/[No character style]">
                <Content>4</Content>
              </CharacterStyleRange>
            </ParagraphStyleRange>
          </Cell>
        </Table>
      </CharacterStyleRange>
    </ParagraphStyleRange>
  </Story>
</idPkg:Story>

A note on the validator counts: the renderer reports this package as one paragraph and zero runs. That single paragraph is the host paragraph the <Table> rides on — its run is consumed by the table, so it contributes no text run of its own. The six cell paragraphs are laid out inside the table's own grid pipeline and are not added to the story's paragraph and run totals.

Columns size the horizontal tracks

A <Column> is an empty element: it has no content, only a width. Columns appear in left-to-right order, and each one's Name is its zero-based index.

Attribute · ColumnType / valuesSupportNotes
Selfstring idSupportedThe column id.
Namestring (zero-based index)SupportedThe column index as a string: "0" for the first column, "1" for the next, and so on. This is the column half of a cell’s col:row address.
SingleColumnWidthdouble (pt)SupportedThe column’s width in points. A column with no width contributes 0 to the table’s total width.

Rows size the vertical tracks

A <Row> is likewise empty — it carries the row's height constraints. Rows appear top-to-bottom, header rows first, then body, then footer, matching the <Table> counts. Each row's Name is its zero-based index across the whole table.

Attribute · RowType / valuesSupportNotes
Selfstring idSupportedThe row id.
Namestring (zero-based index)SupportedThe row index as a string, counting from 0 at the top across all regions. This is the row half of a cell’s col:row address.
SingleRowHeightdouble (pt)SupportedThe row’s nominal height in points. The renderer grows a row past this when its cell content needs more space (and a MaximumHeight is not in the way).
MinimumHeightdouble (pt)SupportedA floor the row will not shrink below. The effective height is the larger of SingleRowHeight and MinimumHeight, then grown to fit content.
MaximumHeightdouble (pt)SupportedA ceiling the row will not grow past. Absent means unbounded — IDML writes a large sentinel when there is no limit, which the parser treats as no limit.

AutoGrow, KeepWithNextRow, and StartRow are stored by IDML on a <Row> but are not read here; content-driven row growth is on by default, and the keep-together / forced-start behaviours are not yet honoured.

Not yet parsedAutoGrow, KeepWithNextRow, StartRow

Cells hold the content

A <Cell> is where the grid meets the text. Each cell names its position with Name="col:row" (both zero-based), so a cell at column 1 of row 0 is Name="1:0". Cells are serialised in column-major order — every cell in column 0 top-to-bottom, then column 1, and so on — but their Name is what places them, so the serialisation order does not matter to the result.

Position and span

Attribute · CellType / valuesSupportNotes
Selfstring idSupportedThe cell id.
Namestring ("col:row")SupportedThe cell’s grid address — column index, a colon, row index, both zero-based. This, not the document order, is what positions the cell.
RowSpanintSupportedHow many rows the cell occupies, starting at its row. Defaults to 1. Values above 1 merge cells vertically — see below.
ColumnSpanintSupportedHow many columns the cell occupies, starting at its column. Defaults to 1. Values above 1 merge cells horizontally.

Merged cells

A merged cell is just a cell with a span greater than 1. A cell with ColumnSpan="2" occupies its own column and the one to its right; a cell with RowSpan="3" occupies its row and the two below. The covered grid positions have no <Cell> element of their own — they are absorbed by the spanning cell. This is why the number of <Cell> elements is usually fewer than rows × columns: every merge removes the cells it swallows.

When a row-spanning cell needs more height than its rows provide, the renderer adds the shortfall to the last row of the span; the earlier rows keep their declared heights.

Insets and the cell's text

A cell's content is ordinary text: one or more <ParagraphStyleRange> children, exactly as in the body of a story. The cell's four insets pad that text in from the cell edges.

Attribute · CellType / valuesSupportNotes
TextTopInset / TextLeftInset / TextBottomInset / TextRightInsetdouble (pt)SupportedPadding between the cell edges and its text, per side, in points. Default 0. Read directly off the cell, not from the cell style.
AppliedCellStylestring (CellStyle id)Parsed, not yet renderedThe cell style the cell applies. The cell style’s fill and per-edge strokes are resolved as a fallback when the cell omits its own; insets and the cell’s starting paragraph style are not yet read from the style. See the note below.
FirstBaselineOffsetAscent | CapHeight | LeadingOffset | EmboxHeight | XHeight | FixedHeightParsed, not yet renderedWhere the first line of cell text drops from the cell’s top inset. Captured; the renderer uses Ascent semantics today.
MinimumFirstBaselineOffsetdouble (pt)Parsed, not yet renderedThe fixed baseline drop used when FirstBaselineOffset is FixedHeight. Parsed for completeness.

AppliedCellStyle resolution is partial: the renderer reads the resolved cell style's fill colour and per-edge strokes as fallbacks, but a cell style's own insets, starting paragraph style, and diagonals are not yet read — so cell padding comes from the TextInset attributes on the cell, not from its style. The detail of which style attributes are read is on table and cell styles.

Fill and per-edge strokes

A cell can paint its own background and its own four edge strokes. InDesign serialises an explicit stroke on every cell edge when a table-style divider applies, even when the cell's AppliedCellStyle is [None] — so honouring these per-cell edges is what makes ordinary gridlines appear. An inline value on the cell wins over whatever its cell style would contribute.

Attribute · CellType / valuesSupportNotes
FillColorstring (swatch id)SupportedThe cell’s background fill. A reference into Resources/Graphic.xml; wins over the resolved cell style’s fill.
TopEdgeStrokeColor / BottomEdgeStrokeColor / LeftEdgeStrokeColor / RightEdgeStrokeColorstring (swatch id)SupportedPer-edge stroke paint. Each drawn edge wins over the cell style’s same edge.
TopEdgeStrokeWeight / BottomEdgeStrokeWeight / LeftEdgeStrokeWeight / RightEdgeStrokeWeightdouble (pt)SupportedPer-edge stroke weight in points.
TopEdgeStrokeTint / … / RightEdgeStrokeTintdouble (0–100%)SupportedPer-edge stroke tint percentage.

Diagonal lines

A cell can draw one or both diagonal lines across itself. The parser reads InDesign's diagonal attributes; the renderer emits a stroke for each diagonal that is drawn.

Attribute · CellType / valuesSupportNotes
LeftLineDrawnbooleanSupportedDraws the diagonal that runs top-left to bottom-right.
RightLineDrawnbooleanSupportedDraws the diagonal that runs top-right to bottom-left.
LeftLineStrokeColor / RightLineStrokeColorstring (swatch id)SupportedPaint for each diagonal.
LeftLineStrokeWeight / RightLineStrokeWeightdouble (pt)SupportedWeight for each diagonal.
DiagonalLineInFrontbooleanSupportedWhen true, the diagonal paints on top of the cell content; otherwise behind it.

VerticalJustification (TopAlign, CenterAlign, BottomAlign, JustifyAlign) and RotationAngle are stored on a <Cell> but are not read here — cell content sits at the top of the cell and is not rotated.

Not yet parsedVerticalJustification, RotationAngle on Cell

Frequently asked questions

How does a <Cell> know which grid position it occupies? Each cell names its position with Name="col:row", both zero-based — so a cell at column 1 of row 0 is Name="1:0". Cells are serialised in column-major order, but the Name is what places them, so the document order does not affect the result.

How are merged cells represented? A merged cell is a cell with a RowSpan or ColumnSpan greater than 1. The grid positions it covers have no <Cell> element of their own — they are absorbed by the spanning cell — which is why a table usually has fewer <Cell> elements than rows × columns.

Where does a cell's text padding come from? From the four TextInset attributes (TextTopInset, TextLeftInset, TextBottomInset, TextRightInset) read directly off the <Cell>, defaulting to 0. A cell style's own insets are not yet read, so padding comes from the cell, not its AppliedCellStyle.

Why does the validator report the table example as one paragraph and zero runs? The single paragraph is the host paragraph the <Table> rides on; its run is consumed by the table, so it contributes no text run. The cell paragraphs are laid out inside the table's own grid pipeline and are not added to the story's paragraph and run totals.

On this page