text
Text sets a run of words in one of five type roles: body text for reading, interface text for short names and values, muted and dim text for secondary lines, and mono text for values.
when to use
- For sentences and paragraphs: body text, set as a paragraph.
- For short text in an interface that isn't a control's own label, such as a name in a list or a value in a panel: interface text.
- For secondary facts beside the main line, such as a timestamp, a size or a path: muted text. For a line people can safely skip: dim text.
- For values people read in monospace, such as durations, hashes and sizes, when they don't need the frame that code draws: mono text.
- For a line that must not wrap, such as a long path in a narrow column: text cut to one line.
when to use something else
- For a page or section title. Use a heading, which makes a real heading, at the first or the second heading level.
- For commands, flags or anything people type or copy. Use code, which marks the text as code and puts it in a frame.
- For a keyboard key. Use kbd, which draws the key as a keycap.
- For a form label, a hint or an error. Use a field. It makes a real label, ties the hint and the error to the control, and marks the control as invalid. Text that only looks like a label is styled text, tied to nothing.
- For a state or a message. The state of an object is a status; a message about the page is a banner.
anatomy
- Run of text. Words in one role, with no space of their own around them. The role sets the typeface, the weight, the size, the spacing between lines and the colour.
- Ellipsis (when it is cut to one line). Three dots where the line is cut, at the edge of its container.
variants and states
the five roles
| role | looks | use it for |
|---|---|---|
| Body text (the default) | The body face at reading size, in a soft white | Sentences and paragraphs |
| Interface text | The body face, smaller than body text, a little heavier and brighter | A name in a list, a value in a panel |
| Muted text | The body face at the size of interface text, in grey | Facts beside the main line: a timestamp, a size, a path |
| Dim text | The body face at the size of interface text, in a darker grey | A line people can safely skip |
| Mono text | Monospace at the size of interface text | Values people read: durations, hashes, sizes |
Muted and dim text are the size of interface text, not of body text. They are for secondary lines in an interface, not for quieter paragraphs: there is no muted version of body text.
mono values in a sentence
Mono text is monospace without the frame and the colour that code has. Use it for values people read, not for code.
The last backup took 00:04:12 and wrote 412 gb.
cut to one line
Text can be cut to a single line where its container ends.
what the text is
What the text is can change while its look stays the same: text in any role can be a paragraph, or a heading at a level that the heading component doesn't offer.
Backups
Backups run every night at 02:00 and are kept for 14 days.
behaviour
- Text is only there to be read: it takes no focus and handles no keys.
- A line cut to one line needs a width to cut against: it is at most as wide as its container.
The keyboard map, the element it renders and what it passes through are on the text's React page.
accessibility
- The meaning comes from what the text is, not from its look. Make it a paragraph, a heading or a run of words inside other text, whichever it really is.
- Colour carries no meaning. Muted and dim text lower the emphasis, not the importance. Never put the only copy of something people need in dim text.
- Every text colour, dim included, has enough contrast on every background.
Today: a line cut to one line is cut only for the eye. A screen reader reads all of it, but people who see the screen, whether they use a keyboard, touch or a mouse, can't reach the rest: no tooltip is built in. Show the full value somewhere they can reach, in a detail view or in a tooltip, whose trigger takes focus.
content
- Body text is for full sentences. Follow the voice: sentence case, plain words, no exclamation marks.
- Interface text is a few words: a name, a value, a short phrase.
- Muted text states facts, not instructions: “Updated 3 min ago”, “412 GB used”.
- Dim text is only for what people can skip. Warnings and next steps never go there.
- Mono text is for values. A sentence set in mono to look technical is harder to read, not more precise.
do and don't
Run ctl get volumes to list them.
Run ctl get volumes to list them.
related
- Heading: page and section titles.
- Code: commands and identifiers, in a frame.
- Typography: the full set of type roles, these five included.
- Content & voice: how to write the words.
specs
| role | in code | typeface | weight | size / line height | colour |
|---|---|---|---|---|---|
| Body text | variant="body" (the default) |
Inter (--ff-ui) |
400 | 16px / 1.55 | --fg-2 |
| Interface text | variant="ui" |
Inter | 500 | 13px / 1.4 | --fg |
| Muted text | variant="muted" |
Inter | 400 | 13px / 1.4 | --fg-muted |
| Dim text | variant="dim" |
Inter | 400 | 13px / 1.4 | --fg-dim |
| Mono text | variant="code" |
JetBrains Mono (--ff-mono) |
500 | 13px / 1.5 | --fg-2 |
- Element: a
spanwith no margin.aspicks another element and keeps the look:as="p"for a paragraph,as="h3"for a heading levelHeadingdoesn't offer,as="div"for a block.variant="code"is still aspan, not acodeelement. - Cut to one line:
truncate. Aninline-blockwithmax-width: 100%, on one line (white-space: nowrap), cut withtext-overflow: ellipsis. It sets notitle. - Contrast: every text colour,
--fg-dimincluded, meets 4.5:1 on every background. - The other components:
Headingrenders a realh1orh2;Coderenders acodeelement in a frame;Fieldrenders thelabel, ties the hint and the error to the control and marks it invalid.Text as="label"is only styled text, tied to nothing.