the symptom, in your words

"A text line box renders half again taller than the line-height you declare"

✓ verified on 26.07.22
lane Building UIposted

▸ SYMPTOM

You build a UI panel to a browser mockup — a modal, a list, a stack of buttons — and it looks right for a few rows. Then you total a column of ten rows and find it runs 70px past the bottom of the region you sized for it. Nothing in the box model looks wrong: padding, borders, margins, gaps and explicit width/height all measure exactly what you declared. The overflow only shows up once the stack is tall enough to expose the accumulated slack.

▸ CAUSE

A text element's line box measures about half again as tall as the line-height you declare. Measured on a live 1:1 capture (a ScreenPanel pinned to Scale = 1, so one CSS px is one image px):

  • font-size: 16px; line-height: 22px renders a 33px line box.
  • font-size: 13px; line-height: 20px renders a 30px line box.

Both hold across different font families (a UI sans and a monospace alike). Only the line box inflates — every other box-model value measures exactly as declared — which is exactly why the drift hides. A single row looks fine; the error is per-row and only becomes visible when you sum a column.

The consequences compound through anything sized from a mockup's row arithmetic:

  • A 13px button with 9px vertical padding and a 1px border stands 50 tall, not 40.
  • A list row with 9px padding stands 48, not 38.
  • A modal body sized from a mockup's row totals needs its fixed scroll regions shrunk by the accumulated difference, or its outer size grown.

▸ FIX

Do not "correct" it by declaring smaller line-height values — that fights the engine's line-box metrics and breaks the design system's type scale for every other panel that shares it. Instead, size honestly around the real line box:

  • Derive every fixed sub-height from the ONE column with the least slack, and write the arithmetic in a comment next to the number so the next edit keeps the budget.
  • Verify the result on a scale-1 capture, not by construction. Pin the panel to AutoScreenScale = false, Scale = 1 so one CSS px maps to one image pixel, then measure the rendered rows with a ruler rather than trusting the mockup's math.

▸ WHY IT WORKS

The inflation lives in the line box, not in padding, borders, or margins — so the box model you can see is telling the truth and the type metrics are the hidden variable. Once you measure the real line-box height on a 1:1 capture and budget fixed regions from the tightest column, the accumulated per-row slack has nowhere to hide, and the stack lands inside its parent instead of spilling past it. Leaving the type scale alone keeps every other panel that inherits it correct.

Verified on engine 26.07.22: seen in a real project.
s&box moves fast; an undated fix is a liability. Spot a stale detail?
changelog
  • Published

Want to know when new guides or fixes drop? Join the community to help build this out. Report gotchas, flag outdated fixes, or just lurk.

Join the Discord