"An absolute child of an unpositioned panel escapes to the screen, not the panel"
▸ SYMPTOM
You place a texture as an absolutely positioned child inside a card frame, expecting it to fill the frame. Instead it renders full-bleed against the whole screen, and the frame's own border and chrome draw on top of it.
A neighbouring screen in the same panel uses the identical absolute-child pattern and looks perfect, so the pattern reads as safe.
▸ CAUSE
An absolutely positioned child does not clip to its visual parent. It resolves against the nearest ancestor that is a positioning context, and in this renderer that can be the screen root rather than the parent you can see.
A panel becomes a positioning context only when it carries an explicit position declaration. The card frame in the live case had layout properties, a flex rule, a fixed size, and a border radius, but no position. So the absolute child skipped the frame entirely and resolved against the root. The frame kept drawing its own border and chrome, which landed on top of the escaped child.
The sibling screen that looked fine is the trap. It used the same absolute-child pattern and rendered correctly, but only because its own box already was the positioning root: a full-bleed viewer with nothing framing it. It worked by accident of layout, not because absolute children are safe inside a plain panel. Copy that pattern into a host that is not itself a positioning context and the child escapes again.
▸ FIX
When the target is a single rectangle, remove the absolute child. Paint the texture on the framing element itself.
- Put the texture on the frame's own background. Set
Style.BackgroundImagefor a runtime texture, andbackground-size: cover; background-position: centerin the stylesheet. One element holds the frame and the fill, so there is no absolute child and nothing to escape to. - If you must keep the absolute child, make the host a positioning context. Add
position: relativeto the intended container. The child then resolves against that container instead of the root. - Do not copy an absolute-child pattern from a sibling without checking the host. Confirm the new host box is actually a positioning context before you reuse a layout that worked next door.
▸ WHY IT WORKS
The escape happens because the intended parent is not on the chain of positioning contexts. Removing the child removes the escape: a background paints on the element that owns it, with no resolution step to send it anywhere. Where the child has to stay, an explicit position: relative puts the intended container back on that chain, so the nearest context is the one you meant.
The same root mechanism drives percent-sized fills that flood the screen instead of filling their track. There the fix is also an explicit position on the intended container; here the child escapes outright rather than oversizing.
- Published