The Measure Is More Than a Line Length

Traditional typography defines the measure as the length of a line of text. But the term has a deeper history that can reshape how you think about layout. Before desktop publishing, typesetters worked with physical metal type, setting lines within a composing stick. Measure was literally the width of that stick — the space available for type, around which everything else on the page (column widths, margins, gutters) was designed.

A heading and three paragraphs of text in white against a black background.
An uncomfortable measure makes reading more difficult. See this example in my lab.

This suggests a content-first approach: instead of letting layout dictate the measure, let the measure inform the layout. When the line length is correct, the rest of the composition tends to fall into place.

Making the Measure a CSS Variable

In practice, the measure can be encoded as a custom property using ch units, which relate to the width of the zero character in the chosen font — a natural fit for line length.

:root {
  --measure: 60ch;
}

The ch unit works well because character count, not pixel width, is what drives readability. Between 60 and 70 characters per line is generally comfortable, so 60ch is a common baseline. However, this isn't universal: typefaces with a large x-height appear visually larger and make 60ch feel too long; condensed faces can make it feel short; wide faces stretch it out. Tracking adjustments also shift perceived measure. Treat 60ch as a starting point and adjust by eye for the specific typeface.

Applying the Measure to Text Containers

One direct application is constraining text blocks to remain readable on large screens. A good practice is to use max-inline-size (the logical property equivalent of max-width) set to the measure:

article {
  max-inline-size: var(--measure);
  margin-inline: auto;
}
A heading and three paragraphs of text in a white contained in a narrow column against a black background.
Well considered measure makes reading more comfortable. See this example in my lab.

This guards against the long-line syndrome that appears when content spans the full width of a large display.

Multi-Column Layouts and Column Sizing

The measure proves valuable for multi-column layout, an underused CSS tool. Rather than forcing a specific number of columns, specifying a column width lets the browser decide how many will fit. The measure can drive these column widths:

article {
  column-width: var(--measure);
}
A heading and three paragraphs of text in white against a background and split into two equal-sized columns.
The measure can define multi columns widths. See this example in my lab.

Once the container is wide enough, the browser flows text into as many readable columns as space allows. When space is tight, it gracefully collapses back to a single column — no breakpoints or media queries required.

Grids Anchored to Content

The same principle applies to grid design. For a two-column layout pairing long-form text with a flexible secondary column, lock the text column to the measure so the reading column keeps a comfortable line length while the secondary column takes whatever remains:

.layout {
  display: grid;
  grid-template-columns: minmax(0, var(--measure)) 1fr;
}
A heading and three paragraphs of text in white against a black background on the left next to an image of a woman in a cowgirl hat and denim shirt staring directly ahead.
The measure also creates grids which feel connected to content. See this example in my lab.

Measure as a Breakpoint: Container Queries

For years, designers have anchored layouts to device-defined breakpoints like 320px, 48em, or 64em. But these numbers have nothing to do with content — they are more accurately "guesspoints." A measure-driven breakpoint works differently: coupled with container queries, it checks a component's container width instead of the viewport. When a container becomes narrower than a readable line length, the layout collapses; when enough space is available, it can expand.

For example, a container query can apply specific styles when a component is narrower than 65 characters, as this rule does:

/* When the container is no wider than the --measure */
@container (max-width: var(--measure)) {
  /* Styles */
}

Consider a design with a wide column for main content and a narrower column for supporting information:

[data-layout="yogi"] {
  display: grid;
  grid-template-columns: 3fr 1fr;
}

If the container can't accommodate a column that reaches the measure, the query can switch both columns into a single-column layout:

@container (max-width: var(--measure)) {
  [data-layout="yogi"] {
    grid-template-columns: 1fr;
  }
}

Because the breakpoint is tied to content (readability) rather than device width, the result feels more natural and more comfortable to read.

Building a Measure System

For projects with diverse content types, defining multiple measure variations can help maintain a consistent rhythm across different text blocks:

:root {
  --measure: 60ch;
  --measure-s: 55ch;
  --measure-l: 80ch;
}

These values support different situations — small for captions and short text blocks, regular for body copy, and large for introductions, headings, and hero sections. When type, spacing, and layout all share the same underlying measure-driven rhythm, the composition feels more coherent and intentional.

Designing from the Measure

Treating the measure as a key design parameter can shift how you approach layout entirely. It replaces guesswork with a logic rooted in readability, and it creates a stronger relationship between what the content says and how it is presented. Once you anchor the page to a readable line length, both the composition and the reading experience become more deliberate and focused.