🎨 position: sticky Works Everywhere Except Inside This One Container
A sticky header works perfectly when tested on its own, and the moment it’s placed inside a scrollable card or panel, it stops sticking entirely – scrolling right past the top of its container as if position: sticky had no effect at all.
🐞 The Problem
.panel {
height: 400px;
overflow-y: auto; /* the scrollable container */
}
.panel-header {
position: sticky;
top: 0;
/* Sticks correctly when the PAGE scrolls,
but not when THIS panel scrolls internally
- if a parent has overflow:hidden somewhere
between them, it silently breaks. */
}
🔍 Why This Happens
position: sticky is scoped to its NEAREST scrolling ancestor - and it silently stops working if ANY ancestor between the sticky element and that scroll container has overflow set to anything other than visible (including "hidden", "auto", or "scroll" on an unrelated wrapping div) unless that ancestor IS the intended scroll container. A single wrapping div added for unrelated styling reasons, with overflow: hidden for a border-radius clip, is enough to break it with zero visible warning.
✅ The Fix: Audit Every Ancestor Between the Sticky Element and Its Scroll Container
- Check every parent element between the sticky header and the scrollable container for any overflow value other than
visible— even one on an unrelated wrapper breaks the chain. - If an ancestor needs overflow:hidden for its own reasons (e.g. clipping a rounded corner), move that clipping to a different element, or restructure so the sticky element’s parent chain up to the scroll container stays overflow:visible.
- Confirm the sticky element also isn’t inside a parent with a fixed height smaller than its own content in a way that clips it — that’s a related but separate cause of the same symptom.
⚠️ Quick Way to Find the Culprit
- In DevTools, select the sticky element and walk UP the DOM tree checking computed ‘overflow’ on each ancestor until you find the first non-visible one that isn’t the intended scroll container — that’s almost always the fix location.
- This same rule applies just as often to elements meant to stick within a modal, a sidebar, or a table’s header row — the overflow chain rule is universal, not specific to any one layout.
Sticky positioning isn’t broken when it stops working — it’s obeying a scoping rule about overflow that most developers never knew existed until it silently ruined their layout.
