Typography

Titles, paragraphs and inline text, with ellipsis, copy, edit and the semantic color types.

Usage

When text needs a component, which of the four parts to use, and what each prop decides: the heading tag, the color, the size, the truncation and the elements the decoration flags render.

When to use

Use Typography for text that needs something done to it: a heading in the document outline, a semantic color, a truncation with a tooltip, a copy button, in-place editing, or inline code and kbd that follow the theme.
  • A heading anywhere in a page or a card. Title renders a real <h1> to <h5>, sized by the theme, so it shrinks in compact mode.
  • Copy that is quieter than the rest. type uses the theme's text colors, so a secondary line stays readable in both modes with no hex in your code.
  • A value the reader will copy: an ID, a key, a path. copyable with ellipsis.suffix makes it fit a narrow column.
  • Document content. The root <Typography> styles the native h1 to h5, p, ul, li and table inside it.
Use something else when
  • You need none of its props. A plain <p>, <span> or <h2> with the theme's text classes (text-secondary, text-tertiary, text-size-heading-2) uses the same tokens without a component.
  • The text labels a form control. Use the Form item's label, which links the label to the input. A Text beside an input does not.
  • The text navigates. Use your router's link. Typography.Link is an <a> with the link color, for text that happens to be a link.
  • You need a multi-line editor. editable strips newlines as you type and Enter commits. Use Input.TextArea instead.

Title, Paragraph, Text and Link

The four parts share one set of props, so type, copyable, editable, ellipsis and the decoration flags behave the same on each. What differs is the element they render.
  • Typography.Title renders <h1> to <h5>, chosen by level. It has no strong, because a heading is already bold.
  • Typography.Paragraph renders a <div> with a bottom margin, and is the only part that takes multi-line ellipsis.
  • Typography.Text renders a <span>. It is inline, with no margin of its own.
  • Typography.Link renders an <a> with the link color and hover. Its ellipsis is on or off only.
  • Use the root Typography for documents, and the parts for UI text. The root renders an <article> that styles the native h1 to h5, p, ul, blockquote, pre and table inside it, for Markdown or CMS output. Use Title, Text and Paragraph for single pieces of copy.

Level is an outline, not a size

level picks the heading tag, and screen readers, outline views and tables of contents read the tag. Pick the level from where the heading sits in the page, then adjust the look with a class if needed. Picking it for its size is how a card ends up as the page's h1.
  • Use one <h1> per page, for the page's subject. level defaults to 1, so a bare <Title> inside a card is the wrong level.
  • Do not skip a level on the way down. A section under an h2 is an h3, even where the design wants it small.
  • Title stops at level 5. There is no h6. A level of 6 logs a warning in development and falls back to h1.
  • Heading sizes come from the theme and shrink in compact mode. A heading that needs another size on one surface takes a class, and keeps its level.

The semantic type colors

type takes five values: secondary, tertiary, success, warning and danger. The first two turn the volume down, and the other three carry a meaning.
  • secondary is a step stronger than Ant Design's. It uses colorTextSecondary, for supporting copy that is still meant to be read: a caption, a helper line, a timestamp.
  • tertiary is the lighter gray Ant Design calls secondary, for text that is there if you look for it. Code that relied on the old secondary look moves to tertiary.
  • success, warning and danger state an outcome. Use them where the words are about one, and not to get a green or a red.
  • For unavailable text, use the disabled flag. It means unavailable, not quiet.

Size names a step, not a pixel

size steps down the theme's text ramp. On Text and Paragraph, label, sm and xs are 13, 12 and 11px in the default theme, and each step stays smaller than the one above it, in compact mode too. The line height follows each step.
  • An unset size adds nothing, so a plain <Text> renders at the base size.
  • Title has no size. It is sized by level.
  • Small text is still small: three steps down is 11px, which suits a caption, not a paragraph.

Ellipsis, and what it costs

ellipsis comes in four forms. The single-line form is plain CSS, and the rest are measured in JavaScript.
  • One line. ellipsis as a boolean, or with rows: 1. Text and Link are inline, so they need a width to cut at, like the block class.
  • Several lines. { rows: 3 }, on Paragraph only. Passing rows or expandable to Text logs a warning.
  • Expandable. expandable: true adds a button after the text, and "collapsible" lets it close again. symbol changes the label and onExpand reports each change.
  • With a tooltip. tooltip shows the full text on hover and focus. It suits a cut-off value in a dense table, and it does not help on touch.
  • ellipsis.suffix keeps the end of the text. Use it for file paths, IDs and keys, and pair it with copyable.text so the full value is copied. onEllipsis fires when the text starts or stops being cut.

Copyable and editable

Both take true or a config object, and both add a button after the text, or before it with actions={{ placement: 'start' }}.
  • Copy and edit icons come from your icon pack. Your own copyable.icon or editable.icon replaces them, enterIcon: null removes the return hint, and copyable={false} stays off. The default copy icons animate the swap, and icons you pass swap without animation.
  • copyable.text is what gets copied, whatever is shown. That is how a cut-off key copies in full. It can be a function that returns a Promise, for a value you fetch on click.
  • copyable.tooltips and copyable.icon each take a pair, for before and after copying. Pass false to tooltips to show none.
  • Copy the whole useful value. A copy button next to half an ID is worse than none.
  • editable swaps the text for a text area in place. triggerType sets what starts it: ["icon"] by default, or ["icon", "text"] to make the text clickable too.
  • Keep editable children a string. The editor starts from the children only when they are a string, so a node opens an empty editor.
  • Editing manages itself unless you pass editing. Enter and blur both commit, Escape cancels, and newlines are removed as you type, so use it for a name or a title.
  • onChange gives you the trimmed string, and you store it. If you ignore onChange, the old text comes back when editing ends.

The decoration flags are real elements

code, keyboard, mark, strong, italic, underline and delete each wrap the text in the matching element, and they combine in a fixed nesting order, whatever order you write the props in.
  • code is an identifier, a path or a snippet. keyboard is a key the reader presses. They look alike and mean different things, and a screen reader tells them apart.
  • Code and keys follow the theme. code, keyboard and a native pre use the theme's fills and corner radius, in light and dark mode. kbd keeps its heavier bottom edge, which is what makes it look like a key.
  • mark is a search hit or a highlight. Its background is a fixed yellow that does not follow the theme, so check it in dark mode.
  • strong renders <strong>, not <b>. It marks importance and can be read with emphasis. For a keyword that is only set apart, use <b>, or a font-strong class for the weight alone.
  • The same goes for the rest: italic renders <i> (style, not stress), delete renders <del> (removed content) and underline renders <u>, which most people read as a link.

Styling it

Style parts with classNames. The keys are root, actions (the wrapper around the buttons), action (each copy, edit and expand button) and textarea (the editor, only there while editing). styles takes the same keys.
  • Use theme classes rather than fixed values. The type colors, the heading sizes and the code styles all change with dark mode, and a hex does not.
  • For a size off the ramp, use a class instead of size. Setting both size and a text-[13px] of your own gives one element two sizes, and the last class wins.