Pretext Lab
03Height from width
Arc 2 · Basic Measurement

Height from width

The simplest question you can ask a text engine is the one every card, every chat bubble, every virtualized row depends on: given this text and this width, how tall? In Pretext that question is a single function call, and the answer arrives before the text is painted.

Drag the width below. The box settles exactly to the content — no reflow flash, no overshoot. The height in the corner is Pretext's answer; the box uses it as its own min-height.

height · —px

I went to the woods because I wished to live deliberately, to front only the essential facts of life, and see if I could not learn what it had to teach, and not, when I came to die, discover that I had not lived.

400

Mechanism

Once at boot, we call prepare(text, font). Pretext segments the paragraph, measures every segment's width against the browser's canvas font engine, and caches the result inside an opaque handle.

On every width change we call layout(handle, width, lineHeightPx) and read the returned { height, lineCount }. No DOM is touched. The returned height is the exact pixel height the browser would have produced at that width — not a rounded estimate, not a probe reflow. We assign it to the container as minHeight before the next paint, so the box knows its size before the text is placed.

This one call — layout() — is the entire primitive for content-aware containers. Everything Arc 2 builds leans on it.

Application

The whole family of "jumpy on mount" patterns collapses into a one-liner:

Each of these used to require inserting the element hidden, reading its offsetHeight, removing it, and trusting the read. Now the answer comes back from arithmetic, in the same frame you asked.

"I went to the woods because I wished to live deliberately, to front only the essential facts of life, and see if I could not learn what it had to teach, and not, when I came to die, discover that I had not lived."

Henry David Thoreau, Walden (1854)

Direct Claude

"fit exactly to the content" use the height returned by layout() as the container's height "snap to content — no reflow flash" set minHeight from layout() before inserting the text "card should know its size before mount" prepare() the body, layout() at the target width, render pre-sized "animate the box opening to the message" transition height toward the value layout() just returned
Next: the font string is the contract between your CSS and Pretext's idea of width.
one prepare, one layout per width change
import { prepare, layout } from '@chenglou/pretext';

// Once, at boot. Keep the font string identical to the CSS you'll render.
const FONT = "400 20px 'EB Garamond', serif";
const LINE_HEIGHT = 20 * 1.55;
const handle = prepare(TEXT, FONT);

// On every width change. No DOM reads.
widthSlider.addEventListener('input', (e) => {
  const width = parseFloat(e.target.value);
  const { height, lineCount } = layout(handle, width, LINE_HEIGHT);

  textRegion.style.width = width + 'px';
  textRegion.style.minHeight = height + 'px';  // settles before paint
  heightBadge.textContent = `height · ${Math.round(height)}px`;
});