Variant collapse, Positioning
Polser
I.
Context
Within Design Handoff, positional needs were repeatedly solved with variants.
As they accumulated, a structural limit became clear: layout intent was being stored as component permutations, not as a model.
II.
Landscape
Position was treated as a variant result.
Placement lived inside each component’s variant set, not in a shared positioning model.
That does not scale. Each new position increases surface area and maintenance.
When a needed position is missing, there is no safe extension path — only detaching, local overrides, and broken structure.
III.
Decisions
— Stop encoding placement as a variant problem. Treat it as a reusable behaviour.
— Introduce a dedicated layer for positioning. Composable, explicit, and independent from the host component.
— Align the design model with the code model: placement expressed as offsets, not as enumerated outcomes.
— Make the extension path safe: new placements should not require detachment, nor new variants, nor internal restructuring.
— Constrain the surface area: one mechanism, repeatable across components, governed once.
IV.
Model
The model follows development offset positioning: placement is an offset, not a variant.
It is split into
two utility layers.
A.
Offset
The Slot shifts through a constrained placement set — top, bottom, left, right, and corners — exposed through one Position property.
B.
Absolute
A parent wrapper contains Offset Position, so the same Slot can move again on a second plane.
In practice, Offset Position handles the local shift. Absolute Position provides the frame that makes that shift portable across layouts.
V.
Refinements
Adopting the model required a refactor across most interaction and container components — buttons, links, popovers, and similar patterns — where placement had been embedded as variants.
Those components were restructured to delegate positioning to the utility layer, reducing their variant surface while keeping behaviour stable.
VI.
Standards
A.
Structure
— Positional behaviour lives in utility components, not inside product components.
— Host components expose a Slot for composition; they do not own placement variants.
— Positioning is expressed through properties, not duplicated internal frames.
— No “position” variants inside interaction components (buttons, links, popovers, tooltips).
— No detaching to achieve placement. If placement requires detachment, the model is incomplete.
— Utility positioning remains one-slot: it wraps a single child and stays behaviour-only.
C.
Exclusions
— No local, component-specific positioning rules.
— No parallel positioning utilities per team or market.
VII.
Position stopped being a per-component problem.
By moving placement into one utility layer, components lost positional variants and became smaller, simpler, and easier to maintain.
For designers, extension became immediate: placement can be adjusted without detaching, overrides, or new variants.
For the system, the reach is compositional: one positioning model reused across interaction patterns, with less fragmentation and handoff closer to code.
VIII.
Form
The model ships as a single utility component: Absolute Position, containing Offset Position as a nested internal layer.
IX.
Notes
This case is not about a new component. It is about moving responsibility.
Position moves from host variants to a dedicated utility model.
The constraint was consistency.
The refactor only works if the model becomes the default path. Otherwise, variants grow back.
The success criterion is simple:
when a new placement is needed, it should be expressed through the model, not requested as a new variant.
I shared an early tutorial on this direction back in 2023 — see here.