Stockio

Position Sticky Not Working? How to Fix CSS Sticky

Debug sticky positioning by tracing scroll containers, inset values, ancestor overflow, and layout stretching, with a reliable sidebar example and inspection checklist.

By Jonah Weiss

Design Systems Lead ·

On this page

A sticky sidebar can appear completely inert even when the declaration is present in computed styles. Sticky positioning depends on surrounding layout and scrolling behavior, not just one property. Debugging it becomes much easier when you identify the scroll container, the sticky inset, and the available travel distance separately.

Build a layout with room to travel

Use the Flexbox Playground to sketch a main column and a narrower sidebar. Make the main content substantially taller than the sidebar. The tool helps expose alignment and stretching, but you will need a scrollable page fixture to observe the actual sticky behavior.

The first requirement is travel space. A sticky element remains constrained by its containing block. If its parent is only as tall as the element itself, there is little or no useful distance over which it can stay attached to the scrolling view.

Start with a simple document before adding application shells, nested panels, and toolbar offsets. If the simple version works, reintroduce ancestors one at a time. This method finds the structural condition that breaks sticking instead of producing a collection of unrelated overrides.

Set an inset on the scrolling axis

Sticky needs a nonautomatic inset on the axis where you expect sticking. A declaration of position: sticky alone does not say where the element should attach. For a sidebar near the top of the page, set a block-start inset.

.page-layout {
display: flex;
align-items: flex-start;
gap: 2rem;
}

.page-main {
flex: 1 1 0;
min-inline-size: 0;
}

.page-aside {
flex: 0 0 16rem;
position: sticky;
inset-block-start: 1rem;
}

@media (max-width: 48rem) {
.page-layout {
  display: block;
}

.page-aside {
  position: static;
}
}

This example uses logical insets, which describe the block axis rather than assuming top-to-bottom horizontal writing. In a conventional horizontal document, inset-block-start corresponds to the top edge.

Read MDN’s position reference for the behavior of sticky boxes. Sticky remains part of normal flow; unlike fixed positioning, it does not simply detach from the page and attach permanently to the viewport.

Trace every ancestor with overflow

Sticky behavior is tied to the nearest ancestor with a scrolling mechanism, even when that ancestor is not the element the user visibly scrolls. An overflow: auto, scroll, or hidden declaration can therefore change which boundary matters.

Inspect the overflow chain from the sticky element outward. A wrapper added to hide horizontal spill can unintentionally become the relevant scrolling ancestor. If that wrapper never scrolls vertically, the sticky behavior may look broken even though the browser is following the layout rules.

Check computed values on both axes. Certain combinations of visible and nonvisible overflow cause the computed value on the other axis to change. Looking only for an explicit overflow-y declaration in the source can miss the actual result.

MDN’s overflow documentation explains these interactions. overflow: clip differs from hidden because it does not itself establish a scroll container, but replacing hidden with clip can change other behavior. Verify clipping and formatting requirements instead of using it as an unexamined sticky workaround.

Remove accidental stretching and height constraints

A sidebar stretched to the height of its grid area or flex line may have no room left to move. In the example, align-items: flex-start prevents cross-axis stretching in the horizontal flex row. A grid sidebar may need align-self: start for the same reason.

The correct fix depends on which element owns the sticky behavior. Sometimes the outer sidebar should stretch while an inner wrapper sticks. This inner-wrapper pattern preserves a full-height sidebar background while giving the smaller content box useful travel distance.

Also inspect explicit heights and minimum heights. A sticky element taller than the available scrollport creates complicated edge constraints and may not behave like the simple “always visible” sidebar you intended. Redesign the content or provide a carefully considered internal scrolling area when necessary.

Do not set arbitrary heights solely to make sticking appear. The parent should derive a meaningful extent from the page layout. If the desired behavior is attachment independent of the containing block, fixed positioning may be the right model, but it requires its own space-management strategy.

Handle offsets, overlap, and real page states

A fixed header changes the useful sticky inset. Store the header height and desired gap in explicit custom properties when their values are shared. For example, combine them with calc() rather than scattering slightly different pixel offsets across multiple sidebars.

Sticky elements establish a stacking context. If content appears to paint over the sidebar, inspect stacking relationships and backgrounds before assigning an enormous z-index. A transparent sticky region can let underlying text show through even when its stacking order is otherwise correct.

Use the MDN stacking context guide to understand those boundaries. The existing responsive container architecture guide can help with the surrounding page shell, but the sticky debugging process should still begin at the nearest scrolling ancestor.

Test a short page as well as a long one. No visible sticking on a page with no overflow is normal. Test a short sidebar, a long sidebar, browser zoom, and content that loads after the initial render. These variations reveal height assumptions that a static screenshot conceals.

Keep the final behavior documented in the project’s development notes: intended scroller, inset source, parent boundary, and narrow-layout fallback. Those four facts are enough to prevent many regressions when a future wrapper or overflow rule is introduced.

A useful final inspection is to temporarily outline every ancestor. You can then watch which box ends the sticky travel and which one actually scrolls. This visual evidence is usually faster than repeatedly changing position values without a model of the surrounding layout.

Verify keyboard and zoom behavior

Consider a viewport 800 pixels tall with an 80-pixel header and a 16-pixel sticky gap. A sidebar containing 900 pixels of navigation cannot remain fully visible beneath that header. Raising its z-index or reducing its top offset does not fix the geometry. Decide whether the sidebar should return to normal flow, collapse sections, or become a bounded scrolling region. If you choose internal scrolling, make sure keyboard users can reach every link and see which region is scrolling.

Check focus visibility while tabbing through the sidebar and main content. A focused control can be scrolled behind a fixed header even when the sticky layout looks correct at rest. Appropriate scroll padding on the scrolling container or scroll margin on targets can help reserve space for navigation and focus movement; verify the result rather than assuming one offset handles every interaction.

Repeat this check with browser zoom and a short laptop viewport. Width-based breakpoints alone do not detect a sidebar that has become taller than its available vertical space. Also test expanding a disclosure inside the sticky box. The resulting height change should not strand important controls outside the reachable area. Treat normal document flow as a valid fallback, not as a failed version of the design.

Key takeaways

  • Provide an inset and enough parent height for useful sticky travel.
  • Trace computed overflow through every ancestor.
  • Prevent unintended stretching or stick an inner wrapper instead.
  • Account for fixed headers and stacking contexts explicitly.
  • Test short, long, and dynamically changing content before declaring success.
Featured sponsor

Reach designers & developers at work

Put your product next to the tools people use every day. One sponsor per placement, no tracking pixels.

Become a sponsor

Keep reading

Related articles

More in HTML & CSS
HTML & CSS

10 Best Online Code Playgrounds Like CodePen

Compare ten browser-based places to write, test, and share code, from quick HTML experiments to full-stack demos, with practical advice for choosing the right workspace.

Includes: Flexbox playgroundJonah WeissJonah Weiss
HTML & CSS

Flexbox Overflow Fix: min-width, flex-basis and Shrink

Debug overflowing flex layouts by understanding automatic minimum sizes, flex-basis, shrinking, and text wrapping, with focused fixes for common component failures.

Includes: Flexbox playgroundJonah WeissJonah Weiss
HTML & CSS

CSS :has() Selector: Parent Selectors and Conditional UI

Use CSS :has() to style parents from child states, adjust optional-content layouts, control specificity, and ship readable fallbacks without extra classes.

Includes: Flexbox playgroundJonah WeissJonah Weiss
Motion & Animation

10 Best JavaScript and CSS Animation Libraries

Compare ten web animation libraries for interface feedback, scrolling effects, and expressive motion. Find a practical match for your coding comfort, project size, and performance needs.

Includes: Flexbox playgroundAiko TanakaAiko Tanaka
UI Design

Search Bar and Filter UI Design for Catalogs

Create search and filter interfaces with clear scope, predictable application rules, useful result feedback and responsive layouts for catalogs and dashboards.

Includes: Flexbox playgroundMaya LindqvistMaya Lindqvist
JavaScript & Frameworks

Interactive Documentation: Why Live Code Demos Win

Design fast, accessible documentation demos that start with readable static examples, add focused controls, and measure whether readers complete real tasks.

Includes: Flexbox playgroundDaniel KimDaniel Kim