Field Guide / intermediate

Sticky positioning: why it fails and how to design around it

Sticky positioning works when the element has a scroll container, a threshold, and enough room to move.

position: sticky feels unreliable until you treat it as a contract. A sticky element is relative until it crosses an offset threshold inside its scroll container, then it sticks within the limits of its containing block.

When sticky fails, one of those conditions is usually missing.

It needs an offset

.toc {
  position: sticky;
  inset-block-start: 1rem;
}

Without top or the logical inset-block-start, there is no threshold for the browser to use. The element remains in normal flow.

The scroll container matters

Any ancestor with overflow that creates a scroll container can change where sticky is evaluated. This is the classic failure:

.page {
  overflow: hidden;
}

That rule may have been added to hide a decorative bleed, but it can also trap sticky descendants. Prefer fixing the element that overflows instead of putting overflow: hidden on a large page wrapper.

Sticky needs space

If the sticky element is as tall as its container, it has nowhere to stick. A sidebar table of contents inside a short parent may appear broken because the parent ends before the sticky behavior becomes visible.

.article-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 16rem;
  align-items: start;
}

align-items: start prevents the sidebar from stretching to match the main content height, which often makes sticky behavior easier to reason about.

Design around mobile

Sticky sidebars rarely belong on narrow screens. Use sticky for local, high-value controls such as an alphabet nav, a filter bar, or a table header only when it does not steal reading space. The viewport is smaller, browser chrome moves, and sticky elements can quickly become more intrusive than helpful.

Sticky is best used as a progressive enhancement. The page should remain readable when the element simply scrolls away.

References