the symptom, in your words

"A panel's width and height are the outer size (border-box by default)"

✓ verified on 26.07.22
lane Building UIposted

▸ SYMPTOM

  • Panels built from a mockup come out consistently too small — every box is narrower and shorter than the design, by an amount that happens to match its own padding.
  • You added padding or a border to a panel and expected it to grow outward; instead the content area shrank and the outer size stayed put.
  • A layout that looked right at zero padding drifts tighter the moment you pad the rows, and the drift is uniform across every padded element.

▸ CAUSE

s&box's razor/SCSS layout uses the border-box box model by default. A panel's declared width/height is the outer number: padding and border thickness are subtracted from it to find the content area, never added on top.

There is no box-sizing declaration involved anywhere — the untouched default already behaves this way. Measured live with a dev console command reading Panel.Box.Rect:

  • A row declared width: 512px with 24px of padding on each side measured 512.4px outer — not 512 + 48 = 560.
  • A 30px glyph with a 2px border measured 30.5px outer — not 30 + 4 = 34.

The failure mode is authoring from a mockup as if the model were content-box: taking the width the mockup shows, then adding padding and border on top in your head.

snippet
// WRONG: treating the mockup width as a content number.
// The mockup row is 512px wide; you pad it 24px each side and
// "add" the padding, declaring the content width:
.row {
    width: 464px;      // 512 - 48, expecting padding to push it back to 512
    padding: 0 24px;
}
// Result: outer width = 464px. Every row ships 48px too narrow.

Because the arithmetic is applied per element, every padded box shrinks by exactly its own padding — so the whole sheet reads as uniformly undersized rather than obviously broken.

▸ FIX

Author every width and height as the OUTER number the mockup shows. Let padding and border live inside it — do not subtract them by hand.

snippet
// RIGHT: the declared size IS the outer size the mockup draws.
.row {
    width: 512px;      // the mockup's outer width, verbatim
    padding: 0 24px;   // sits inside the 512, no arithmetic needed
}

If you ever need to confirm what a panel actually measures at runtime, read Panel.Box.Rect from a dev ConCmd rather than eyeballing it from a screenshot — the layout engine gives you the exact outer rect.

Do not design a whole sheet's sizing around the assumption that padding adds to the outer size. That assumption is a content-box habit from other CSS environments; it does not hold here.

▸ WHY IT WORKS

Border-box means the declared dimension is a promise about the element's outer footprint, and the engine fits content, padding, and border within that footprint. That is exactly what a mockup measures — the visible outer edges of each box — so authoring the mockup's numbers verbatim produces the mockup's layout with zero manual arithmetic.

One caution when reasoning from a design review: a claim of the shape "there's no engine precedent for box-sizing: border-box" can be simultaneously true and irrelevant. A missing precedent for a declaration is not evidence that the property defaults to the opposite value. The default behavior is border-box regardless of whether anyone ever writes the declaration — so test the default directly (Panel.Box.Rect) before building a sheet's arithmetic around its assumed absence.

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