The Browser Is Too Late

The line break is the oldest unsolved problem in web typography. Every other element ofeditorial craft — the typeface, the leading, the measure, the weight — can be specified in astylesheet and trusted to render consistently. The line break cannot. The browser decideswhere each line ends at the moment the reader opens the page, using a reflow algorithm that knowsnothing about the paragraph as a unit, nothing about the rhythm of the sentence, and nothing aboutwhat the compositor would have done.

Print never worked this way. In a print shop, the compositor set the type into a forme before the inktouched paper. The line breaks were made decisions, not runtime accidents. A Linotype operator in1920 was making line-break choices — justified or ragged, with or without hyphenation, hold thewidow — that the web has never learned to make at all.

The browser’s reflow engine is not unintelligent. It handles bidirectional text, handles Unicode, handlesvariable-width glyphs with reasonable accuracy. What it cannot do is reason about the paragraph as awhole before committing to a break. It walks the line from left to right, packs in glyphs until themeasure is full, and wraps. That is not typesetting. That is triage.

The consequence shows up at 65 characters — the measure where Fraunces sits on this page. At thatwidth, a greedy line-breaker will occasionally produce a very short first line in a paragraph, or strand atwo-syllable word alone at the end of a long one. These are not disasters. But they are the kind of smallfailure that accumulates, paragraph by paragraph, into a page that reads like it was assembled ratherthan composed.

Pilcrow’s answer is to move the decision earlier. At build time, before the page reaches anyone, a head-less Chromium instance loads each post with its actual CSS — the real Fraunces instance at its realoptical size, the real 65ch measure — and runs pretext1 over every paragraph. The line breaks are com-puted against the actual rendered geometry, not an approximation of it. The output is a static HTMLfile with every prose line wrapped in a <span class="pt-line">. The browser receives pre-broken text.There is nothing left to decide.

The hyphenation works the same way. Hyphenopoly, a TeX-trained library, inserts soft hyphens at syl-lable boundaries before the typeset pass runs. The combination produces breaks that a browser’shyphens: auto cannot: breaks chosen for the particular word at the particular column width, with afour-character minimum on the post-hyphen fragment so the eye is never stranded on a residual like csor ly with nothing to anchor it.2 Words like disproportionate and comprehension and extraordinarybreak at the syllable, not wherever the glyph count happened to run out.

The drop cap on this post’s first paragraph is not decoration. It is a structural signal — the same signalthat rubricators drew in red ink into manuscript codices to mark the start of a new section. It tells thereader: this is the beginning; the text is waiting for you. Pilcrow measures the float box created by thecap and adjusts each successive line’s available width accordingly, so the text runs alongside it cleanlyrather than tucking under. That measurement happens at build time. The browser never sees it as aproblem to solve.

The argument is not that the web should work like print. Print is print; it has its own constraints and itsown failures. The argument is that the line break has always required a person — or, failing a person, asystem that reasons about the whole paragraph before committing to a break. The web delegated thatto a greedy reflow algorithm and called it good enough. For a long time it was. In 2026, when thedefault page is assembled in thirty seconds from a template that ten thousand other sites are also using,good enough is no longer distinguishable from not trying.

A typeset page is distinguishable. Not because it shouts — it doesn’t — but because it holds still. Thecolumn does not drift. The lines end where they should. The face earns its place at this size. The pagearrives at the reader already composed, carrying the evidence of a decision made for their sake, beforethey arrived.

Footnotes

  1. pretext is @chenglou/pretext on npm. It walks the text buffer counting graphemes against a Canvas 2D meas-urement context, without touching the rendered DOM. Pilcrow routes it through a Playwright page.route()intercept at a virtual origin — no network request, version-pinned, fully deterministic across builds.

  2. The four-character threshold is Pilcrow’s orphan guard. After pretext computes a paragraph’s lines, theguard checks every hyphenated line-end. If the post-hyphen fragment on the next line is fewer than four char-acters, the guard strips the offending soft hyphen and re-runs the layout from the paragraph start. Theupstream fix for the root cause — pretext issue #162, filed 2026-04-30, resolved 2026-05-08 in commitf06fef0 — changes pretext’s default behaviour so soft-hyphen breaks stay at the insertion point. When thatfix reaches npm, the guard comes out.