Typography

Raw
GuidancelatestM3Retrieved 2026-05-11

Material Design 3 — Typography

Overview

M3's typography system is built around two concepts: the typeface (font family) and the typescale (a set of role-based text styles). These are represented as separate token layers, and the relationship between them is explicit: typeface tokens define the font families, and typescale tokens map each text role to specific family, size, weight, and line-height values.


M3 Expressive Update (May 2025)

The M3 type scale now includes 30 type styles: 15 baseline styles (unchanged) and 15 new emphasized styles.

Emphasized styles add expressive weight to highlighted moments within a layout — they are not replacements for the baseline styles but additive options for greater typographic contrast and hierarchy.

Emphasized style tokens follow the pattern --md-sys-typescale-<role>-<size>-emphasized-<property>. For example:

  • --md-sys-typescale-display-large-emphasized-weight
  • --md-sys-typescale-headline-medium-emphasized-size

Platform availability: Emphasized styles are available in Jetpack Compose, MDC-Android, and Flutter. Web support is not yet available (as of May 2025).

Variable fonts: Roboto Flex can express a wide range of emotional states through its variable axes (weight, width, grade, slant, optical size), but is not yet part of the formal M3 typescale.


Typefaces

M3 distinguishes two typeface roles:

Typeface RoleTokenDefaultPurpose
Brand--md-ref-typeface-brandRobotoDisplay, headline, title scales — expressive, prominent text
Plain--md-ref-typeface-plainRobotoBody, label scales — readable, utilitarian text

In the default system, both roles use Roboto. Customization typically involves replacing brand with a product's own display typeface while keeping a system/neutral font for plain.

Each typeface requires three weights to be loaded: Regular (400), Medium (500), and Bold (700). These weights map to M3's normal, medium, and bold token values.

Important: If you do not customize the typeface, you must load Roboto explicitly (e.g. from Google Fonts). The system does not bundle the font.

/* Load Roboto */
@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700&display=swap');

Typeface customization via CSS:

@import url('...your-font...');
:root {
  --md-ref-typeface-brand: 'Your Brand Font';
  --md-ref-typeface-plain: system-ui;
}

Typescale

The typescale is M3's complete set of text styles, organized into five roles, each available in three sizes.

The Five Typescale Roles

RolePurposeWhen to Use
DisplayLargest text. Short, important strings.Hero headings, splashscreens, decorative moments
HeadlineHigh-emphasis text, shorter than displayPage titles, section headers, dialog titles
TitleMedium emphasis. Longer than headlines.List headings, card titles, app bar titles
BodyThe workhorse. Long-form readable contentArticle text, descriptions, form instructions
LabelSmall, utilitarian. Button text, captionsButton labels, field labels, captions, chip labels

Sizes Within Each Role

Each role has three sizes: large, medium, small. Use larger sizes for more emphasis and visual prominence; smaller sizes for denser UIs or secondary information.

Default Type Scale Values

Role + SizeFont FamilyWeightSizeLine Height
Display LargeBrandRegular (400)57sp64sp
Display MediumBrandRegular (400)45sp52sp
Display SmallBrandRegular (400)36sp44sp
Headline LargeBrandRegular (400)32sp40sp
Headline MediumBrandRegular (400)28sp36sp
Headline SmallBrandRegular (400)24sp32sp
Title LargeBrandRegular (400)22sp28sp
Title MediumBrandMedium (500)16sp24sp
Title SmallBrandMedium (500)14sp20sp
Body LargePlainRegular (400)16sp24sp
Body MediumPlainRegular (400)14sp20sp
Body SmallPlainRegular (400)12sp16sp
Label LargePlainMedium (500)14sp20sp
Label MediumPlainMedium (500)12sp16sp
Label SmallPlainMedium (500)11sp16sp

sp = scalable pixels (equivalent to rem in web contexts)


Token Naming Convention

Web typescale tokens follow the pattern --md-sys-typescale-<role>-<size>-<property>:

--md-sys-typescale-body-medium-font        /* font-family */
--md-sys-typescale-body-medium-size        /* font-size */
--md-sys-typescale-body-medium-line-height /* line-height */
--md-sys-typescale-body-medium-weight      /* font-weight */

Typeface reference tokens: --md-ref-typeface-brand, --md-ref-typeface-plain

Shortcut: Changing --md-ref-typeface-brand and --md-ref-typeface-plain cascades through all typescale roles that use those families, avoiding the need to update each role individually.

For per-role typeface overrides (e.g. a different font for headlines specifically):

:root {
  --md-sys-typescale-headline-font: var(--my-display-font);
  --md-sys-typescale-title-font: var(--my-display-font);
}

Applying Typography — Usage Guidelines

Display: Reserve for the single most important text on a screen. Typically one instance per view. Avoid using display sizes for interactive or functional text.

Headline: Used for section titles, dialog headers, and page-level labels. Should communicate clear hierarchy. One to two per screen is typical.

Title: For component-level headings — card titles, list item headers, app bar labels. Title Large is appropriate for prominent app bar text; Title Medium and Small for secondary component headings.

Body: The primary reading text. Body Large for long-form prose; Body Medium for standard UI descriptions; Body Small for supplementary or fine-print text.

Label: For all small utility text — button labels, form field labels, tab labels, chip text, captions. Label Large is the standard for button text; Label Small for captions and timestamps.


Do's and Don'ts

Do:

  • Use the typescale role that matches the content's purpose, not its desired visual size
  • Load all three weights (400, 500, 700) for any font you configure
  • Use --md-ref-typeface-brand and --md-ref-typeface-plain to change fonts globally rather than overriding individual tokens
  • Maintain the line-height values — they are calibrated for readability

Don't:

  • Use Display or Headline sizes for body text, even if you want large body text — adjust size via the appropriate body tokens
  • Skip weight loading — missing weights cause browsers to synthesize them, producing poor results
  • Mix M2 typography class names (mdc-typography--headline1) with M3 token names

Sources