Typography
Text uses the system font of each OS and a fixed set of roles, from Display to Caption. Pick a role for what the text is, and its size, weight, and line height come with it.
<tk-text variant="title-md" as="h2">Billing</tk-text> <tk-text>Your plan renews on the first of each month.</tk-text> <tk-text variant="caption" color="secondary">Prices include tax.</tk-text>
Roles
<tk-text variant="display-sm">Display Small</tk-text> <tk-text variant="title-md">Title Medium</tk-text> <tk-text variant="heading-md">Heading Medium</tk-text> <tk-text variant="body-md">Body Medium</tk-text> <tk-text variant="label-md">Label Medium</tk-text> <tk-text variant="caption">Caption</tk-text> <tk-text variant="code-sm">Code Small</tk-text>
| Role | Use for | Not for |
|---|---|---|
| Display | the one hero title of a landing or promo screen | anything inside a component; long lines |
| Title | page and section headings, three levels | a promo hero |
| Heading | a subheading inside a block; Heading Medium titles dialogs, sheets, and empty states | the page title |
| Body | paragraphs and descriptions; Body Small for dense content such as tables, menus, and helper text | headings |
| Label | the text of a control: buttons, tabs, field labels | paragraphs; the value typed into a field, which is Body |
| Caption | timestamps, metadata, fine print, the second line under a row's label | main text |
| Code | code and technical values, in the mono font | ordinary text |
Body Medium (16/24) is the default for text. Most roles come in Large, Medium, and
Small; Heading and Code have Medium and Small, and Caption has one size. Every size, line
height, and weight is in the
Label and Body share sizes
Label sits one size below Body: Label Large is 16px, the size of Body Medium. Two pairs differ only in weight:
- 14/20: Body Small at 400, Label Medium at 500.
- 12/16: Caption at 400, Label Small at 500.
Use Caption for a second line that supports the line above it, and Label Small for the text of a small control.
- Label Medium is the default control label: buttons at medium and large size, tabs, field labels, menu options.
- Label Small is for small buttons and icon buttons.
- Label Large is for control text that sits in the reading flow: accordion and collapsible headers, a toast's action.
Links
A link has no role of its own. tk-link
Applying a role
With tk-textvariant picks the role and as picks the
HTML element. Choose the heading level from the page outline, then the role that looks
right.
<tk-text variant="title-sm" as="h2">Payment method</tk-text> <tk-text variant="heading-sm" as="h3">Billing address</tk-text>
In your own CSS: a role isn't one variable. Set it from the type variables listed in
the
.summary {
font-family: var(--font-family-sans);
font-size: var(--font-size-sm);
line-height: var(--line-height-body-sm);
font-weight: var(--font-weight-regular);
}Emphasis
Make a word stand out with weight, not with a bigger size or a new color.
<tk-text>Your trial ends in <tk-text as="span" weight="semibold">3 days</tk-text>.</tk-text>
There are four weights: 400 regular, 500 medium, 600 semibold, and 700 bold. Headings are 600, labels 500, and body text 400.
Text color
A role sets the shape of text, not its color. Color comes from the text/* color tokens;
on tk-text, set color. Links use text/accent. See
<tk-text color="secondary">Last edited 5 minutes ago</tk-text> <tk-text color="error">Card declined</tk-text>
Fonts
Thykes loads no font. Each OS shows its own system font:
| OS | Font |
|---|---|
| macOS, iOS | SF |
| Windows | Segoe UI |
| Android | Roboto |
| Linux | Ubuntu or Cantarell |
Code uses the system monospace font. To line up numbers in a column, set
font-variant-numeric: tabular-nums.
Set the base font on your page. The token CSS only defines variables; it doesn't style your elements. Without this rule, plain elements and slotted text fall back to the browser's serif font:
body {
font-family: var(--font-family-sans);
}Accessibility
- Main text is at least 14px (Body Small); the default is 16px. 12px is for Caption and Label Small only.
- Keep lines to 60–80 characters in paragraphs.
- Leave room for text spacing. Layouts must survive line height at 1.5×, paragraph spacing at 2×, letter spacing at 0.12×, and word spacing at 0.16× the font size. Don't fix heights that clip text.
- Pick heading tags by outline, not by size: one
h1per page, no skipped levels. - Don't carry hierarchy or meaning by color alone; use size, weight, and position.
- Truncate only with a way to read the rest, such as a tooltip or a details view.
- Contrast is set in the color tokens: 4.5:1 for text, 3:1 for large text (24px, or
18.66px bold). See
Color .
Limits
- Font sizes are in px. Text grows with browser zoom, but not with the browser's default font-size setting.
Do / Don't
| ✅ Do | ❌ Don't |
|---|---|
| Pick a role for what the text is | Set a font size by hand |
| Use Display only for a screen's hero title | Put Display inside a component |
| Emphasize with weight | Add a bigger size to stress one word |
| Keep main text at 14px or larger | Set body text in 12px |
| Align paragraphs to the start | Justify text; it leaves uneven gaps |
| Write in sentence case | Set ordinary text in all caps |
Use tabular-nums for columns of numbers |
Let digits in a column shift widths |
Related
Text : the component that applies a role.Prose : spacing between paragraphs of authored content.Link andCode block .Color : text colors and contrast.Spacing : line heights and spacing share the 4px unit.
The 18 type roles and the variables they are built from.
Roles
Each role is a set of the variables below. Sizes and line heights are in px.
| Role | tk-text variant |
Size / line height | Weight | Font |
|---|---|---|---|---|
| Display Large | display-lg |
64 / 72 | 600 | sans |
| Display Medium | display-md |
48 / 56 | 600 | sans |
| Display Small | display-sm |
40 / 48 | 600 | sans |
| Title Large | title-lg |
32 / 40 | 600 | sans |
| Title Medium | title-md |
28 / 32 | 600 | sans |
| Title Small | title-sm |
24 / 28 | 600 | sans |
| Heading Medium | heading-md |
20 / 24 | 600 | sans |
| Heading Small | heading-sm |
18 / 24 | 600 | sans |
| Body Large | body-lg |
18 / 28 | 400 | sans |
| Body Medium (default) | body-md |
16 / 24 | 400 | sans |
| Body Small | body-sm |
14 / 20 | 400 | sans |
| Label Large | label-lg |
16 / 24 | 500 | sans |
| Label Medium | label-md |
14 / 20 | 500 | sans |
| Label Small | label-sm |
12 / 16 | 500 | sans |
| Caption | caption |
12 / 16 | 400 | sans |
| Code Medium | code-md |
16 / 24 | 400 | mono |
| Code Small | code-sm |
14 / 20 | 400 | mono |
| Link | none | 16 / 24 | 400 | sans |
Label Small and Caption add --letter-spacing-caption; every other role uses
--letter-spacing-normal. Link describes a link in body text; tk-link takes the type of
its line instead.
Font size
| Variable | px |
|---|---|
--font-size-xs |
12 |
--font-size-sm |
14 |
--font-size-md |
16 |
--font-size-lg |
18 |
--font-size-xl |
20 |
--font-size-2xl |
24 |
--font-size-3xl |
28 |
--font-size-4xl |
32 |
--font-size-5xl |
40 |
--font-size-6xl |
48 |
--font-size-7xl |
64 |
Line height
Two sets, both on the 4px grid: body for reading text, labels, and code, and heading
for Display, Title, and Heading. The variable is --line-height-{set}-{size}, paired with
the font size it serves. A dash means the set has no value at that size.
| Size | --line-height-body-* |
--line-height-heading-* |
|---|---|---|
xs |
16 | — |
sm |
20 | — |
md |
24 | — |
lg |
28 | 24 |
xl |
28 | 24 |
2xl |
— | 28 |
3xl |
— | 32 |
4xl |
— | 40 |
5xl |
— | 48 |
6xl |
— | 56 |
7xl |
— | 72 |
Font weight
| Variable | Value | Used by |
|---|---|---|
--font-weight-regular |
400 | Body, Caption, Code, Link |
--font-weight-medium |
500 | Label |
--font-weight-semibold |
600 | Display, Title, Heading |
--font-weight-bold |
700 | emphasis |
Letter spacing
| Variable | Value | Used by |
|---|---|---|
--letter-spacing-normal |
0em | every role except the two below |
--letter-spacing-caption |
0.01em | Caption, Label Small |
Font family
| Variable | Stack | Used by |
|---|---|---|
--font-family-sans |
system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Ubuntu, Cantarell, "Noto Sans", "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji" |
all text |
--font-family-mono |
ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Roboto Mono", "Ubuntu Mono", "Liberation Mono", monospace |
Code |