Skip to content

ExpressiveCSS

Browse documentation

Typography

Material Design 3 type, from the HTML.

View as Markdown

The HTML elements carry the type scale. <h1> to <h6> take display and headline roles, <p> takes body-large and <small> takes body-small. Add a class only when the element cannot carry the role, such as a <span class="label-large"> or a <p class="display-large"> used as a hero numeral.

Tokens follow the M3 type system. Each role sets family, size, weight, line-height, and letter-spacing from --md-sys-typescale-*. They do not set font-style. The token named -font-family-style holds "Regular" / "Medium", which are weights, not CSS font-style keywords.

M3's --md-ref-typeface-brand and --md-ref-typeface-plain tokens both default to Roboto. Large display, headline, and title-large roles use brand. Smaller title, body, and label roles use plain. Override the reference tokens to use a different family.

Noto Sans is the fallback for characters Roboto cannot cover. Roboto ships Latin, Latin Extended, Cyrillic, Cyrillic Extended, Greek, Greek Extended and Vietnamese. Noto Sans adds Devanagari. Each subset comes at 400, 500 and 700. Every subset is its own face with a unicode-range, so the browser downloads only the scripts and weights the page renders.

Noto Sans Arabic, Noto Sans Hebrew and Noto Sans Thai come next in the fallback. Each covers only its script's range, so a page fetches one only when it shows that script. CJK text falls through to the system font the browser picks for the element's lang. Set lang on Japanese, Chinese and Korean text. For another script, load its family and add it to --md-ref-typeface-fallback before sans-serif.

Semantic map

Heading 1

Heading 2

Heading 3

Heading 4

Heading 5
Heading 6

A paragraph uses body-large. It is for longer reading, not chrome.

Small print and figcaptions use body-small.

<h1>Heading 1</h1>
<h2>Heading 2</h2>
<p>A paragraph uses body-large.</p>
<small>Small print.</small>
Element Role Size Weight
h1display-small2.25rem400
h2headline-large2rem400
h3headline-medium1.75rem400
h4headline-small1.5rem400
h5title-large1.375rem400
h6title-medium1rem500
pbody-large1rem400
small, figcaptionbody-small0.75rem400
bodybody-medium0.875rem400

The fifteen roles

When no tag maps to the role, use the class. Display-large and display-medium have no heading. Use them for short, important numerals and hero lines.

Display Large

Display Medium

Display Small

Headline Large

Headline Medium

Headline Small

Title Large

Title Medium

Title Small

Body Large

Body Medium

Body Small

Label Large

Label Medium

Label Small

<p class="display-large">Display Large</p>
<span class="label-large">Label</span>
Class Size Weight Line height Tracking
display-large3.5625rem4004rem−0.015625rem
display-medium2.8125rem4003.25rem0
display-small2.25rem4002.75rem0
headline-large2rem4002.5rem0
headline-medium1.75rem4002.25rem0
headline-small1.5rem4002rem0
title-large1.375rem4001.75rem0
title-medium1rem5001.5rem0.009375rem
title-small0.875rem5001.25rem0.00625rem
body-large1rem4001.5rem0.03125rem
body-medium0.875rem4001.25rem0.015625rem
body-small0.75rem4001rem0.025rem
label-large0.875rem5001.25rem0.00625rem
label-medium0.75rem5001rem0.03125rem
label-small0.6875rem5001rem0.03125rem

Emphasis

<em> is italic. <strong> and <b> are weight 500 (M3 Medium). Helpers cover the rest when the tag is already taken.

Emphasized, strong, italic, bold, light, thin, underline, overline, upper, capitalize this.

<em>Emphasized</em>
<strong>strong</strong>
<span class="bold">bold</span>
<span class="upper">upper</span>

body-large, body-medium, and body-small apply the three body roles to an element that is not a <p> or <small>.

Add -emphasized to a role class for its heavier Material 3 Expressive counterpart, such as .label-large-emphasized or .headline-small-emphasized. Each of the fifteen roles has one, with the same family, size and spacing. Display, headline, title-large and body roles go to 500. Title-medium, title-small and label roles go to 700. The weight is a token, --md-sys-typescale-emphasized-{role}-font-weight. The framework bundles Roboto and Noto Sans at 700, and the browser loads that weight only when a page uses it.

Inbox Unread

<h2 class="headline-small-emphasized">Account security</h2>
<span class="label-large-emphasized">Selected</span>

Blockquotes

Blockquotes emphasize a quote or citation. The bar on the start side uses --md-sys-color-primary.

This is an example quotation that uses the blockquote tag. Here is another line to make it look bigger.
<blockquote>
  This is an example quotation that uses the blockquote tag.
</blockquote>

Keyboard keys

The stylesheet draws <kbd> as a keycap. Wrap a combination in an outer <kbd>, which stays plain around the keys inside it. A trailing <kbd> in a menu or list item is quiet shortcut text instead.

Press Ctrl+K to open the command palette, or ? for help.

<p>Press <kbd><kbd>Ctrl</kbd>+<kbd>K</kbd></kbd> to open the command palette.</p>

Highlighted text

<mark> highlights part of a text, such as the letters a search matched. It adds no padding, so a match inside a word does not split it. To highlight ranges from a script without changing the markup, register them under the name mark with the CSS Custom Highlight API.

Results for “press”: Expressive buttons, Pressed states

<p>Ex<mark>press</mark>ive buttons</p>
const range = new Range();
range.setStart(textNode, 2);
range.setEnd(textNode, 7);
CSS.highlights.set("mark", new Highlight(range));

Flow text

flow-text scales font size with the viewport so line length stays readable. Resize the window and watch the sample change, or use the button to compare with unscaled body text.

To see Flow Text in action, slowly resize your browser and watch the size of this text body change. Use the button above to toggle flow-text off and on to see the difference.

<p class="flow-text">I am Flow Text</p>

Prose

Add .prose to a container of bare HTML, such as rendered Markdown or CMS output. It caps the line length at 70 characters, spaces out headings and indents lists. It underlines links in lists and headings, and gives inline <code> and <pre> blocks a surface. It styles only elements without a class, so a button or chip inside the content keeps its own look.

Release notes

Run npm ci, then rebuild. See the theme guide for colors.

npm run build
<div class="prose">
  <h2>Release notes</h2>
  <p>Run <code>npm ci</code>, then rebuild.</p>
  <ul>
    <li><a href="/helpers.html">Helpers</a></li>
  </ul>
  <pre><code>npm run build</code></pre>
</div>

Put .prose on a <div>, <section> or <main>. The framework draws every <article> as a card, so an article with .prose would look like one.

Typeface tokens

Override the brand and plain reference tokens to customize the scale. Each role keeps its M3 size, weight, line height, and tracking.

:root {
  --md-ref-typeface-brand: "Roboto Flex";
  --md-ref-typeface-plain: "Roboto";
}

The default order is Roboto, Noto Sans, then the generic sans-serif family. ExpressiveCSS leaves the root font size to the browser. It expresses the M3 scale in rem with the standard 16px conversion, so browser text-size preferences keep working.

No matching pages

  • Source color

    The seed every generated ramp derives from. Pick one and browse the docs — the whole theme follows. Error does not: it is a fixed hue.

    Default source: Mist Iris.

    ExpressiveCSS presets: Lagoon, Harbor, Breeze, Cobalt, Iris.

    Bold

    Soft

    Mist

    Glow