Loading page…
Loading page…
One hairline, three jobs — cut a stack horizontally, split a row vertically, or carry a set of coordinates between two segments of rule. Everything else that divides content in this system is a border utility; this page names all of them so the choice is never a guess.
Horizontal fills its container and is the default. Vertical is a one-pixel column that stretches to the tallest sibling — it needs a flex parent, and it never carries a label.
Broadcast queue
Confirmed
Full width, h-px. Spacing is the caller's — pass my-4 or wrap it.
Balance
1.482 90 BTC
In flight
0.006 10 BTC
Fee rate
14 sat/vB
w-px, self-stretch. Height comes from the flex row, so give it siblings with real content.
import { Separator } from "@coldharbor/webui";
<Separator className="my-3" />
<div className="flex items-center gap-4">
<Stat label="Balance" value="1.482 90 BTC" />
<Separator orientation="vertical" />
<Stat label="Fee rate" value="14 sat/vB" />
</div>--ch-border--ch-fg-faint--ch-surface--ch-font-family-monoPass label and the rule splits into two segments around centred mono caps. Horizontal only — a vertical separator ignores it. Station coordinates are the house label; a short section name works the same way. The label is decoration, not structure — see Semantics before you let it stand in for a heading.
The signature footer rule on every wallet surface.
Treasury surfaces use it to open a block. Sighted readers get the name; assistive tech does not, so the block still needs a heading of its own.
Rule, label, content. The visible heading is the rule; the announced heading is the sr-only h3 above it.
// Ornament — decorative drops the role, aria-hidden silences the label.
<Separator label="54°38′N 19°53′E" decorative aria-hidden />
// A named block — the rule is the visible heading, the sr-only h3 is the real one.
<h3 className="sr-only">Holdings</h3>
<Separator label="Holdings" />--ch-border--ch-fg-faint--ch-surface--ch-font-family-monodecorative swaps role=separator for role=none, so the rule stops being announced as a boundary. It does not silence a label: the label span is plain text either way. Two rules follow from that, and they run opposite to what the prop names suggest.
role="separator" with aria-orientation. Announced as a boundary — use it when the line is the only thing marking one. Separator children are presentational, so a label here is NOT read out.
role=none leaves the label in the accessibility tree. Add aria-hidden for repeating ornament — otherwise every surface announces its coordinates.
// Announced boundary: this rule is the only thing separating two groups.
<Separator />
// → <div role="separator" aria-orientation="horizontal" />
// Ornament: role=none alone still leaves the label readable, so hide it too.
<Separator label="54°38′N 19°53′E" decorative aria-hidden />
// A label that carries meaning belongs in a heading, not on the rule —
// role="separator" makes its own children presentational.
<h3 className="sr-only">Holdings</h3>
<Separator label="Holdings" />--ch-border--ch-fg-faint--ch-surface--ch-font-family-monoNever stack separators between list items. divide-y divide-line-faint draws the rules from the list itself — no trailing hairline, no extra nodes, and the faint border keeps repeated rules from striping the surface.
Padding lives on the row so the rule spans the full frame width.
<ul className="ch-frame flex flex-col divide-y divide-line-faint bg-surface">
{rows.map((row) => (
<li key={row.id} className="flex items-center justify-between gap-4 px-4 py-3">
…
</li>
))}
</ul>--ch-border-faint--ch-surface--ch-fg-muted--ch-fg-faintA heading that owns the content below it carries its own border-b border-line — the rule belongs to the header, not between two peers. PageHeader is built this way. Reach for Separator only when the boundary has no heading to attach to.
Quorum 2 of 3.
Body follows the rule.
Rule attached to the header, padded off the title with pb-3.
Change output
Network fee
No heading to hang the border on — a peer boundary inside one block.
<header className="border-b border-line pb-3">
<h3 className="font-heading text-sm font-semibold text-fg">Signers</h3>
</header>
// vs. a boundary with no header of its own
<Separator className="my-3" />--ch-border--ch-fg--ch-fg-mutedPlain rule, labelled rule and a divided list on the canvas layer.
--ch-border--ch-fg-faint--ch-surface--ch-font-family-mono