position: sticky in CSS

position: sticky keeps an element in normal flow until an inset such as top constrains its position within the relevant scrollport. It then remains stuck only while its containing block still has room for it. So let's take a look at the property and its practical constraints.
How does position:sticky work?
To see sticky positioning in action, let's set up a basic example:
HTML
<body> <div class='sticky-parent'> <p>Not Sticky</p> <div class='sticky-child'> <p>Sticky</p> </div> </div></body>CSS
body { height: 4000px; padding: 0; margin: 0;}p { margin: 0;}.sticky-parent { position: relative; height: 100%; display: block; background: red; height: 2000px;}.sticky-child { position: sticky; top: 0;}You can check out a fairly rudimentary CodePen implementation of this here.
A sticky element is constrained by its containing block and by the nearest ancestor that establishes a scrolling mechanism. In the example, the sticky child stops at the bottom edge of .sticky‑parent because it cannot move outside that containing block. The parent does not need position: relative merely to make sticky work; its dimensions are what provide the available travel area here.
You will also need to set an "offset" parameter, like top. You can also set a bottom, left, or right. The inset provides the threshold and stuck offset on that axis. For top: 0, the element remains in normal flow until its normal position would move above the scrollport's top edge, then it is visually constrained there without becoming position: fixed.
Overflow does not categorically disable sticky positioning. An ancestor with overflow other than visible can establish the scrolling mechanism that sticky uses, so the element may stick within that ancestor rather than the viewport. It will appear not to stick if that ancestor never scrolls or leaves no travel area. Inspect overflow, overflow-x and overflow-y on every ancestor when the scroll container is not the one you expected.
Compatibility and Support
Thankfully, the position: sticky property actually enjoys pretty widespread support! You can use it in Edge, Chrome, Firefox, Opera, and Safari (starting from versions released in late 2021 to mid‑2022). It also is fairly well‑supported for mobile browsers.
Common Reasons Sticky Fails
A sticky element needs an inset such as top, bottom, left or right. Without that threshold, the browser has no point at which to switch the element into its stuck position.
Ancestor layout can change sticky positioning without making the property universally invalid. Check which ancestor supplies the scrollport, which box supplies the containing block, whether the chosen axis has an inset, and whether the sticky element has enough space to move before it reaches its containing‑block boundary.
How I Usually Debug It
First check the inset value. Then inspect the ancestors for overflow, scrolling and contain rules that create a different scrolling or containing context from the one expected. Finally, make sure the containing block is larger than the sticky element and leaves room for it to travel.
The Wrap‑Up
A very handy property, position: sticky seems to be one of the better‑supported CSS properties that offers some more complex and dynamic options for your elements without the use of JavaScript. It's an exciting view into the future of CSS, potentially becoming more and more mixed with the more traditional JavaScript areas of development.