Skip to main content

Lists

A <x:list> is a vertical stack of <x:li> items, each flowed and wrapped like a mini <x:textbox> but with a hanging indent: the marker sits in the gutter and continuation lines align to the text column, not back under the marker. It is the ordered/unordered list SVG never got, and lowers to a <g> of drawn bullet shapes plus one plain <text> of positioned <tspan>s — live and selectable.

Compiling…
Bullet and numbered listsOpen in viewer ↗Edit in Playground →
Bullets that cycle by depth, decimal→alpha→roman numbering with a resuming outer counter, and a list flowed inside a referenced card.

Syntax​

<x:list x="40" y="80" width="300" list="bullet" font-size="14" item-spacing="5">
<x:li>Top-level item that wraps under its own text column</x:li>
<x:li indent="1">A nested item — one indent step in</x:li>
<x:li indent="2">Deeper still</x:li>
</x:list>

Hanging indent and nesting​

Each <x:li> is one item; indent="N" sets its nesting level (0 is the top). Every level steps the text column right by the indent step, and continuation lines of a wrapped item align to that column — the marker hangs in the gutter to its left. An empty item still advances one line.

Markers cycle by depth​

Bullet markers are drawn shapes, not font glyphs, so they don't vary by font and stay optically balanced. They cycle every three levels: a filled disc, a hollow ring, then a filled square. The shapes are area-compensated — the square's side is r·√π so its area matches the disc's, and the ring's outer diameter is enlarged about 12% since a hollow mark reads lighter.

With list="number", markers cycle decimal → lower-alpha → lower-roman by depth and keep an outline counter per level. The counter restarts whenever nesting pops back to a shallower level, so a top item after a sublist resumes where it left off — 1. 2. a. b. 3. Numbers are right-aligned into the gutter, so 1. and 10. share a column edge.

list="none" suppresses the marker but keeps the indent. A marker on the list — or on a single <x:li> — forces a named drawn shape (disc / circle / square / dash) or any literal string (▸, —, ★, …), overriding the cycle.

Flowing inside a shape​

Instead of x / y / width, give the list in="#rect" to take its left edge, top, and width from a referenced shape's bounding box (a baked reference). That box also supplies the height for valign, so a list can sit top, middle, or bottom inside a card.

Attributes​

AttributeValuesDefaultDescription
listbullet / number / nonebulletMarker style for the whole list.
markerdisc / circle / square / dash, or a literal string—Force a marker (drawn shape or literal text); overrides the list cycle.
marker-sizenumber1Scale factor on the drawn bullet shapes.
marker-fillcolorfillMarker color (shapes and number/character markers).
x y widthlength—The block's left edge, top, and content width.
in#id—Bind geometry to a referenced shape's bounding box; also supplies the height for valign.
valigntop / middle / bottomtopVertical placement within the height.
indentlength1.5emPer-level indent step.
marker-gaplength0.5emGap between the marker and the text column.
item-spacinglength0.35emExtra vertical gap between items.
font-*, line-height, fillas text—Base style for every item.

An <x:li> may set indent="N", marker="…", and font-size="…" (a smaller sub-point). It inherits the list's size and line-height otherwise, and its marker scales to match its size.

How it lowers​

A <x:list> compiles to a <g> containing the drawn bullet shapes plus one plain <text> whose positioned <tspan>s carry the item text and any number/character markers — no runtime, fully selectable.

v0 limits​

One style per item beyond font-size (inline <tspan> fill/weight inside an item is not yet applied). No shrink-to-fit or height clipping — the list flows from valign within the height but doesn't shrink to fit it. Number, roman, and character markers are live text (the glyphs must exist in the font); bullet shapes are drawn and font-independent.

See also​