Cmpnts

Menu

Molecules

Prose

Styles bare HTML, such as CMS and Markdown output, so it reads like the rest of the library without classes.


Planting a shade garden

Shade under trees is usually dry. Read the soil guide first.

  • Leaf mould
  • Mulch for the first summer
Code
HTML
<div class="prose">
  <h2>Planting a shade garden</h2>
  <p>Shade under trees is usually dry. Read the <a href="/soil">soil guide</a> first.</p>
  <ul>
    <li>Leaf mould</li>
    <li>Mulch for the first summer</li>
  </ul>
</div>

Why it exists

Long text usually comes from somewhere that can’t add classes, such as a CMS or a Markdown file. Prose makes that output read like the rest of the library by styling the bare elements.

Each element takes the type of the text atom it stands for, so a heading in an article matches a heading in an interface. Prose has no options of its own. It follows the sizing mode around it, and so does the space between its blocks, so one article sits properly in a page, a Dialog or a compact region.

It styles everything in its scope, whatever classes an element has, because CMSs put their own classes on every block. That’s why .prose-end exists: anything that should stay a component has to leave the scope.

When to use

  • For long-form text you can’t put classes on: CMS output, Markdown, an article.
  • Not for markup you write by hand in an interface: use text atoms and a list (.list).
  • Not for components in the text: put those in a .prose-end.

Rules

  • Which elements: every element in the prose takes the prose look, whatever classes it has (a CMS’s, such as WordPress’s wp-block-list; a text atom on an element still wins for type). Components (ul.cluster, .table, .divider, a Card) and widgets go in a .prose-end. Links are the exception: a Link with a class is left alone.
  • Anchors: an element with an id keeps --prose-scroll-margin above it when scrolled to. A product with a sticky header adds the header height to that token.

Article

A real article starts at <h1>; this one starts at <h3> to fit the page around it.

Planting a shade garden

Shade under trees is usually dry. Read the soil guide first.

What to buy

  • Leaf mould
  • Mulch for the first summer

The love of gardening is a seed once sown that never dies.

Abstract cover artwork
Figure 1: The cover of the planting guide.
:where(textarea) { field-sizing: content; }
Code
HTML
<article class="prose">
  <h3>Planting a shade garden</h3>
  <p>Shade under trees is usually dry. Read the <a href="/soil">soil guide</a> first.</p>

  <h4>What to buy</h4>
  <ul>
    <li>Leaf mould</li>
    <li>Mulch for the first summer</li>
  </ul>

  <blockquote>
    <p>The love of gardening is a seed once sown that never dies.</p>
  </blockquote>

  <figure>
    <img src="/examples/cover.svg" alt="Abstract cover artwork" width="800" height="533" loading="lazy">
    <figcaption>Figure 1: The cover of the planting guide.</figcaption>
  </figure>

  <pre><code>:where(textarea) { field-sizing: content; }</code></pre>
</article>

A component in the text

Text styled by prose.

A card, outside prose.

Prose carries on.

Code
HTML
<article class="prose">
  <p>Text styled by prose.</p>
  <div class="prose-end">
    <div class="card">
      <div class="card__body"><p class="text">A card, outside prose.</p></div>
    </div>
  </div>
  <p>Prose carries on.</p>
</article>

Everything inside .prose-end is outside prose: no element type, no margins, and links need a class. The .prose-end block itself keeps the rhythm around it. Components on lists, Tables and rules (ul.cluster, .table, .divider) need one too: prose styles every list, Table and rule in its scope.

Sizing comes from around it

This text grows with the viewport.

This text takes the compact size from the region around it.

Code
HTML
<article class="prose font-sizing-fluid">
  <p>This text grows with the viewport.</p>
</article>

<div class="ui-compact">
  <article class="prose">
    <p>This text takes the compact size from the region around it.</p>
  </article>
</div>

Prose has no mode of its own. It follows the mode on itself or around it: fixed on a plain page, cq in a Dialog, compact in a compact region. The rhythm follows the same mode.

Do and Don’t

DoDon’t
Put components and widgets in a .prose-end.Leave a ul.cluster, .table or Card in the prose, which styles it too.
Put a text atom on an element to change its type.Add a class that only sets type another way.
Set the sizing mode on the prose or around it.Look for a prose size option.
Set the column width on the Wrapper the prose sits in.Set a width on the prose.
Write emoji in the text.Use emoji classes.

In Storybook

See also

  • Text and Heading: The type styles, from a display title to small text, and the List.
  • Wrapper: Centres content, caps its width and keeps it off the screen edge.
  • Link and Block Link: A way to go somewhere else, in running text or as a row of its own.
  • Table: Data in rows and columns, with rules, alignment and sticky edges.

Search the docs