"Flex-grow track with a percentage-width child causes a layout feedback loop"
A hand-rolled slider has a .track element with flex-grow: 1 and a .fill child sized by width: N%. As you drag the slider value higher, the entire track grows wider — the slider balloons instead of the fill bar growing within a fixed track.
The flex layout engine computes the flex-grow item's content basis from its child first. Since the child's width is a percentage of that same flex item, the two measurements feed back into each other: a wider fill makes the track's content basis larger, which makes the percentage resolve to a larger value, which makes the fill wider. The layout is unstable — it grows without bound as the value increases.
Use the engine's own ground-truth pattern from addons/base/code/UI/Controls/SliderControl.razor(.scss): make the track size only against its flex row and take the fill out of flow entirely with position: absolute.
.slider {
display: flex;
flex-direction: row;
.track {
position: relative; // anchor for the absolute fill
flex-grow: 1; // sizes against the row, not its children
}
.fill {
position: absolute; // OUT OF FLOW — can't feed back into track sizing
left: 0px;
height: 100%;
width: 50%; // set dynamically via style binding
}
}The percentage width now resolves against the track's already-determined flex size, not against a content-dependent basis.
Do NOT use flex-basis: 0 + overflow: hidden on the track as an alternative. This was tried and produced visual artifacts — a misshapen fill element floating near the track's midpoint at every value, caused by inherited justify-content interacting with the absolute-child-inside-zero-basis combination. The position: absolute approach is both simpler and matches the engine's own slider implementation.
Taking the fill out of normal flow with position: absolute breaks the circular dependency. The track's flex size is determined purely by the row layout (via flex-grow: 1), and the fill's percentage width resolves against that already-fixed size. There's no feedback path — the fill can be 0% or 100% without affecting the track's own dimensions.