bi-08 — Analysis
Required invariants
- A layout result depends only on its node, its style, and its constraint space. No ambient mutable state — which is what makes results cacheable at all.
- Fragments are immutable. They can be referenced from paint without defensive copying.
- The cache key must be complete. An omitted input produces a wrong render with no error.
- Layout is expressed logically.
inline/block,start/end— physical thinking breaks in RTL and vertical writing modes. - Geometry is per-fragment. One element may produce several;
getClientRects()returns more than one rectangle for a split inline.
Why caching is the whole architecture
The old architecture mutated boxes in place, which made "can I skip this subtree?" unanswerable. Explicit inputs plus immutable outputs turn that into a key comparison.
This is the same enabling condition as immutable state in a store (fw-01) and immutable
display items (bi-09): you cannot cache what can change underneath you.
Failure modes
| Break | Consequence | Where it shows |
|---|---|---|
| Incomplete constraint-space key | stale geometry, no error | resize, container queries |
| Read geometry inside a write loop | O(n²) forced synchronous layout | the classic |
| Assume one element = one box | wrong for anonymous boxes, fragments, display:none | tables, multicol |
| Physical coordinates | breaks in RTL / vertical | i18n rollout |
Animate width/top | layout every frame | any animation |
The costs that are structural, not accidental
- Intrinsic sizing needs a pre-pass.
max-content, flex bases, and auto grid tracks all require asking a subtree its preferred size before deciding its actual one. Tables are intrinsic-sizing heavy by nature, which is a real part of why large tables are slow — not merely node count. - Percentage resolution against an auto-height containing block resolves to
auto. This is a cycle-breaking rule, and it is the answer to "why doesn'theight: 100%work" — the single most asked CSS question with the least satisfying folk answer. - Fragmentation forces resumable algorithms. Most apps never paginate, and the architecture pays for it everywhere. A genuine §46 case to argue both ways.
Scrollbars are a layout input
With non-overlay scrollbars, the scrollbar sits between the inner border edge and the outer padding
edge — inside the border box. So triggering a scrollbar reflows content, and macOS (overlay) and
Windows (classic) genuinely lay out differently. "It looks right on my Mac" is not evidence, and
scrollbar-gutter exists to buy back the stability.