Headings
Pick a heading token by composition layer and the HTML element by outline intent — the two independent choices every title makes.
A heading makes two independent choices, and conflating them is the usual mistake:
- Which token sizes it — decided by the heading's composition layer (a section headline is not a card title).
- Which HTML element renders it — decided by whether it is a document outline node, not by the token or the BEM name.
Get these from two different rules. The token comes from the table below; the element comes from HTML Semantics — Heading element selection.
Role by layer
| Layer | Role token | Weight / line-height | Example |
|---|---|---|---|
| Section headline | --heading-xl … --heading-huge (--display-* for oversized marketing) | semibold / tight | Hero headline, page title |
| Container / Block title | --heading-sm … --heading-md | semibold / tight | Card title, ContentBlock title, DataSection title |
| Component label | --label-* | medium / normal | Field label, stat label, chip / tab label |
ContentBlock's title slot is --heading-sm + --font-weight-semibold + --font-line-height-tight — the Block-title row, made concrete. Blueprint section headlines run the upper steps (--heading-lg/--heading-huge); --display-* is the mode-invariant tier available for oversized editorial headlines, though current blueprints render heroes with the top --heading-* steps.
A component label is not a small heading. Field labels, stat labels, and chip / tab labels are the label family and use --label-* with --font-family-label — never a --heading-* token. The marketing "eyebrow / kicker" above a headline is a subtitle in BDS (slot vocabulary), a --body-* role covered in Paragraphs — not a heading either.
Element by outline intent
Size and element are orthogonal: <div class="bds-card__title"> and <h3 class="bds-card__title"> are both valid and both use heading-tier tokens — the choice is outline intent, not appearance.
- An outline node (a section title a screen-reader user navigates to) renders
<h1>/<h2>/<h3>. - A decorative or repeating title (one card in a grid of many, a metric tile) renders
<div>or<p>, still with__titleBEM and heading tokens.
The titleAs prop
ContentBlock exposes this choice as the titleAs prop (h1–h4 | div | p):
- Default
h3— the common case nests inside aCard, an outline child two levels below the page<h1>. - Pass
h2when the block is a direct outline sibling of the page's<h1>(a top-level page region). - Pass
div/pwhen the block repeats decoratively and is not an outline node.
<ContentBlock titleAs="h2" title="Membership Plans" description="…" />Casing
Headings and section titles use title case — the copy-side companion to the font-family role rule. The full rule (major vs minor words, hyphenated compounds, the CMS-content and microcopy exceptions) lives in Typography — Heading casing.
Related
- Typography — the
--heading-*/--display-*/--label-*scales and the font-family role rule. - Paragraphs — the body roles a heading sits above.
- Content Rhythm — the spacing between a heading and what follows it.
- HTML Semantics — outline nodes, stable IDs, and element selection.
Display Choice
Which display a given shape of data gets — table, field grid, card grid, list, accordion, or banner — the shape that rules each one out, and the state shell that wraps it.
Paragraphs
The body-text roles and line-height pairings, and how to decide between a ContentBlock description, Prose, and a raw slot paragraph.