Typeset

A prose container for long-form text content. Wrap any article, blog post, or documentation block in .typeset to get sensible typography, vertical rhythm, and readable line length — no per-element tweaking needed.

Vertical Rhythm

Block siblings (p, ul, ol, blockquote, headings) are automatically spaced with --flow-space (default 0.75em). Line-height is set to 1.4 and max-width to 65ch for optimal readability.

The king, seeing how much heavier his nephew's attention was to home than his, and that all his own meaſures were fruſtrated by the unaccountable prejudice his nephew had taken againſt the unfortunate Miſs Frick, he gave it as his laſt advice.

An enumeration of all the particulars, the delivery, and the eſtate to be purchaſed, would ſwell this article to a tedious length.

Headings

h1–h4 are sized relative to each other with tighter line-height (1.2 for h1/h2, 1.33 for h3/h4). h1 gets extra top margin for section separation.

This is a level-one heading

Body text following an h1.

This is a level-two heading

Body text following an h2.

This is a level-three heading

Body text following an h3.

This is a level-four heading

Body text following an h4.

Heading Spacing Rules

Spacing between headings and body adapts to the context. A spacious 2rem gap appears before headings that follow body content, while headings after an h1 stay tightly coupled at 1rem. Body after a heading gets a close 0.5rem gap.

Page Title

Subtitled — tightly coupled to h1

Body text after a heading stays close (0.5rem). This keeps the heading visually connected to its content.

Another paragraph flowing naturally after the first. The regular rhythm between body paragraphs is 0.75em.

A New Section

When body content precedes a heading, a spacious 2rem gap is added to visually separate the new section.

Nested Subsection

Same rules apply at every heading level. Body before a heading gets breathing room; body after a heading stays close.

Lists

Unordered lists use square markers; ordered lists use decimal. Markers use the accent font and reduced opacity. List items have a small gap between them.

A paragraph before the list:

  • Square markers for unordered lists
  • Items have 0.25em gap between them
  • Markers use the accent font at 60% opacity

A paragraph between lists:

  1. Decimal markers for ordered lists
  2. Same item spacing as unordered lists
  3. Also uses the accent font for markers

Lists can also be nested:

  • Top-level item
    • Nested item with square markers
    • Another nested item
  • Another top-level item

Definition Lists

dl elements use a two-column grid. Terms sit in the left column (60% opacity, no wrap) and descriptions span the right column.

Typeset
A prose container with sensible typography defaults.
Flow Space
The CSS custom property that controls vertical rhythm between block siblings.
Ch
A relative unit equal to the width of the "0" character, used for readable line length.

Inline Code

Inline code gets a monospace font, slightly reduced size, padding, and a subtle background. Code blocks (pre > code) are left untouched — only inline code within paragraphs or list items is styled.

The .typeset class applies a set of sensible defaults to all child elements. Use --flow-space to customize the vertical rhythm spacing.

Inline code looks distinct from body text, making it easy to spot class names like .typeset or property names like max-width inline.

Putting It All Together

A realistic example combining headings, paragraphs, lists, definition lists, and inline code — all in a single .typeset container.

On the Design of Typesetting

A brief guide to readable prose on the web

Good typography is invisible. The reader should never notice the spacing, the line length, or the font choices — they should simply read. The .typeset utility provides a set of defaults that make this possible.

Core Principles

  • Line length: Capped at 65ch — roughly 65 characters per line, the sweet spot for readability.
  • Line height: Set to 1.4 for body text, giving letters room to breathe without feeling loose.
  • Vertical rhythm: Block siblings are automatically spaced using the --flow-space custom property.

Technical Details

Layer
typeset
Selector
:where(.typeset)
Max Width
65ch
Default Flow
0.75em

The :where() pseudo-class keeps specificity low, so you can override any rule without fighting selector wars. Need a different flow space? Just set --flow-space on the container or any child.