Skip to content

HTML tag reference

This is the supported letter HTML vocabulary. Every tag below has a placement rule and example. The reference build compares this catalogue against the implementation’s region/block/inline/layout vocabulary, preventing unnoticed additions/removals.

Use a single letter root with a required main body. Do not add browser html, head or body wrappers. Unsupported tags, attributes, styles and HTML recovery fail with a source location. Comments and structural indentation are allowed; explicit text belongs in appropriate text blocks.

Use paired closing tags for custom empty elements: page-break, component, page-number and page-count. Standard img, br and param are void tags. Escape literal markup as </&; template values are literal text and cannot create markup.

style selects supported inline CSS. style-name names a document-local theme style. They are allowed only where the tag supports styling: logo has no wrapper appearance; watermark forbids named styles and has special appearance rules; if, else, param and page-break have stricter attribute restrictions.

data-if selects an element using a Boolean map path. data-each repeats supported blocks/rows using a List path, with required data-as alias. These attributes are processed only in template mode, before normal tag validation. They are not arbitrary expressions; see the directive reference.

<letter>

Placement
Exactly one root
Defaults
A4 portrait; 20 mm margins; 25 mm header; 15 mm footer; en-GB, LONG dates, UTC; no selected currency.

Use letter markup without html/head/body wrappers. Root typography is inherited by content; use Java for independent per-side margins. Custom paper dimensions are a pair. Positive-size paper must accommodate margins/zones.

AttributeAccepted input / meaning
pagea4 or letter; case-insensitive
orientationportrait or landscape
page-width-mmPositive custom paper width; requires page-height-mm
page-height-mmPositive custom paper height; requires page-width-mm
margins-mmFinite uniform physical page margin, in mm
header-height-mmReserved header height in mm
footer-height-mmReserved footer height in mm
language-tagBCP 47 language/country identifier
date-patternJava DateTimeFormatter pattern
date-styleFULL, LONG, MEDIUM or SHORT
currencyISO 4217 currency code
zone-idJava ZoneId name; affects temporal formatting
<letter page="a4" margins-mm="20"><main><p>Hello</p></main></letter>

<main>

Placement
Required direct child of letter
Defaults
One required region; body blocks keep source order.

Only the body flow permits explicit page-break blocks. A selected template must contain renderable body content.

<main><p>Body text</p></main>

<header>

Placement
Direct child of letter; unique per page selector
Defaults
All pages; automatic left-aligned placement; height derives from header-height-mm.

Exact placement requires x-mm, y-mm, width-mm and height-mm together. Text alignment can be overridden on child blocks. Put paragraph margins on child p/div blocks. FIRST/FOLLOWING variants override ALL on matching pages.

AttributeAccepted input / meaning
pagesall, first or following
alignleft, center or right; controls box placement and initial text alignment
width-mmPositive header width in mm
height-mmPositive header height in mm
x-mmExact x relative to inner page; requires all four bounds
y-mmExact y relative to inner page; requires all four bounds
<header pages="first" align="right"><p>Company address</p></header>
Placement
Direct child of letter; unique per page selector
Defaults
All pages; fitting height uses footer-height-mm.

Supported rich blocks and images; no page breaks. Reserve sufficient height on letter. Put text spacing on child blocks.

AttributeAccepted input / meaning
pagesall, first or following
<footer pages="all"><p>Page <page-number></page-number> of <page-count></page-count></p></footer>
Placement
Direct child of letter
Defaults
Image fitting box 45 × 20 mm.

Exactly one img child. Apply dimensions/styles to img, not to the logo wrapper. Named image assets only.

<logo><img src="asset:logo" width="40mm" alt="Example Company"></logo>

<signature>

Placement
Direct child of letter
Defaults
flow; 20 mm.

Styled text/images/blocks; no page breaks. bottom-last places the signature on the final generated letter page above the footer. This is a visible signature, not cryptographic signing.

AttributeAccepted input / meaning
placementflow or bottom-last (bottom_last also accepted)
height-mmFinite positive signature reservation, in mm
<signature placement="bottom-last" height-mm="20"><p>Customer Services</p></signature>

<watermark>

Placement
Direct child of letter
Defaults
All pages; opacity 0.12; text 45° / image 0°; image fitting box 80 × 40 mm.

Either plain text or exactly one img child. Text uses independent watermark font/color/size defaults and permits only regular undecorated text. No named style. Image styles belong on img. Standard PDF profile only; does not reserve body space.

AttributeAccepted input / meaning
opacityFinite number from 0 through 1
rotationFinite rotation in degrees, about page center
pagesall, first or following
<watermark opacity="0.12" rotation="45">DEMONSTRATION</watermark>

<sender>

Placement
Direct child of letter
Defaults
Optional semantic regions; role defaults/theme apply.

Rich block content. Fluent/HTML semantic parts assemble in conventional letter order rather than arbitrary root tag order. Each role is unique.

<sender><p>Example content</p></sender>

<recipient>

Placement
Direct child of letter
Defaults
Optional semantic regions; role defaults/theme apply.

Rich block content. Fluent/HTML semantic parts assemble in conventional letter order rather than arbitrary root tag order. Each role is unique.

<recipient><p>Example content</p></recipient>

<subject>

Placement
Direct child of letter
Defaults
Optional semantic regions; role defaults/theme apply.

Rich block content. Fluent/HTML semantic parts assemble in conventional letter order rather than arbitrary root tag order. Each role is unique.

<subject><p>Example content</p></subject>

<salutation>

Placement
Direct child of letter
Defaults
Optional semantic regions; role defaults/theme apply.

Rich block content. Fluent/HTML semantic parts assemble in conventional letter order rather than arbitrary root tag order. Each role is unique.

<salutation><p>Example content</p></salutation>

<closing>

Placement
Direct child of letter
Defaults
Optional semantic regions; role defaults/theme apply.

Rich block content. Fluent/HTML semantic parts assemble in conventional letter order rather than arbitrary root tag order. Each role is unique.

<closing><p>Example content</p></closing>

<date>

Placement
Direct child of letter
Defaults
Final document locale/date pattern formats a value attribute.

Choose value with no child content, or authored rich date content without value. Supports semantic DATE theme styling.

AttributeAccepted input / meaning
valueISO LocalDate, such as 2026-10-20
<date value="2026-10-20"></date>

<reference>

Placement
Direct child of letter
Defaults
Semantic REFERENCE role.

Authored rich content follows the configured label.

AttributeAccepted input / meaning
labelRequired nonblank reference label
<reference label="Account"><p>DEMO-000001</p></reference>

<p>

Placement
Inside a region, rich cell, group or supported container
Defaults
Inherited body typography; ordinary paragraph flow.

Inline text and formatting. Source whitespace is normalized by markup parsing; use br for explicit lines. Images are separate blocks.

<p>Hello <strong>${name}</strong>.<br>Second line.</p>

<h1>

Placement
Block content inside supported regions/containers
Defaults
Bold; semantic sizes h1=18, h2=16, h3=14, h4=12, h5=11, h6=10 pt, below named/explicit overrides; keep with next.

Inline formatted heading text. Current tagged-PDF model emits H1 for every heading level; HTML level does not establish a complete PDF heading hierarchy.

<h1>Account update</h1>

<h2>

Placement
Block content inside supported regions/containers
Defaults
Bold; semantic sizes h1=18, h2=16, h3=14, h4=12, h5=11, h6=10 pt, below named/explicit overrides; keep with next.

Inline formatted heading text. Current tagged-PDF model emits H1 for every heading level; HTML level does not establish a complete PDF heading hierarchy.

<h2>Account update</h2>

<h3>

Placement
Block content inside supported regions/containers
Defaults
Bold; semantic sizes h1=18, h2=16, h3=14, h4=12, h5=11, h6=10 pt, below named/explicit overrides; keep with next.

Inline formatted heading text. Current tagged-PDF model emits H1 for every heading level; HTML level does not establish a complete PDF heading hierarchy.

<h3>Account update</h3>

<h4>

Placement
Block content inside supported regions/containers
Defaults
Bold; semantic sizes h1=18, h2=16, h3=14, h4=12, h5=11, h6=10 pt, below named/explicit overrides; keep with next.

Inline formatted heading text. Current tagged-PDF model emits H1 for every heading level; HTML level does not establish a complete PDF heading hierarchy.

<h4>Account update</h4>

<h5>

Placement
Block content inside supported regions/containers
Defaults
Bold; semantic sizes h1=18, h2=16, h3=14, h4=12, h5=11, h6=10 pt, below named/explicit overrides; keep with next.

Inline formatted heading text. Current tagged-PDF model emits H1 for every heading level; HTML level does not establish a complete PDF heading hierarchy.

<h5>Account update</h5>

<h6>

Placement
Block content inside supported regions/containers
Defaults
Bold; semantic sizes h1=18, h2=16, h3=14, h4=12, h5=11, h6=10 pt, below named/explicit overrides; keep with next.

Inline formatted heading text. Current tagged-PDF model emits H1 for every heading level; HTML level does not establish a complete PDF heading hierarchy.

<h6>Account update</h6>

<div>

Placement
Block content inside regions/containers
Defaults
Text-only div becomes a text block; block children make an inherited style scope.

Style scopes preserve named-style inheritance. Mixing bare text with child block elements is rejected; wrap prose in p when grouping blocks.

<div style="color:#12665B"><p>First paragraph</p><p>Second paragraph</p></div>

<group>

Placement
Block content inside regions/containers
Defaults
Soft keep-together by default; style can choose auto/prefer/always.

Groups supported blocks. An impossible strict keep can fail. Page breaks are only allowed where the enclosing body context permits them.

<group style="keep-together:prefer"><h3>Heading</h3><p>Related text.</p></group>

<span>

Placement
Inline text within paragraphs, headings and list/cell text
Defaults
span inherits; strong/b set bold; em/i set italic; u sets underline.

Use style/style-name for supported typography. Explicit false/normal values can override inherited emphasis. Styles must name registered or standard font faces.

<p>Normal <span>emphasized text</span>.</p>

<strong>

Placement
Inline text within paragraphs, headings and list/cell text
Defaults
span inherits; strong/b set bold; em/i set italic; u sets underline.

Use style/style-name for supported typography. Explicit false/normal values can override inherited emphasis. Styles must name registered or standard font faces.

<p>Normal <strong>emphasized text</strong>.</p>

<b>

Placement
Inline text within paragraphs, headings and list/cell text
Defaults
span inherits; strong/b set bold; em/i set italic; u sets underline.

Use style/style-name for supported typography. Explicit false/normal values can override inherited emphasis. Styles must name registered or standard font faces.

<p>Normal <b>emphasized text</b>.</p>

<em>

Placement
Inline text within paragraphs, headings and list/cell text
Defaults
span inherits; strong/b set bold; em/i set italic; u sets underline.

Use style/style-name for supported typography. Explicit false/normal values can override inherited emphasis. Styles must name registered or standard font faces.

<p>Normal <em>emphasized text</em>.</p>

<i>

Placement
Inline text within paragraphs, headings and list/cell text
Defaults
span inherits; strong/b set bold; em/i set italic; u sets underline.

Use style/style-name for supported typography. Explicit false/normal values can override inherited emphasis. Styles must name registered or standard font faces.

<p>Normal <i>emphasized text</i>.</p>

<u>

Placement
Inline text within paragraphs, headings and list/cell text
Defaults
span inherits; strong/b set bold; em/i set italic; u sets underline.

Use style/style-name for supported typography. Explicit false/normal values can override inherited emphasis. Styles must name registered or standard font faces.

<p>Normal <u>emphasized text</u>.</p>

<a>

Placement
Inline text
Defaults
Inherited appearance.

Links remain native PDF links. Unsupported URI schemes are rejected. Link text may use supported inline formatting.

AttributeAccepted input / meaning
hrefRequired HTTP, HTTPS or mailto destination
titleOptional descriptive title
<p><a href="https://example.com/help" title="Help">Contact support</a></p>

<br>

Placement
Inline text
Defaults
Explicit line change within the current text block.

Void HTML element; no children. Use another p for a new paragraph.

<p>First line<br>Second line</p>

<page-number>

Placement
Inline text, including header/footer
Defaults
Dynamic current/total generated-letter page number.

Empty elements with paired closing tags. Counts exclude appended attachment pages. They do not accept text children.

<p>Page <page-number></page-number> of <page-count></page-count></p>

<page-count>

Placement
Inline text, including header/footer
Defaults
Dynamic current/total generated-letter page number.

Empty elements with paired closing tags. Counts exclude appended attachment pages. They do not accept text children.

<p>Page <page-number></page-number> of <page-count></page-count></p>

<page-break>

Placement
Body flow only
Defaults
Starts a new body page.

Empty, paired closing tag; no attributes including style/style-name. Not allowed inside tables, fixed regions, signatures, canvases or columns.

<main><p>First page</p><page-break></page-break><p>Second page</p></main>

<img>

Placement
Standalone block, supported region/rich cell, logo or image watermark
Defaults
Body fitting box up to 60 × 40 mm; region-specific defaults elsewhere; aspect ratio preserved.

PNG/JPEG/restricted static SVG. CSS dimensions override attributes. Percentages use available region dimensions. Width alone permits natural fitted height. No URL/file fetch, inline text images or image background-color.

AttributeAccepted input / meaning
srcRequired asset:name reference to supplied bytes
widthPositive mm/pt/px/% length; unitless means px at 96 dpi
heightPositive mm/pt/px/% length; unitless means px at 96 dpi
altImage description used in tagged output
<img src="asset:chart" width="70mm" alt="Comparison of previous and new rates">

<ul>

Placement
Supported block content
Defaults
Unordered bullets / ordered numbering; each nested list has independent numbering/indentation.

Direct li children with inline text and optional nested lists. Arbitrary paragraph/image/table blocks inside li are unsupported.

<ul><li>First item</li><li>Second item<ul><li>Detail</li></ul></li></ul>

<ol>

Placement
Supported block content
Defaults
Unordered bullets / ordered numbering; each nested list has independent numbering/indentation.

Direct li children with inline text and optional nested lists. Arbitrary paragraph/image/table blocks inside li are unsupported.

<ol><li>First item</li><li>Second item<ul><li>Detail</li></ul></li></ol>

<li>

Placement
Direct child of ul or ol
Defaults
Inline formatted item text.

Place text before child ul/ol lists; text after a child list is rejected.

<li>Item text<ul><li>Nested text</li></ul></li>

<table>

Placement
Supported regions/containers, outside another table
Defaults
Equal weights; ordinary row keeps prefer keeping a row together; optional theme table appearance.

One optional repeating thead row plus body rows. Define tbody for grouped rows. Spans must occupy a valid grid. No nested tables/page breaks, including through components.

AttributeAccepted input / meaning
column-weightsComma-separated positive finite relative column weights
row-keepauto, prefer or always
<table column-weights="2,1"><thead><tr><th>Item</th><th>Price</th></tr></thead><tbody><tr><td>Service</td><td>12.50</td></tr></tbody></table>

<thead>

Placement
Child of table
Defaults
Optional repeating header section.

Exactly one logical tr header row; th/td cells may span columns. Header and body span grids are independent. Keep rules intended for body rows are rejected in headers. The keep-together attribute is rejected on thead.

<thead><tr><th>Item</th><th>Price</th></tr></thead>

<tbody>

Placement
Child of table
Defaults
Body row group; optional inherited cell/text appearance.

Multiple groups can define explicit row grouping. Spans must stay within their legal grid/group constraints.

AttributeAccepted input / meaning
keep-togetherauto, prefer or always; applies to this body row group
<tbody keep-together="prefer"><tr><td>Related row</td></tr></tbody>

<tr>

Placement
Direct child of thead/tbody or supported table structure
Defaults
Inherits table row policy.

Direct th/td cells only. Template data-each/data-as/data-if may select or repeat real rows. Header row keep overrides are rejected.

AttributeAccepted input / meaning
row-keepauto, prefer or always; body rows only
keep-with-nextauto, prefer or always; body rows only
<tr row-keep="prefer"><td>Value</td><td>12.50</td></tr>

<th>

Placement
Direct child of tr
Defaults
1 × 1; th has bold semantic default below named/explicit overrides.

Either inline text or supported rich blocks. Borders/padding/background/vertical alignment inherit by field. Text mixed with child block elements is rejected.

AttributeAccepted input / meaning
colspanPositive integer number of columns
rowspanPositive integer number of rows
<th colspan="2"><p>Spanning cell</p><ul><li>Detail</li></ul></th>

<td>

Placement
Direct child of tr
Defaults
1 × 1; th has bold semantic default below named/explicit overrides.

Either inline text or supported rich blocks. Borders/padding/background/vertical alignment inherit by field. Text mixed with child block elements is rejected.

AttributeAccepted input / meaning
colspanPositive integer number of columns
rowspanPositive integer number of rows
<td colspan="2"><p>Spanning cell</p><ul><li>Detail</li></ul></td>

<canvas>

Placement
Supported block flow
Defaults
Coordinates start at the canvas upper-left corner within body flow.

Bounded indivisible flow unit containing positioned box children. Boxes must fit; overlaps are intentional in list paint order. No automatic splitting, browser absolute positioning or page breaks.

AttributeAccepted input / meaning
width-mmOptional finite positive width; defaults to available region width
height-mmRequired finite positive canvas height
<canvas width-mm="160" height-mm="30"><box id="address" x-mm="0" y-mm="0" width-mm="75" height-mm="25"><p>Example address</p></box></canvas>

<columns>

Placement
Supported block flow
Defaults
0 mm gap; independent columns.

Column children split the available width by weight and can flow across pages. No automatic text threading/balancing; no explicit page breaks inside columns.

AttributeAccepted input / meaning
gap-mmFinite nonnegative gap between columns
<columns gap-mm="6"><column weight="2"><p>Main text</p></column><column weight="1"><p>Side text</p></column></columns>

<column>

Placement
Direct child of columns
Defaults
Weight 1.

Independent supported block content and local style. A wider weight does not cause text to flow from another column.

AttributeAccepted input / meaning
weightFinite positive relative width
<column weight="2"><p>Column content</p></column>

<box>

Placement
Flowing block, or positioned direct child of canvas
Defaults
Ordinary flowing content with optional decoration.

Supports padding, background-color, border and per-edge borders alongside inherited typography. No general browser box model. Inside canvas, box instead declares a bounded positioned rectangle with a unique id, explicit width/height and optional x/y. Its rich content must fit; no page breaks. Decoration CSS applies to flowing box, not the positioned canvas wrapper.

AttributeAccepted input / meaning
idCanvas box only: Required unique nonblank stable identifier
x-mmCanvas box: finite nonnegative x; defaults to 0
y-mmCanvas box: finite nonnegative y; defaults to 0
width-mmCanvas box only: Required finite positive item width
height-mmCanvas box only: Required finite positive item height
<box style="padding:3mm; border:0.5pt solid #12665B; background-color:#F0F7F4"><p>Important information</p></box>

<component>

Placement
Supported block content
Defaults
Expands document-local reusable blocks before validation.

Empty element with a paired closing tag. Unknown references and reference cycles fail. Context rules still apply to expanded content.

AttributeAccepted input / meaning
refRequired name registered through components(...) or the shared model
<component ref="legal"></component>

<param>

Placement
Inline template content; template mode only
Defaults
text formatting unless selected; final template locale applies.

Void HTML tag, no closing tag, children or style/style-name. Wrap with span/strong for styling. Substitution creates literal text, never markup. Supported input type must match the format.

AttributeAccepted input / meaning
keyRequired scalar map path
formattext, date, number or currency
patternOptional formatter pattern
currencyOptional ISO currency override
<p>Total: <strong><param key="total" format="currency" currency="EUR"></strong></p>

<if>

Placement
Template content outside table structure
Defaults
Selects true branch or direct else branch; no expressions/truthiness.

Only flag is permitted. Use data-if on real table rows/cells. Inactive branches do not require their values/assets.

AttributeAccepted input / meaning
flagRequired map path to an actual Boolean
<if flag="showNotice"><p>Notice</p><else><p>Standard text</p></else></if>

<else>

Placement
One direct child of if
Defaults
Selected when flag is false.

No attributes, including style/style-name. Must be unique and in the supported final branch position.

<if flag="showNotice"><p>Notice</p><else><p>Standard text</p></else></if>