Support matrix
What the five published targets do with a declaration, in one place, so you don’t hold five contracts in your head at once. The cells come from the engine’s specification at the version these docs describe.
This page isn’t normative. Each target’s own page states its contract, and this one indexes them without overriding any. Where a cell and a target page disagree, the target page is right.
A cell names the fate of the declaration and then says what it comes to. A fate is one of resolved, approximated, withdrawn, unread, and not applicable for a target with no such concept to answer with. A cell marked (best-effort) describes what that target does today and may change without a breaking change. Everything else is that target’s contract. Rows about an engine or target behaviour rather than a declaration carry plain prose.
Every published target also ships these fates as data. Its capabilities
descriptor exports { target, declarations }, keyed by the schema name an
author writes, so a host can ask before it renders rather than reading this
page. That’s what makes a document’s required marking checkable — see
Validating definitions.
True in every target
- A hidden cell keeps its slot, rendering an empty
<td>, an empty styled cell, or an empty field. - Grouping is the walk order everywhere. No target reorders bands.
- The report default is the outermost layer of the style stack.
- An image item’s target-blind semantics: a nullish
sourceskips it, invalid bytes throw, a hidden one emits nothing. - The marking’s wording is the engine’s. A target owns only where it goes.
- Definition problems throw synchronously from
render. Render errors reject located.
Page and pagination
| Declaration or behaviour | html |
pdf |
xlsx |
csv |
docx |
Stated in |
|---|---|---|---|---|---|---|
page.header / page.footer content |
unread — the closures are never called | resolved — drawn on every page, height reserved | resolved — the worksheet’s print header and footer. Text items only, in the section align names, with bold and size as their look |
unread — the closures are never called | resolved — a section header and footer. This target reads each band at page 1 and again at page 2 of 2. A first-page part rides only where the two differ | Page bands |
| A render error inside a page band | never raised — the band isn’t evaluated | raised, located, at render — the target reads each band at the probe | raised, located, at render — the target reads each band at page 1 and page 2 of 2 | never raised | raised, located, at render — this target calls the closures | Page bands |
break |
approximated — q-break and q-break-after classes, inert without host print CSS |
resolved — the four positions | resolved — a worksheet per boundary | withdrawn — no page to break | resolved — a page break on the instance’s first paragraph, or on the one after its last | Group definition |
reset: "page" |
withdrawn — no numbering to restart | resolved — restarts the numbering | withdrawn — writes no page numbers | withdrawn — no page to break | resolved — a nextPage section with pgNumType at 1 |
Group definition |
columns (page columns) |
resolved — a CSS multicol container. Balancing and gutter are the browser’s (best-effort) | resolved — strips of the page. Gutter and balancing are (best-effort) | withdrawn — no page to strip | withdrawn — no strips here | resolved — section cols, equal width, and approximated past three in Google Docs |
Page columns |
page.margin |
resolved — an @page margin rule |
resolved — the four sides of the page box | resolved — written as print setup. Declaring it here and in xlsx({ page }) is a render error |
withdrawn — a record has no page | resolved — pgMar, all four sides |
PDF › Options |
page.size |
resolved — the @page size |
resolved — the paper for every page | resolved — the print paper code | withdrawn — a record has no page | resolved — pgSz |
PDF › Options |
page.orientation |
resolved — the @page size’s turn |
resolved — the paper turned | resolved — the print orientation | withdrawn — a record has no page | resolved — pgSz turned, with w:orient |
PDF › Options |
Report-header height |
withdrawn — a CSS height pins the body box, not the page top | resolved — pins a box from the page top | withdrawn — no page top to pin from | withdrawn — no page top to pin from | withdrawn — no portable way to pin a box from the page top | PDF › Options |
Structure
| Declaration or behaviour | html |
pdf |
xlsx |
csv |
docx |
Stated in |
|---|---|---|---|---|---|---|
| The group tree | resolved — nested q-group containers carrying the group name |
resolved — outline entries nested by depth, and a half-line gap | resolved — that order, and row outline levels nested by depth, so a reader collapses an instance. Boundaries add no rows | resolved — that order alone | resolved — Heading<n> from this target’s own styles.xml, so no theme typography leaks |
Group definition |
A group’s label |
withdrawn — a fragment has no navigation of its own | resolved — the outline entry’s title | resolved — the worksheet name where a boundary opens one | withdrawn — a record carries no navigation | approximated — the navigation pane is the headings, so it reads the header’s text | Group definition |
A group’s collapsed |
resolved — the two bands alone, without the content between them | resolved — the same | resolved — the rows hidden and the group shut, so a reader opens it again | withdrawn — a record has only an order, so dropping rows would change the data | resolved — the two bands alone, without the content between them | Group definition |
Column width |
approximated — a <col> width a browser may widen past |
resolved — the share exactly, with width-less columns measured from content | withdrawn — no table for a share to be a share of. Content sizes the column instead | withdrawn — a record has no width | approximated — declared shares exact in a fixed tblGrid. Width-less columns divide the remainder evenly |
XLSX › Sizing the columns |
Slot width |
resolved — a percentage on the slot, width-less slots flexing | resolved — the share exactly, with the rest divided evenly | withdrawn — the same ground as column widths | withdrawn — a record has no width | resolved — a fixed table with no borders, shares exact | Split item |
span |
resolved — a colspan on the cell |
resolved — one box drawn across the columns | resolved — merged in header and total rows, never over data | resolved — the first field carries it, the rest empty | resolved — gridSpan |
Span |
| Keeping table headers in view | the reference sheet’s thead rule, under print fragmentation |
the header row repeats after every page break and at a new strip | a freeze pane at the first table’s header row | not applicable — a file has no view | resolved — tblHeader repeats the row after every page break |
XLSX › Freeze |
Style
| Declaration or behaviour | html |
pdf |
xlsx |
csv |
docx |
Stated in |
|---|---|---|---|---|---|---|
uppercase |
resolved — text-transform, which the browser applies locale-sensitively |
resolved — capitalised before measuring, Unicode default case mapping | withdrawn — capitalising the cell would turn presentation into data | withdrawn — a record carries no style | resolved — capitalised before writing, Unicode default case mapping | Style declarations |
| Padding and the box | resolved — sides inline, box-sizing: border-box |
resolved — insets wrap width. A sliced item keeps the sides it owns | borders approximated (solid → thin) and padding withdrawn |
withdrawn — a record carries no style | resolved per cell (tcMar, tcBorders, shd). Approximated on an item — pBdr and shading, padding as the border space |
Style declarations |
spaceBefore / spaceAfter |
resolved — margins that add rather than collapse | resolved — the cursor skips except at a fresh page or strip top | withdrawn — a grid has no flow | withdrawn — a record carries no style | resolved — paragraph spacing before/after | Style declarations |
format |
resolved — stringified at the markup edge through format() |
resolved — the same, from the instance locale | resolved — a number format, and the cell stays typed | withdrawn — the field carries the typed value instead | resolved — stringified at the markup edge through format() |
Style declarations |
href |
resolved — an <a> around the run’s span |
resolved — a link annotation over the run’s rectangles | approximated — a cell hyperlink where the whole cell points at one place | withdrawn — a record carries no style | resolved — a hyperlink, to a URL or to the bookmark a label wrote |
Style declarations |
| What the target supplies where the author declared nothing | nothing — every visual default is the host stylesheet’s | report header bold 1.4×, group header bold, 10 pt base, cell padding | report header bold 1.4×, group header bold, 10 pt base | nothing — a record has no presentation | report header bold 1.4×, group header bold, 10 pt base, 6 pt / 2 pt cell padding, a half-line gap before an instance | HTML › Styles |
A family name that’s not a generic |
resolved — quoted as the family, or the host’s fonts mapping |
approximated — falls back to sans unless the host embeds the face |
resolved — passed through for the reader’s application | withdrawn — a record carries no style | resolved — named on the run for the reader to substitute, never embedded | Style declarations |
valign |
resolved — vertical-align, a row’s reaching its cells |
resolved — the lines placed in the slack a row or slot leaves | resolved — undeclared writes nothing, so the application’s own default stands | withdrawn — a record carries no style | resolved — vAlign on the cell |
Style declarations |
| What the host supplies | the stylesheet — every visual default — and what a family name means |
the TrueType faces through fonts — and which scripts come out right is the parser’s, not quario’s |
the reader’s application, which resolves an unmapped family name |
nothing | nothing — no fonts option, no stylesheet | PDF › Text |
Text and values
| Declaration or behaviour | html |
pdf |
xlsx |
csv |
docx |
Stated in |
|---|---|---|---|---|---|---|
| A cell that’s one bare interpolation | display text — a Date as ISO 8601 UTC |
display text — a Date as ISO 8601 UTC |
a native number, boolean, or date cell | the typed value as text — a Date as ISO 8601 UTC |
display text — a Date as ISO 8601 UTC |
Event stream |
| Literal markup in template text | literal text — escaped at the markup edge | literal text | literal text | literal text | literal text | String syntaxes |
| A cell of more than one styled run | resolved — one <span> per run, carrying that run’s whole style |
resolved — face, size, and colour per run. The line takes the largest | resolved — worksheet rich text, and a run’s background is inert |
withdrawn — runs flatten to their joined text | resolved — one <w:r> per run, its own shading included |
XLSX › Styled runs |
| Characters outside WinAnsi | intact | ? on the base-14 faces. An embedded face draws them by its own cmap |
intact | intact | intact — the parts are UTF-8 XML | PDF › Text |
| A newline inside a cell | a break, through the reference sheet’s pre-line rule |
a hard line break, with wrapping still applied within each line | wrapText, so the break shows in the grid |
a quoted field whose record spans lines | a <w:br/>, a hard line break |
HTML › Classes and the stylesheet |
Cell text beginning with = |
plain text | plain text | an inert string — never a formula, and never mangled | apostrophe-prefixed: the author’s text changes | plain text | CSV › Injection guard |
Output
| Declaration or behaviour | html |
pdf |
xlsx |
csv |
docx |
Stated in |
|---|---|---|---|---|---|---|
| An image item | an <img> holding a data: URI — needs img-src data: |
drawn at the size fit dictates, never split across a page, an SVG as vector paths |
a floating drawing anchored to one row — wholly best-effort, and an SVG throws | no record of its own, and an empty field in a slot | inline (wp:inline) at the size fit dictates, capped at the text column, never floating, and an SVG throws |
Image item |
Image alt |
resolved — the alt attribute, escaped |
withdrawn — no tagged structure to carry it | withdrawn — a floating drawing carries none | withdrawn — a record carries none | resolved — docPr descr |
Image item |
| The unlicensed marking | a badge element before the report root | a diagonal line on every page. Its geometry is (best-effort) | a row-1 banner and the workbook description | one trailing line — weaker than the other three | the first paragraph of every footer part, before any authored content | License keys |
| Determinism | an identical fragment | byte-identical output | byte-identical output | an identical string | identical bytes on every supported runtime, while the writer is fflate | PDF › Determinism |