CSS Position: Fixed and Sticky
CSS Position: Fixed and Sticky
Fixed elements stay in a viewport position while sticky elements act normally until reaching a scrolling threshold.
What you’ll learn
- Distinguish fixed from sticky positioning.
- Identify the sticky scroll container and inset.
- Avoid obscuring content with pinned elements.
Understand the concept
position: fixed positions a box relative to the viewport in common cases; it does not occupy normal-flow space. position: sticky behaves like normal flow until an inset, such as top: 0, constrains its position within a scroll container.
Sticky positioning needs a non-auto inset on the relevant axis. Fixed or sticky headers may obscure headings or controls, so reserve space and test scroll and keyboard navigation. The fixed sample is safely confined to an iframe viewport.
.floating-help { position: fixed; right: 16px; bottom: 16px; }What the browser evaluates
Fixed uses a viewport-related positioning context in typical cases; sticky positioning participates in normal flow until a scroll threshold is reached.
Sticky header in a scrolling box
Scroll the constrained list and watch its label stick to the top.
HTML
<div class="sticky-list"><div class="sticky-header">Tasks · Monday</div><p>Review emails</p><p>Plan the week</p><p>Check updates</p><p>Prepare notes</p><p>Send report</p></div>CSS
.sticky-list { height: 118px; overflow-y: auto; background: #f8fafc; border: 1px solid #cbd5e1; }
.sticky-header { position: sticky; top: 0; z-index: 1; padding: 9px; background: #0f766e; color: white; font-weight: 700; }
.sticky-list p { padding: 8px; margin: 0; border-bottom: 1px solid #e2e8f0; }Rendered output
Review emails
Plan the week
Check updates
Prepare notes
Send report
Observe: The green header remains at the visible top edge while list contents scroll underneath.
Fixed item inside an isolated mini-page
This embedded frame keeps viewport-fixed behavior from overlaying the tutorial itself.
HTML
<iframe title="Fixed positioning within a demonstration viewport" loading="lazy" sandbox="" srcdoc="<!doctype html><html><head><style>body{margin:0;font:14px Arial,sans-serif;padding:10px 10px 140px;background:#eff6ff}p{margin:0;max-width:180px}a{position:fixed;right:12px;bottom:12px;background:#1d4ed8;color:white;padding:8px 12px;border-radius:7px;text-decoration:none}</style></head><body><p>Scroll inside this frame; the blue action stays in its bottom-right corner.</p><p style="margin-top:55px">More content below...</p><a href="#top">Fixed action</a></body></html>" style="width:100%;max-width:360px;height:155px;border:1px solid #94a3b8;border-radius:9px;background:#eff6ff;"></iframe>CSS
iframe { max-width: 360px; display: block; }Rendered output
Observe: Inside the mini-page, the button stays at the frame’s lower-right corner while its content scrolls. The iframe HTML contains position: fixed.
Explain the result
Fixed uses a viewport-related positioning context in typical cases; sticky positioning participates in normal flow until a scroll threshold is reached.
Compare the two examples: identify the selector, each changed property, and which visible part of the output proves that the CSS took effect.
Common mistakes to avoid
- Fixed elements can cover other controls when the viewport becomes narrow.
- Sticky can appear not to work if the chosen scroll container or threshold differs from your expectation.
Try it yourself
Scroll the sticky list. In a separate test document, change fixed to absolute and compare what happens during scrolling.
Before changing the code, predict what will change. Then verify by checking the rendered result.
Check your understanding
What you should remember
Use sticky for section context and fixed sparingly for truly persistent controls.
Revisit the rendered examples if the rule still feels abstract. Change one declaration at a time so you can connect cause and effect.
Reaching the recap and completing the quizzes are separate milestones.