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