Skip to content

fix(yoga): resolve in-flow child percent against parent content box (B7 / #60)#88

Merged
re-marked merged 4 commits into
mainfrom
fix/percent-against-content-box
May 17, 2026
Merged

fix(yoga): resolve in-flow child percent against parent content box (B7 / #60)#88
re-marked merged 4 commits into
mainfrom
fix/percent-against-content-box

Conversation

@re-marked

Copy link
Copy Markdown
Owner

Closes #60.

Summary

<Box width="100%"> inside a bordered or padded parent used to overflow into the parent's border/padding zone — the percent resolved against the parent's OUTER width instead of its content-box width. A right-anchored element (e.g. a titlebar close button at x = N − 1) would land underneath the right border and become invisible or partially clipped.

Pre-fix the doc comment in `layoutNode` already asserted "Per CSS, a % width resolves against the parent's content-box width" — but the code passed outer width as the percent reference. The comment was right; the code was wrong. The fix is two lines.

What changed

`packages/shared/src/yoga-layout/index.ts` — `ownerW`/`ownerH` (the reference sizes used when resolving children's percentage values) now derive from `innerMainSize`/`innerCrossSize` (parent content box) instead of `width`/`height` (parent outer). `innerMainSize`/`innerCrossSize` were already computed two lines above.

Behavior cascade

  • width="100%", height="100%", min/maxWidth: percent, min/maxHeight: percent, flexBasis: percent on an in-flow child all resolve against parent content box. Matches CSS containing-block rules.
  • position: relative percent offsets resolve against parent content box.
  • ⚠ Child percent margin / padding / border now also resolve against parent content box, not parent outer. Yoga upstream resolves them against outer. Documented deviation — TUI consumers expect "% on a child = fraction of available space inside the parent", which is more consistent with this fix. Rare in practice; small magnitude even when present.
  • Absolute children unaffected — they continue to use the parent's padding-box per CSS §10.1 (layoutAbsoluteChild is on a separate path and untouched).
  • ✓ Per-edge position values (top/right/bottom/left) all resolve against ownerWidth per existing Yoga upstream convention — not changed here.

Test plan

  • failing repro test (packages/shared/src/yoga-layout/index.test.ts) — bordered parent + width="100%" child asserts content-box width
  • padded parent + width="100%"
  • BOTH border + padding subtracted
  • vertical axis (height="100%")
  • non-100% percent (width="50%" against content box)
  • no-border / no-padding regression case (no behavior change when there's nothing to subtract)
  • minWidth, maxWidth percent
  • flexBasis percent on a row container
  • position: relative left percent
  • documentation test pinning the Yoga-upstream deviation for child margin percent
  • documentation test pinning that position: absolute children stay on the padding-box path
  • pnpm typecheck / lint / build / test — 772 passed (was 760; +12 new for B7)

re-marked and others added 4 commits May 17, 2026 10:30
…60)

Co-Authored-By: Mark <psyhik17@gmail.com>
Co-Authored-By: Claude <noreply@anthropic.com>
…loses #60)

Co-Authored-By: Mark <psyhik17@gmail.com>
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Mark <psyhik17@gmail.com>
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Mark <psyhik17@gmail.com>
Co-Authored-By: Claude <noreply@anthropic.com>
@re-marked
re-marked merged commit 04313f6 into main May 17, 2026
1 check passed
@re-marked
re-marked deleted the fix/percent-against-content-box branch May 17, 2026 08:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

B7: width="100%" on a child of a bordered parent overpaints the border

1 participant