Get a heading whose size, weight, tracking and leading always match, with the document outline (level) set apart from the look (size).
When to use
- Keep page and section titles consistent: a 36px title always gets display tracking, and a 20px one never goes semibold.
- Keep the outline correct when the design wants a different size: render an
h2that looks like a 20px title. - Mark a quieter heading under a stronger one with
tone="secondary".
When not to use
Installation
npx shadcn add https://eased.dev/r/heading.jsonThe command adds Heading, everything it builds on and Eased’s tokens to your project.
Usage
import { Heading } from "@/components/eased/heading/heading";import { Text } from "@/components/eased/text/text";export function BillingHeader() { return ( <header className="flex flex-col gap-1"> <Heading level={1}>Billing and invoices</Heading> <Text tone="secondary">Manage your plan, payment methods and receipts.</Text> </header> );}Examples
Level and size apart
Use size when the outline needs an h2 but the layout needs a smaller title, such as a card heading.
<Heading level={2} size="xl">Payment methods</Heading>Secondary tone
Use tone="secondary" for a heading that sits under a stronger one, such as a group label inside a settings page.
<Heading level={3} size="md" tone="secondary">Billing contact</Heading>API reference
Heading
| Prop | Type | Default | Description |
|---|---|---|---|
level | 1 | 2 | 3 | 4 | 5 | 6 | 2 | The element it renders, h1 to h6. |
size | "md" | "lg" | "xl" | "2xl" | "3xl" | "4xl" | "5xl" | "6xl" | by level | 16, 18, 20, 24, 30, 36, 48 or 60px. Without it, level 1 is 4xl, 2 is 2xl, 3 is xl, 4 is lg, and 5–6 are md. |
tone | "default" | "secondary" | "default" | secondary uses the secondary text colour. |
className | string | "" | Appended to the heading's classes. |
Every other h1–h6 attribute passes through, such as id for an anchor link.
Each size carries its own weight: medium below 24px, semibold from 24px, and the display face with tracking-display from 36px. Sizes use the text-display-* and text-ui-* tokens in eased.css.
Accessibility
- It renders a real
h1–h6, so the outline that screen readers navigate by followslevel, neversize. - Keep levels in order on a page; change
size, notlevel, to make a heading look smaller.
Motion
None. A heading holds still so the things around it can move.
Notes for AI
Pick Heading for any title outside rendered markdown. Set level from the document outline first, then set size only when the design calls for a different look. Don't skip levels to get a smaller size.
Don't add font-semibold, tracking-* or text-* size classes: the size already pairs weight, tracking and leading, and extra classes break that pairing. Don't use it for headings inside markdown output; Prose styles those.
Responsive
Sizes are fixed rem values and don't change with the viewport. Long titles wrap with text-balance, so the last line is never a single word, and long words break instead of overflowing. The heading has min-w-0, so it shrinks inside flex and grid rows; add truncate through className to keep it on one line.