mugen

Fonts & Layout

The font/line-height/width fields that drive measurement and CSS.

The font a Text measures with is the font its CSS paints with — that's why heights can't drift. Each Text carries its own font; <MugenVList> supplies defaults so you don't repeat them, and maxW (the content-width cap, which the engine needs to measure) lives on the list.

<
  ={}
  ={() => .}
  ={}
  ="16px Inter" // default for every <Text> — canvas/CSS shorthand
  ={22} // px
  ={0} // px (optional)
  ="normal" // or 'pre-wrap'  (optional)
  ="normal" // or 'keep-all'  (optional)
  ="3xl" // content width cap (optional)
/>;

A <Text> with no font/lineHeight inherits these defaults; one that sets its own overrides them. (A Text with neither its own nor a default font throws.)

Cheap vs expensive

font, letterSpacing, whiteSpace, wordBreak feed pretext's expensive prepare() pass — changing one re-segments the text. lineHeight and maxW are cheap: they only re-run the arithmetic layout() pass, so a resize that changes the available width never re-segments.

maxW

The content width is min(viewport, maxW). maxW accepts:

  • a number — px, e.g. maxW: 768
  • a rem/px stringmaxW: '48rem'
  • a named sizesm md lg xl 2xl7xl (a Tailwind-ish rem scale)

Named and rem values resolve against the live root font-size at measure time, so the list tracks browser zoom and :root { font-size } changes instead of baking in a px assumption. When maxW is finite and narrower than the viewport, rows are centered and the text wraps at maxW — exactly as the rendered column does.

Per-Text overrides

A row often mixes styles (a bold author over regular body text). The default covers the body; override on the Text for the exceptions — used for both measure and render, so they stay in sync:

< ={2}>
  < ="600 15px Inter" ={20}>{.}</>
  <>{.}</> {/* inherits the list default */}
</>;

Fonts are typed

font (the list default and a Text's font prop) is a typed template literal — only the canvas shorthands pretext can actually measure type-check: an optional style and/or weight, then a size+unit, then a family.

const :  = '16px Inter'; // ✓
const :  = '600 14px Inter'; // ✓
const :  = 'italic 500 17px Inter'; // ✓
const :  = '15px Inter, sans-serif'; // ✓
const e:  = 'Inter'; // ✗ no size+unit
Type '"Inter"' is not assignable to type 'Font'.
const f: = '16 Inter'; // ✗ no unit
Type '"16 Inter"' is not assignable to type 'Font'.
const : = '16px system-ui'; // type-ok, but rejected at runtime

This catches a whole class of "why is my text the wrong height" bugs before you run anything.

On this page