See when it works, when it silently breaks, and real-world use cases.
Both boxes have a header row. The left one uses normal flow — the header scrolls away.
The right one uses position: sticky; top: 0 — the header locks to the top as you scroll.
position: relative until it hits
the threshold you define (top, bottom, left, or right),
then it locks in place like position: fixed — but only within its parent container.
position: sticky stops working for non-obvious reasons. These are the three most common traps
— each one is demonstrated live so you can see exactly what happens.
overflow: hidden (or auto, scroll) on any ancestor
creates a new scroll container — sticky positions relative to that, not the page. Remove it or use overflow: clip instead.
top, bottom, left, or right.
Without it the element stays in normal flow and never sticks. This is the #1 most common mistake.
top/bottom set? (2) Does any ancestor have overflow set to anything other than visible?
(3) Is the parent container tall enough to have scrollable space?
Three patterns you'll use on almost every project. Scroll inside each demo to see sticky in action.
Scroll down inside the table — the header row sticks to the top so column labels stay visible.
| Tutorial | Category | Read Time | Difficulty |
|---|---|---|---|
| z-index & Stacking Contexts | CSS | 12 min | Intermediate |
| position: sticky Explained | CSS | 10 min | Beginner |
| ::before & ::after Guide | CSS | 8 min | Beginner |
| CSS object-fit Guide | CSS | 6 min | Beginner |
| CSS calc() Explained | CSS | 9 min | Beginner |
| CSS Specificity Deep Dive | CSS | 14 min | Intermediate |
| CSS scroll-snap Tutorial | CSS | 11 min | Intermediate |
| CSS clip-path Shapes | CSS | 10 min | Intermediate |
| CSS filter & backdrop-filter | CSS | 12 min | Intermediate |
| CSS Dark Mode Guide | CSS | 9 min | Intermediate |
| CSS Container Queries | CSS | 12 min | Advanced |
| CSS :has() Selector | CSS | 10 min | Advanced |