Prose
.prose — styling for content you do not control.
Examples
A heading from a CMS
Prose restores the vertical rhythm the reset strips, so editorial content reads correctly with no per-element classes.
- Including lists,
- which get their markers back.
<div class="prose">
<h2>A heading from a CMS</h2>
<p>Prose restores the vertical rhythm the reset strips, so editorial content
reads correctly with no per-element classes.</p>
<ul>
<li>Including lists,</li>
<li>which get their markers back.</li>
</ul>
</div>The one utility that styles bare elements. It exists because markup out of a CMS has no classes to hang anything on, and .prose-narrow / .prose-wide change the measure.
Tokens 5
Level 2, declared on .prose itself. Set any of them on that selector to restyle this utility without touching the skin.
| Token | Default |
|---|---|
| --prose-gap | var(--space-5) |
| --prose-gap-rule | var(--space-12) |
| --prose-gap-tight | var(--space-2) |
| --prose-gap-heading | var(--space-8) |
| --prose-gap-subheading | var(--space-6) |
Variants and states
Variants
.prose-full.prose-narrow.prose-wide
State it reads
Read from the platform, never mirrored into a class that could disagree with it.
:hover
Before you ship it
What you have to do 3 requirements
- Put it on the wrapper, not on the page. Every rule here is scoped to
.prose, and it is scoped there because it styles bare tags. On<body>it would restyle every<p>and<ul>in your own components too. - Do not nest one
.proseinside another. The rhythm is a sibling gap applied at any depth, so an inner block's first child would take the outer block's gap as well. - Give a wide table somewhere to scroll. A table is the one thing in editorial content that legitimately outgrows the measure, and this file deliberately does not make it scroll on its own — see the rule below.
src/css/utilities/prose.css · npx mostlycss add prose