fixed under transform
The fixed element that stopped meaning it
The badge below says position: fixed. It should be pinned to your screen — but this frame carries a transform, so the frame is its world now. Scroll and it stays put. In here.
position: fixedCaveatposition: fixed is pinned to the viewport only while no ancestor gets in the way, and the list of things that get in the way keeps growing: transform, filter, backdrop-filter, will-change: transform, contain: paint, container-type. Any of them turns the ancestor into the containing block, and the fixed element quietly behaves as absolute inside it. This is why the sticky toolbar dies the day someone adds a slide-in animation to the panel around it, and why a third-party wrapper with a stray translateZ(0) breaks a modal it has never heard of. The fix is structural, not stylistic: move the fixed element outside the transformed subtree, or drop the transform once the animation ends.
FallbackNothing to polyfill — this is the spec, and every engine agrees with it. The escape hatch is the top layer: a <dialog> opened with showModal() or a popover renders above the page in a layer no ancestor transform can reach, which makes it the one reliable place left for something that must stay put.
.panel { transform: translateX(0); }
.panel .toolbar {
/* pinned to .panel now,
not to the viewport */
position: fixed;
bottom: 0;
}
/* the top layer — dialog,
popover — ignores ancestor
transforms altogether */
Published