Skip to content

💡 Parent-relative min/max (percent) constraints for sizing #78

Description

@natemoo-re

Is your feature request related to a problem?

There's no way to size an element relative to its parent as a constraint rather than a fixed size. We can say "exactly 50% of the parent" with percent(0.5), but not "at least 50%" or "at most 50%" while still letting content drive the actual size. A sidebar that should be ≥50% tall but grow with its content, or a panel capped at half the viewport, can't be expressed: percent(0.5) pins to exactly 6 rows in a 12-row parent regardless of content, and fit()/grow() only take absolute cell counts in their min/max slots. (Passing a percent into a min/max slot today corrupts layout—it's coerced into a garbage float.)

Describe the solution you'd like

A way to express parent-relative floors and caps, not just fixed sizes, so an element can be bounded by a fraction of its parent while content still determines the size within those bounds. The exact API is open; a few directions worth weighing:

  • Percent in the existing min/max slotsfit(percent(0.5)) / fit(0, percent(0.5)). Smallest surface, but overloads the min/max args.
  • Dedicated clamp helpersclamp(min, max) or minmax(min, max) accepting cells or percent(...), composing with fit()/grow(). More explicit about intent.
  • min() / max() constraint helpers — CSS-like, e.g. max(fit(), percent(0.5)). Most general, largest surface.

Whatever the shape: numeric bounds must keep exact absolute-cell semantics (additive only), and a percent bound should clamp content-aware—a floor still lets content grow past it, a cap still lets content shrink below it.

Describe alternatives you've considered

Measure the parent first (info.get(parent).bounds), compute the cell count, and feed an absolute number back on a second pass—but that needs two renders, goes stale on resize, and can't express floor-plus-content-grows in one pass. The whole-axis percent() is the existing primitive that falls short here.

Additional context

Failing test case on nm/repro/percent-sizing (test · diff). Whichever shape wins, the clamp lives deepest in the layout engine: Clay_SizingMinMax (clay/clay.h:316-328) is absolute float cells with no parent-relative bound, so it needs a percent-aware min/max on the wire and in the engine.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions